接触ObjectMapper时的简单记录

简介

ObjectMapper类是Jackson库的主要类。它提供一些功能可以进行Java对象和json数据之间的相互转换。

部分方法介绍

public String writeValueAsString(Object value)

该方法是将对象转化为json数据的方法。可配合注解@JsonProperty,经过不完整实验。该方法对对象的命名方式有一定要求。以下,用三个例子说明:

//首先创建三个对象
public class Information {
    @JsonProperty(value = "UserObject")
    UserObject userObject;
    @JsonProperty(value = "IdCardObject")
    IDCardObject idCardObject;
}
public class UserObject {
    @JsonProperty(value = "UserList")
    List<User> userList;
}
public class IDCardObject {

    @JsonProperty(value = "IdCardList")
    List<IdCard> idCardList;
}

其中 User 和 IdCard 是两个实体类。
当使用IDCardObject的属性名称为 idCardObject 时,使用writeValueAsString()方法得到的json串是正确的。且@JsonProperty,改变结果key也会改变。
结果如下:

{"UserObject":{"UserList":[{"UserID":"编号1","UserName":"名字1"}]},"IdCardObject":{"IdCardList":[{"CardType":"类型","CardNumber":"卡编号"}]}}

当使用IDCardObject 的属性名称为 iDCardObject 时,结果就会出错。
即变成如下时:

 public class Information {
    @JsonProperty(value = "UserObject")
    UserObject userObject;
    @JsonProperty(value = "iDCardObject")
    IDCardObject idCardObject;
}

结果如下:

{"idcardObject":{"IdCardList":[{"CardType":"类型","CardNumber":"卡编号"}]},"UserObject":{"UserList":[{"UserID":"编号1","UserName":"名字1"}]},"IdCardObject":{"IdCardList":[{"CardType":"类型","CardNumber":"卡编号"}]}}

以上两个例子idCardList 和 userList 的数据是一样的。
但是如果只是最里层的POJO类命名方式改变不会影响输出结果。这里将不在贴出实验结果。经过以上例子可以看出使用ObjectMapper的writeValueAsString(Object value)。如果POJO外层有包装类。那么POJO在包装类中的属性名称最好符合 驼峰命名 法。否则可能会出现问题。

其他方法介绍
public <T> T readValue(String content, Class<T> valueType)

该方法是从一个包含了json串的文件读取数据,并根据valueType来装换为对应的对象。

public <T> T readValue(File src, Class<T> valueType)

从File中获取String数据并根据valueType转换为对应的实体类。

public <T> T readValue(URL src, Class<T> valueType) 

从url中获取String数据并根据valueType转换为对应的实体类。

public <T> T readValue(InputStream src, Class<T> valueType)

从流中获取String数据并根据valueType转换为对应的实体类。

集合对象转换

public <T> T readValue(String content, JavaType valueType)

public <T> MappingIterator<T> readValues(JsonParser p, TypeReference<?> valueTypeRef)

public <T> T convertValue(Object fromValue, Class<T> toValueType)

public <T> T convertValue(Object fromValue, TypeReference<?> toValueTypeRef)

该方法是特殊数据格式装换为具体对象的实现,主要是将List和Map对象装换为java对象。下面介绍一下我自己的测试结果。

对于List对象的用法:

JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class,JavaBean.class);
List<Information> informationList = objectMapper.readValue(listBaseJson,javaType);

首先需要获取JavaType对象,通过以下方法获取,其中constructParametricType()的两个参数,第一个参数表示是将List形式的Json串转换为转换为List对象。第二个参数表示List的中包含的对象。使用readValue()第一个参数是json串,第二个参数是通过constructParametricType()获取到的JavaType。这样就能获得正确的List对象。
或者:

List<Information> informationList = objectMapper.convertValue(listBaseJson,new TypeReference<List<>>);

因为convertValue的对象是objecr,所以可以利用convertValue将list<Map<String, String>>转成List< Bean>。

对于Map对象的方法:

objectMapper.getTypeFactory().constructParametricType(HashMap.class,String.class,JavaBean.class);
Map<String,JavaBean> informationMap = objectMapper.readValue(baseMap,javaType);

与List是相同的,区别在于constructParametricType()需要三个参数,第一个参数表示是入参的Map形式的是Json串,并出参也是Map形式。第二个参数表示Map的中Key的类型,第三个参数是Value的类型,一般为我们定义java类。使用readValue()第一个参数是json串,第二个参数是通过constructParametricType()获取到的JavaType。
在map转换中,我尝试了使用使用引用类型(对象)而不是基本类型(Sring,Integer…)。例如如下操作:

JavaType javaType = objectMapper.getTypeFactory().constructParametricType(HashMap.class,JavaBean1.class,JavaBean.class);
Map<IdCard, User> informationMap = objectMapper.readValue(taesJson,javaType);

上述的测试是失败的。所以我感觉在使用这种方法转换时,map的key值只能是基本类型,不能是引用类型。至于其他转换方法。我暂时没有测试。

ObjectMapper的属性设置:

美化输出,转换为格式化的json

mapper.enable(SerializationFeature.INDENT_OUTPUT);  

强制JSON 空字符串("")转换为null对象值:

mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); 

允许序列化空的POJO类,否则序列化空对象是会抛出异常

mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);  

时间类型的转换,把java.util.Date, Calendar输出为数字(时间戳)

mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); 

在遇到未知属性的时候不抛出异常。

mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 

在JSON中允许C/C++ 样式的注释(非标准,默认禁用)

mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);   

如果json中有新增的字段并且是实体类类中不存在的,不报错。即在处理json串时是否允许json中的属性比对应类多。在可以提高扩展性。

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

允许没有引号的字段名(非标准)出现。

mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);  

允许单引号(非标准)

mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

强制转义非ASCII字符

mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);  

将内容包裹为一个JSON属性,属性名由@JsonRootName注解指定

mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true); 

null对象不转换为json

mapper.setSerializationInclusion(Include.NON_NULL); 

序列化的时候序列对象的所有属性

objectMapper.setSerializationInclusion(Include.ALWAYS);  

如果是空对象的时候,不抛异常

objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);  

取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式 。这里使用yyyyMMddHHmmss作为例子。大家可以根据自己需要进行设置。

objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setDateFormat(new SimpleDateFormat("yyyyMMddHHmmss"));  

以上的总结部分是我测试过的。很多是在网上找到的资料。由于时间关系,暂时没有时间测试。同时感谢广大总结者。有任何错误的地方。请指正,在此先谢谢了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值