为什么jackson2不承认第一个大写字母,如果领先的骆驼案例字只有一个字母长?

我正在使用Spring 4 MVC和Jackson 2进行我的服务。 对于其中一个操作,我有一个请求对象,该对象具有一个属性,其中前导驼峰字的长度只有一个字母:

private String aLogId; 

这个类有适当命名的getter和setter:

 public String getALogId() { return aLogId; } public void setALogId(String aLogId) { this.aLogId = aLogId; } 

但是,当我尝试使用相应的JSON属性向此服务发布请求时:

 {"aLogId":"This is a log id"} 

我收到Spring框架的500响应,说该字段无法识别,我的控制器类永远不会被调用:

无法读取JSON:无法识别的字段“aLogId”(类

但是,当我将“L”更改为小写时,请求按预期反序列化并且我的控制器类被命中:

 {"alogId":"This is a log id"} 

为什么jackson期望“L”是小写的,因为它显然是该属性的驼峰案例约定中的第二个单词并且意图是大写的? 是因为第一个单词只有一个字母长吗?

请求对象中还有其他属性,其中第一个单词不止一个字母,并且那些属性不会遇到同样的问题,并且情况不匹配。

您看到的问题是由于Jackson使用Java Bean命名约定来弄清楚Java类中的Json属性。

以下是您看到的具体问题的参考,建议不要将您字段中前两个字母中的任何一个都大写。 如果您使用像IntelliJ或eclipse这样的IDE并让IDE为您生成setter,您会注意到会发生相同的“行为”,您将最终得到以下方法:

 public void setaLogId(String aLogId) { this.aLogId = aLogId; } public String getaLogId() { return aLogId; } 

因此,当您将“L”更改为小写时,jackson能够计算出您想要映射的字段。

说到上面的内容,你仍然可以选择使用“aLogId”字段名称,让Jackson工作所有你需要做的就是使用带有aLogId@JsonProperty注释。

 @JsonProperty("aLogId") private String aLogId; 

以下测试代码用于说明这将如何工作:

 import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; public class Test { @JsonProperty("aLogId") private String aLogId; public void setaLogId(String aLogId) { this.aLogId = aLogId; } public String getaLogId() { return aLogId; } public static void main(String[] args) { ObjectMapper objectMapper = new ObjectMapper(); Test test = new Test(); test.setaLogId("anId"); try { System.out.println("Serialization test: " + objectMapper.writeValueAsString(test)); String json = "{\"aLogId\":\"anotherId\"}"; Test anotherTest = objectMapper.readValue(json, Test.class); System.out.println("Deserialization test: " +anotherTest.getaLogId()); } catch (Exception e) { e.printStackTrace(); } } } 

测试的输出是:

Serialization test: {"aLogId":"anId"}

Deserialization test: anotherId

我的理解是,Jackson默认使用自己的命名约定,它与Java Bean命名约定非常接近但不完全相同。 在Jackson 2.5.0中添加了MapperFeature选项MapperFeature.USE_STD_BEAN_NAMING,告诉Jackson使用Java Bean命名约定 – 请参阅Jackson Issue 653 。 为了向后兼容,MapperFeature.USE_STD_BEAN_NAMING的默认值为false。

这对我有用; 关于getter的@JsonProperty注释!

 import com.fasterxml.jackson.annotation.JsonProperty; public class PaytmRequestJson { private String ORDERID; private String MID; private String CHECKSUMHASH; @JsonProperty("ORDERID") public String getORDERID() { return ORDERID; } public void setORDERID(String ORDERID) { this.ORDERID = ORDERID; } @JsonProperty("MID") public String getMID() { return MID; } public void setMID(String MID) { this.MID = MID; } @JsonProperty("CHECKSUMHASH") public String getCHECKSUMHASH() { return CHECKSUMHASH; } public void setCHECKSUMHASH(String CHECKSUMHASH) { this.CHECKSUMHASH = CHECKSUMHASH; } }