问题
对接腾讯的TIM接口,接口返回的应答包体的字段都是首字母大写的
{
"ActionStatus":"OK",
"ErrorInfo":"",
"ErrorCode":0
}
于是我就定义了一个对应的Bean
@Data
public class TimResult {
private String ActionStatus;
private String ErrorInfo;
private Integer ErrorCode;
}
但是在使用RestTemplate#postForEntity() 进行接口调用后,结果TimResult 对象的各个属性值都为null。
分析原因
通过debug分析发现,是因为RestTemplate 要将响应的json字符串反序列化为TimResult 对象时,从容器中的类型转换器中匹配到了Jackson转换器,然后Jackson进行反序列化时,都没有匹配到TimResult 的各个属性。然后查阅资料发现Jackson默认的属性发现规则将会查找到如下所述的属性:
- 所有被
public 修饰的成员变量; - 所有被
public 修饰的getXxx() 方法; - 所有被
public 修饰的setXxx(value) 方法;
由于我们定义的TimResult 的属性都是private 的,所以Jackson 反序列化时是根据public 的setXxx(value) 方法名得到首字母小写的属性,但是实际上TimResult 的属性都是首字母大小写的,所以都没赋值成功。
若使用FastJson进行序列化、反序列化,就没有这个问题。
解决
解决方法有两种:
- 直接将bean对象中的属性改为public,属性名命名为首字母大写,比如
{"Name":"nomouse","Age":12} ,定义相应的bean为:
public class TimResult {
public String ActionStatus;
public String ErrorInfo;
public Integer ErrorCode;
}
- 但是第一种方法不符合Java的命名规范,所以可以用第二种方法,在属性上添加
@JsonProperty 注解:
@Data
public class TimResult {
@JsonProperty(value = "ActionStatus")
private String actionStatus;
@JsonProperty(value = "ErrorInfo")
private String errorInfo;
@JsonProperty(value = "ErrorCode")
private Integer errorCode;
}
采用上面两种方式不仅在解析json的时候有效,在输出json流的时候同样是以大写字母开头。
|