一、遇到问题

我们在使用@RestController+@RequestBody 这种注解方式做web交互时,经常会遇到如下三种场景:

①请求字段映射不到值

②返回字段大小写与预期的不一致(字段首字母大写)

③某个属性字段序列化需要忽略(不演示)

①②问题Demo演示如下

请求需要的实体 

java json映射对象 json 注解 字段映射_spring boot


应答需要的实体

java json映射对象 json 注解 字段映射_java json映射对象_02



Controller处理


java json映射对象 json 注解 字段映射_spring boot_03


Postman请求和报文内容:


java json映射对象 json 注解 字段映射_java json映射对象_04



java json映射对象 json 注解 字段映射_java_05

 

二、分析原因

   这种情况如果字段本身可以对应的上,首先就是要考虑是不是json解析出了问题, 因为springboot默认使用jackson来格式化web交互的json串 ,所以此时就要从jackson下手,查询jackson资料。

三、查询资料

Jackson简介:

Jackson是一个简单基于Java应用库,可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。Jackson所依赖的jar包较少,简单易用并且性能也要相对高些。

Jackson的常用注解:

JackSon提供了一些的注解,可以用在类上或者是在字段上。通常是数据绑定的时候使用。

1、@JsonIgnoreProperties(ignoreUnknown = true) : 用来忽略序列化实体类时不需要的属性(jackson默认序列化实体类的所有属性,不存在则报错。)

2、@JsonIgnoreProperties({ “userAge”, “userWeight” }) : 指定忽略字段

3、@JsonIgnore: 标在注解上,将忽略此字段

4、@JsonInclude(param)  JsonInclude.Include.NON_EMPTY:属性为空或者null都不参与序列化 JsonInclude.Include.NON_NULL:属性为null不参与序列化

5、@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm:ss”) : 序列化时使用指定时间跪着(默认转化成时间戳)

6、@JsonProperty("fieldName") : 标在字段上,指定序列化后的字段名

7、@JsonAutoDetect 该注解用来 改变默认的自动检测,标记在类上

jackson默认大小写敏感,且首字母转小写 用来指定字段、方法的可见性规则@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY, getterVisibility=JsonAutoDetect.Visibility.NONE)

附加知识点:

@JsonAutoDetect部分源码

java json映射对象 json 注解 字段映射_java json映射对象_06

 

 

Jackson自动检测的规则

对象的属性被初次确定的过程称为自动检测:所有的成员方法和字段被查找。

   1.1.“Getter”方法:所有public,带返回值,符合“getXxx”(“isXxx”,如果返回boolean,被称为“isgetter”)

命名约定的成员方法被推测存在名字为“xxx”的属性(属性名按照bean命名约定推测,即开头大写字母转成小写)。

   1.2.field属性:所有public成员字段被推测要显示的属性,使用字段名字来序列化。

在相同的逻辑属性中同时存在getter和field的情况下。getter方法优先被使用(field被忽略)。

属性集被解析使用这个过程被认为是基本属性集。但自动检测过程本身可以进行不同的配置,并有多个注释和配置设置,可以进一步改变属性的真实有效集序列化。

 

四、解决方法:

1、这三个场景中①和②其实是一样的原因

方法一:用第6个注解 @JsonProperty("fieldName")标识每一个字段

java json映射对象 json 注解 字段映射_spring boot_07

日志

java json映射对象 json 注解 字段映射_spring_08

方法二:用第7个注解 @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY, getterVisibility=JsonAutoDetect.Visibility.NONE)

实体

java json映射对象 json 注解 字段映射_字段_09


日志

java json映射对象 json 注解 字段映射_spring boot_10


postman

java json映射对象 json 注解 字段映射_java_11


2、问题③某个属性字段序列化需要忽略

可以根据实际情况Jackson的常用注解(1、2、3、4)处理。

五、回看问题

综上看,实体映射结果不正确的最主要原因是:变量的命名不规范,导致getter不准确,所以我们开发还是要严格遵守代码规范。