spring mvc的Controller层 一般接收json串 或者url后面传参
1,通过@valid去映射实体类,绑定BindingResult。
@ResponseBody @RequestMapping(value = "/insert", method = RequestMethod.POST) public IResponse insert(@RequestBody @Valid HistoryInfoRequest request, BindingResult result) { IResponse response=new IResponse(); if (result.hasErrors()) { // 请求数据格式错误 for (ObjectError error : result.getAllErrors()) { PlatformLogger.message("请求参数错误, " + error.getDefaultMessage()); } response.setResponseCode(RespCode.BIZ_400_5003.code); response.setErrorInfo(RespCode.BIZ_400_5003.desc); return response; } return response; }
class HistoryInfoRequest { @NotNull @JsonProperty(value = "card_no") private Long cardNo; @NotNull @JsonProperty(value = "card_status") private Integer cardStatus; @notNull @JsonProperty(value = "bank_card_no") private String bankCardNo; ....get set方法 }
通过这种实体类 与json串映射。
这时候会出现很多问题。通过测试童鞋的反馈,
1,类型不匹配,即定义了Long,传过来的时String,页面400错误
测试童鞋希望把这个异常捕获掉,通过json返回给前端。so我看了下源码
首先读取request元素
Object argument = readWithMessageConverters(webRequest, parameter, parameter.getGenericParameterType());
调用readWithMessageConverters方法
protected <T> Object readWithMessageConverters(HttpInputMessage inputMessage, MethodParameter methodParam, Type targetType) throws IOException, HttpMediaType NotSupportedException { return genericConverter.read(targetType, contextClass, inputMessage); } throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes); }
然后调用org.springframework.http.converter.json.MappingJacksonHttpMessageConverter的read方法
public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { JavaType javaType = getJavaType(type, contextClass); return readJavaType(javaType, inputMessage); }
然后调用readJavaType方法时报错,Could not read JSON: Unexpected character ('a' (code 97)): was expecting comma to separate OBJECT entries
private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) { try { return this.objectMapper.readValue(inputMessage.getBody(), javaType); } catch (IOException ex) { throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex); } }
然后一路抛异常,所以不会把错误写到BindingResult。
如果映射成功后,开始对注解进行解析(原生注解)
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator 附加的 constraint
@NotBlank(message =) 验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内
这些注解产生的错误都会写到BindingResult中