@ResponseBody 转化成json后与实体类字段名不一致

实体类A字段名由B改成C后,Controller 中返回的List中字段名仍然是C

java json实体类注解返回默认值_java json实体类注解返回默认值


经过@ResponseBody返回到前台后又变成了B后来发现公司项目采用的是阿里的fastjson, 是开源的Json格式化工具库 此工具库是根据实体类中的get方法来生成json字段

先获取get方法名,再将"get"字符串截取掉作为json字段名

而我恰恰只改了实体类的变量名称而没有改get方法名 所以造成了以上的错误 修正get方法后生效

java json实体类注解返回默认值_java json实体类注解返回默认值_02

java json实体类注解返回默认值_SpringMVC_03

SpringMVC字符串解析成json对象(@RequestBody注解和@ResponseBody注解)

在springmvc中我们可以使用@ResponseBody将输入解析成json对象并返回,这其中其实是通过HttpMessageConverter起作用的。
注:springmvc底层默认使用jackson进行json对象的转换。

HttpMessageConverter

Http请求响应报文其实都是字符串,当请求报文到java程序会被封装为一个ServletInputStream流,开发人员再读取报文,响应报文则通过ServletOutputStream流,来输出响应报文。

从流中只能读取到原始的字符串报文,同样输出流也是。那么在报文到达SpringMVC / SpringBoot和从SpringMVC / SpringBoot出去,都存在一个字符串到java对象的转化问题。这一过程,在SpringMVC / SpringBoot中,是通过HttpMessageConverter来解决的。

在请求进入test方法前,会根据@RequestBody注解选择对应的HttpMessageConverter实现类来将请求参数解析到param变量中,因为这里的参数是String类型的,所以这里是使用了StringHttpMessageConverter类,它的canRead()方法返回true,然后read()方法会从请求中读出请求参数,绑定到test()方法的param变量中。

同理当执行test方法后,由于返回值标识了@ResponseBody,SpringMVC / SpringBoot将使用StringHttpMessageConverter的write()方法,将结果作为String值写入响应报文,当然,此时canWrite()方法返回true。

借用下图简单描述整个过程:

java json实体类注解返回默认值_java_04


在Spring的处理过程中,一次请求报文和一次响应报文,分别被抽象为一个请求消息HttpInputMessage和一个响应消息HttpOutputMessage。

处理请求时,由合适的消息转换器将请求报文绑定为方法中的形参对象,在这里同一个对象就有可能出现多种不同的消息形式,如json、xml。同样响应请求也是同样道理。
在Spring中,针对不同的消息形式,有不同的HttpMessageConverter实现类来处理各种消息形式,至于各种消息解析实现的不同,则在不同的HttpMessageConverter实现类中。

事实上,这里也可以替换为其他的json转化类,在springmvc中配置即可。(当配置mvc:annotation-driven 启用默认配置时springmvc默认是使用spring自己的转化类StringHttpMessageConverter将字符串转化为json对象,下面的配置可以省略,如果想使用其他的json转化类就需要配置)

注;不同的json转化类解析得到的结果可能不同,如jackson解析如果值是null返回null,fastjson解析字符串类型的值如果是null就返回“”,数值类型的如果是null就返回0。

java json实体类注解返回默认值_spring boot_05


java json实体类注解返回默认值_json_06


例:配置使用阿里巴巴提供的fastjson(转化效率更高,速度更快):

java json实体类注解返回默认值_spring boot_07


java json实体类注解返回默认值_json_08


继承关系图:

java json实体类注解返回默认值_SpringMVC_09