04月23, 2018

SpringMVC @RequestBody 自定义参数绑定

SpringMVC @RequestBody 自定义参数绑定

最近在写一个短信发送的平台,作为一个纯服务提供者,我想照着以前在电子支付的账务接口系统做,这样的扩展性很好也很简单。但是之前是采用的WebService做的,使用xml传输数据,然后用xsd去校验数据格式。但这个我希望做成全josn形式的,这样更加简单方便。

含义

RequestBody即请求体,被@RequestBody修饰的参数,即接收当前请求的请求体 下边两种写法是等价的。

@PostMapping
public String get(HttpServletRequest request) throws IOException {
    InputStream is = request.getInputStream();
    DataInputStream input = new DataInputStream(is);
    String str =input.readUTF();
    return "";
}

public String post(@RequestBody String str){
    return "";
}

自定义参数绑定

SpringMVC提供了强大的自定义参数绑定的功能,可以自动把xml或者json转换成JavaBean实体。下边两种写法也是等价的。

@PostMapping
public ResultData post(@RequestBody AuthenticationBean authentication) throws Exception {
    return null;
}

@PostMapping
public ResultData post(@RequestBody String json) throws Exception {
    AuthenticationBean authentication = JSONObject.parseObject(json, authentication.class);
    return null;
}

属性校验

单单的参数绑定还是不够方便,SpringMVC还集成了属性的校验,这样就不需要我们挨个的写if-esle去校验这些参数。 只需要添加@Valid或者@Validated即可,推荐使用前者,前者是javax中注解,、后者是Spring提供的。

@PostMapping
public ResultData post(@Valid @RequestBody AuthenticationBean authentication) throws Exception {
    return null;
}
public class AuthenticationBean {
    @NotBlank(message = "signature 不能为空")
    private String signature;
    @NotBlank(message = "timestamp 不能为空")
    private String timestamp;
    @NotNull(message = "businessType 不能为空")
    private Integer businessType;
    @NotBlank(message = "encodingNonce 不能为空")
    private String encodingNonce;
    private String appid;
    @NotBlank(message = "encodingBody 不能为空")
    private String encodingBody;

    //getter setter
}

属性的校验为JSR-303规范的验证器的规则,如下:

空检查

@Null       验证对象是否为null

@NotNull    验证对象是否不为null, 无法查检长度为0的字符串

@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.

@NotEmpty 检查约束元素是否为NULL或者是EMPTY.



Booelan检查

@AssertTrue     验证 Boolean 对象是否为 true  

@AssertFalse    验证 Boolean 对象是否为 false  



长度检查

@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  

@Length(min=, max=) Validates that the annotated string is between min and max included.



日期检查

@Past           验证 Date 和 Calendar 对象是否在当前时间之前  

@Future     验证 Date 和 Calendar 对象是否在当前时间之后  

@Pattern    验证 String 对象是否符合正则表达式的规则



数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null

@Min            验证 Number 和 String 对象是否大等于指定的值  

@Max            验证 Number 和 String 对象是否小等于指定的值  

@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度

@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度

@Digits     验证 Number 和 String 的构成是否合法  

@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。



@Range(min=, max=) 检查数字是否介于min和max之间.

@Range(min=10000,max=50000,message="range.bean.wage")
private BigDecimal wage;



@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)

@CreditCardNumber信用卡验证

@Email  验证是否是邮件地址,如果为null,不进行验证,算通过验证。

@ScriptAssert(lang= ,script=, alias=)

@URL(protocol=,host=, port=,regexp=, flags=)

在属性不符合配置校验器的规则时,SprigMVC会抛出一个MethodArgumentNotValidException的异常,如果直接把异常信息交给SpringMVC抛给调用者,肯定不太好,所以我们可以使用SpringMVC提供的全局异常处理器经行处理后返回。通常情况下我们会用自己封装类包装,这里只是直接返回。

/**
 * 全局异常处理器
 *
 * @author wpy
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    @ResponseBody
    public String paramValidateExceptionHandler(HttpServletRequest req, MethodArgumentNotValidException e){
        return e.getBindingResult().getFieldError().getDefaultMessage();
    }

}

方法内部处理校验结果

有时候我们可能并不需要直接使用抛异常的方式来解决问题,SpringMVC也提供了这样的解决方案,只要我们再增加一个BindingResult类型的参数即可。

@PostMapping
public void post(@Valid @RequestBody AuthenticationBean authentication,BindingResult bindingResult) throws Exception {
    //出错参数的个数
    System.out.println(bindingResult.getFieldErrorCount());
    //所有从错误
    System.out.println(bindingResult.getAllErrors());
    //第一个出错的错误信息
    System.out.println(bindingResult.getFieldError().getDefaultMessage());
}

本文链接:https://www.qiangshuidiyu.xin/post/spring-requestBody .html

-- EOF --

Comments