使用 ObjectMapper 去生成 json 串时,有这样一个有意思的现象。
类:
@Data
public class DcmtUseElement {
private String IV_NO_START ;
private String IV_NO_END ;
private int IV_CNT ;
private String IV_TYPE;
private String REMARKS = "中间业务平台实体卡制卡平台使用凭证";
private String iLoveU = "s";
private String ILoveU = "b";
private String remarks = "low";
}
使用 ObjectMapper 去获得 json 串,得到这样的结果
{"IV_NO_START":null,"IV_NO_END":null,"IV_CNT":0,"IV_TYPE":null,"REMARKS":"中间业务平台实体卡制卡平台使用凭证","iLoveU":"s","ILoveU":"b","remarks":"中间业务平台实体卡制卡平台使用凭证","iv_NO_START":null,"iv_NO_END":null,"iv_CNT":0,"iv_TYPE":null,"iloveU":"s"}
仔细看上面,发现多出了一些以小写开头的变量。
研究之后发现,这是 ObjectMapper 对象设置了 setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); 的原因。
当不设置时,得到的结果是: {"remarks":"中间业务平台实体卡制卡平台使用凭证","iv_NO_START":null,"iv_NO_END":null,"iv_CNT":0,"iv_TYPE":null,"iloveU":"s"}
发现得到的 json 串完全改写了我们的变量名。
有以下结论:
2.多数时候,我们还是应该要设置 JsonAutoDetect.Visibility.ANY,否则,出来的 json 串中不含原变量名,设置之后虽然多出了小写对应的变量名,但它起码不会丢失。
结论就是,类中变量名尽量要规范,使用驼峰式。另外,不可存在仅大小写不同的变量名。
-------------------------------------------------------------------- 2017 年7月17日完善
在 benny 大神的指点下,发现 setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); 为什么会起到意想不到的作用:在生成的 json 串中同时生成了原变量名和首字母小写的变量名。上面的 PropertyAccessor.FIELD 原来是要设置在生成 json 串时,对象中的成员的可见性:当传入 PUBLIC_ONLY 时表示只将对象中可见的成员放入 son 串中。而属性一般是不可见的,所以一般不会被放入 json 串中。而该属性的 get 方法是可见的。若定义属性名为 name,且定义了 public getName 方法,则 json 会根据 getName 推测出 name 属性,并放入 json 串中 - 这是 json 内部的推测规则。而如果一个纯大写字母变量,则从它对应的 set 方法绝对推测不到原属性名,因此 json 串中就没有这个变量了,至于是什么,那就是 json 内部的推断规则了。
如果两个系统间交互的变量名为纯大写,则可以采用 json 提供的变量名映射方式,@JsonProperty("HAS_MORE") 来实现转化 - 不仅仅用于生成 json 串,同时解析时也会是正确的行为。