Java - 如何进行JSON日期验证?

问题描述 投票:3回答:3

我有这段代码:

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    protected Date statusDate;

但不知何故,它接受日期格式,如 -

"statusDate": "2017-13-27"

要么

"statusDate": "201823-12-12"

是否可以验证请求中的格式(不是手动)?

java json rest date date-parsing
3个回答
0
投票

好吧,你需要编写一个自定义日期序列化/反序列化类,如果在拦截数据时收到的日期格式不符合你的预期,则抛出一个自定义异常。

This的回答将指出你如何做到正确的方向。

您还可以在代码中使用验证器来验证有效负载,并让Jackson处于简单状态。


1
投票

当您将statusDate作为响应返回时,@ JsonFormat用于设置输出格式。

最好创建一个接受String statusDate的DTO对象,然后将其转换为控制器中的Date格式。

要以String格式验证日期,可以使用@Pattern

public class StatusDateDto {

    @NotNull(message="Status date is a required field")    
    @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}", message="Invalid status date")
    private String statusDate;

    //Getter and setter
}

public ResponseEntity<?> postStatusDate(@Valid @RequestBody StatusDateDto dateDto, BindingResult result) {

        if (result.hasFieldErrors()) {
            String errors = result.getFieldErrors().stream()
                .map(p -> p.getDefaultMessage()).collect(Collectors.joining("\n"));   

            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors);
        }

        // Convert the String to Date after validation

        return ResponseEntity.ok().build();
    }

1
投票

是的你可以。让我告诉你细节。

首先,请创建一个基本控制器来过滤所有请求,如下所示:

package com.letv.address.controller;

import com.letv.address.utils.ConstantCode;
import com.letv.address.utils.ResponseWrapper;
import com.letv.xice.core.controller.GlobalController;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by shichaoyang on 2017/1/10.
 */
public class BaseController extends GlobalController {

public ResponseWrapper requestCheckAndPost(BindingResult result) {

    if (result.hasErrors()) {

        List<Object> errorList = new ArrayList<>();

        StringBuilder sBuilder = new StringBuilder();

        for (ObjectError error : result.getAllErrors()) {

            String fieldName = ((FieldError) error).getField();
            String fieldMessage = error.getDefaultMessage();

            sBuilder.append(fieldName)
                    .append(" ")
                    .append(getMessage(fieldMessage))
                    .append(";");

            errorList.add(fieldName);
        }

        return new ResponseWrapper(
                  ConstantCode.FAILING_WITH_ERROR_PARAM_CODE
                , errorList.toArray()
                , ""
                , sBuilder.toString()
                );
    }
    return null;
  }
}

从上面的代码中,BindingResult将检查@JsonFormat或其他组件头,如@NotBlank,@ Pattern等。如果他们达到规则,他们将被BindingResult捕获,我们可以得到错误。下面是我使用的DTO对象,只是显示给你,以便你可以获得更多细节:

package com.letv.address.controller.dto;

import com.letv.address.utils.ConstantCode;
import org.hibernate.validator.constraints.NotBlank;

/**
 * Created by shichaoyang on 2016/12/23.
 */
public class ChildrenAreaSelectRequest{

@NotBlank(message = ConstantCode.REQUEST_VALIDATE_NOT_EMPTY)
private String areaIds;

public String getAreaIds() {
    return areaIds;
}

public void setAreaIds(String areaIds) {
    this.areaIds = areaIds;
  }
}

然后在我们的业务逻辑控制器中,我们需要扩展基本控制器并编写如下代码:

package com.letv.address.controller;

import com.letv.address.controller.dto.ChildrenAreaSelectRequest;
import com.letv.address.controller.dto.ParentAreaSelectReqeust;
import com.letv.address.domain.Area;
import com.letv.address.service.ChildAreaService;
import com.letv.address.utils.ConstantCode;
import com.letv.address.utils.ResponseWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by shichaoyang on 2016/12/12.
 */
@RestController("areaController")
public class AreaController extends BaseController {

@Autowired
protected ChildAreaService childAreaService;

/**
 * get area info by parent id
 *
 * @param areaReqeust
 * @param result
 */
@ResponseBody
@RequestMapping(value = ConstantCode.CHILD_AREA_PATH, method = {RequestMethod.POST})
public ResponseWrapper childArea(@RequestBody @Valid ParentAreaSelectReqeust areaReqeust, BindingResult result) {

    ResponseWrapper validationWrapper = requestCheckAndPost(result);
    if (validationWrapper != null) {
        return validationWrapper;
    }

    List<Area> areaList = childAreaService.selectByParentId(areaReqeust.getParentId());
    if (areaList == null || areaList.size() == 0) {
        return new ResponseWrapper(ConstantCode.SUCCESS_WITH_EMPTY_DATA_CODE, new ArrayList<>());
    } else {
        return new ResponseWrapper(ConstantCode.SUCCESS_WITH_FILL_DATA_CODE, areaList);
    }
  }
}

通过使用上述方法,您可以在请求中轻松验证字段。这是实现这一目标的一种美好方式。

希望有所帮助。

编辑:

用真实代码替换图像,以便任何人都需要测试它。

© www.soinside.com 2019 - 2024. All rights reserved.