本文将为您提供关于使用Java和Jackson将Json序列化为通用结构而无需模式的详细介绍,我们还将为您解释javajson序列化的相关知识,同时,我们还将为您提供关于android–只使用Jack
本文将为您提供关于使用Java和Jackson将Json序列化为通用结构而无需模式的详细介绍,我们还将为您解释java json 序列化的相关知识,同时,我们还将为您提供关于android – 只使用Jackson将超类字段序列化为JSON、angularjs – 让Jackson将Java 8 Instant序列化为纪元毫秒的有效方法吗?、Fastjson和Jackson序列化和读取json的性能实测、Jackson真的无法将json反序列化为通用类型吗?的实用信息。
本文目录一览:- 使用Java和Jackson将Json序列化为通用结构而无需模式(java json 序列化)
- android – 只使用Jackson将超类字段序列化为JSON
- angularjs – 让Jackson将Java 8 Instant序列化为纪元毫秒的有效方法吗?
- Fastjson和Jackson序列化和读取json的性能实测
- Jackson真的无法将json反序列化为通用类型吗?
使用Java和Jackson将Json序列化为通用结构而无需模式(java json 序列化)
我需要序列化JSON,而不必附加到生成对象的特定架构,例如,某些通用set / map / hashmap。
作为输入 ,我有一个带有JSON的字符串。我不知道该JSON的架构。
作为输出, 我想要一个具有输入键值序列化的Java对象(例如Hashmap或类似对象)。
请注意, 输入JSON既具有基本字段,又具有Array / List。
我必须使用Java和Jackson(或其他一些库)。我怎么可能那样做?
答案1
小编典典Jackson数据绑定功能可以使用String键和Object值(也可以是地图或集合)将任何json输入读取到Map中。您只是告诉映射器,您想将json读入映射。您可以通过给映射器适当的类型引用来做到这一点:
import java.util.*;import com.fasterxml.jackson.core.type.TypeReference;import com.fasterxml.jackson.databind.ObjectMapper;public class Test{ public static void main(String[] args) { try { String json = "{ " + "\"string-property\": \"string-value\", " + "\"int-property\": 1, " + "\"bool-property\": true, " + "\"collection-property\": [\"a\", \"b\", \"c\"], " + "\"map-property\": {\"inner-property\": \"inner-value\"} " + "}"; ObjectMapper mapper = new ObjectMapper(); Map<String, Object> map = new HashMap<>(); // convert JSON string to Map map = mapper.readValue(json, new TypeReference<Map<String, Object>>(){}); System.out.println("input: " + json); System.out.println("output:"); for (Map.Entry<String, Object> entry : map.entrySet()) { System.out.println("key: " + entry.getKey()); System.out.println("value type: " + entry.getValue().getClass()); System.out.println("value: " + entry.getValue().toString()); } } catch (Exception e) { e.printStackTrace(); } }}
输出:
input: { "string-property": "string-value", "int-property": 1, "bool-property": true, "collection-property": ["a", "b", "c"], "map-property": {"inner-property": "inner-value"} }output:key: string-propertyvalue type: class java.lang.Stringvalue: string-valuekey: int-propertyvalue type: class java.lang.Integervalue: 1key: bool-propertyvalue type: class java.lang.Booleanvalue: truekey: collection-propertyvalue type: class java.util.ArrayListvalue: [a, b, c]key: map-propertyvalue type: class java.util.LinkedHashMapvalue: {inner-property=inner-value}
android – 只使用Jackson将超类字段序列化为JSON
仅序列化此实例的超类的字段的最佳方法是什么?
目前我必须将JSONIgnore注释添加到我的子类中的每个方法,
有没有更好的方法呢?
解决方法
public class Account implements Serializable { private String accountNumber; private String routingNumber; private BigDecimal balance; // Constructors,setters/getters } public class SavingsAccount extends Account { private BigDecimal savingsRate; // Constructors,setters/getters } final ObjectMapper mapper = new ObjectMapper(); final ObjectWriter writer = mapper.writerWithType(Account.class); final ByteArrayOutputStream baos = new ByteArrayOutputStream(6400); final SavingsAccount account = new SavingsAccount("0031-3402-2189","0009835011203",BigDecimal.valueOf(53500),BigDecimal.valueOf(0.3)); writer.writeValue(baos,account); final String results = new String(baos.toByteArray()); baos.close(); System.out.println(results);
运行上面的代码说明了Jackson编写超类字段,即使运行时实例属于子类类型.
{"accountNumber":"0031-3402-2189","routingNumber":"0009835011203","balance":53500}
编辑:
Thanks,but in my case I try to achieve this behavIoUr for several
classes are fields of the outer class that I serialize. Can I define
the types more in general?
这种情况更容易处理.只需使用@JsonSerialize注释外部类中的相应字段.如果将字段声明为超类类型,则将键入设置为静态.这将使用编译时类型而不是运行时类型将那些字段标记为Jackson以进行序列化.
另一方面,如果将字段声明为子类类型,则将using设置为超类.
以下示例使用我在上面进一步定义的类:
public class BankCustomer implements Serializable { @JsonSerialize(typing=Typing.STATIC) private Account cdAccount; @JsonSerialize(using=Account.class) private SavingsAccount savingsAccount; }
angularjs – 让Jackson将Java 8 Instant序列化为纪元毫秒的有效方法吗?
在Java方面,杰克逊将使用的吸气剂就是:
public Instant getMyInstantVal() { return myInstantVal; }
序列化不会按原样运行,因为默认情况下,jackson-datatype-jsr310不会返回Epoch毫秒数.我看着将@JsonFormat添加到上面的getter中以将Instant变成前端可以使用的东西,但是它遇到两个问题:(1)我可以提供它的模式显然仅限于SimpleDateFormat,它不提供“ epoch milliseconds“选项,以及(2)当我尝试将Instant作为格式化日期发送到浏览器时,Jackson会抛出异常,因为@JsonFormat注释需要Instants的TimeZone属性,我不想硬编码为它会因用户而异.
到目前为止我的解决方案(并且工作正常)是使用@JsonGetter创建替换getter,这会导致Jackson使用此方法来序列化myInstantVal:
@JsonGetter("myInstantVal") public long getMyInstantValEpoch() { return myInstantVal.toEpochMilli(); }
这是正确的方法吗?或者是否有一个很好的注释,我错过了我可以放在getMyInstantVal()所以我不必创建这些额外的方法?
解决方法
Most JSR-310 types are serialized as numbers (integers or decimals as appropriate) if the SerializationFeature#WRITE_DATES_AS_TIMESTAMPS feature is enabled,and otherwise are serialized in standard ISO-8601 string representation.
[…]
Granularity of timestamps is controlled through the companion features SerializationFeature#WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS and DeserializationFeature#READ_DATE_TIMESTAMPS_AS_NANOSECONDS. For serialization,timestamps are written as fractional numbers (decimals),where the number is seconds and the decimal is fractional seconds,if WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS is enabled (it is by default),with resolution as fine as nanoseconds depending on the underlying JDK implementation. If WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS is disabled,timestamps are written as a whole number of milliseconds.
Fastjson和Jackson序列化和读取json的性能实测
偶然间看到的阿里出品的Fastjson,网上对这个json包好评如潮,性能胜Jackson10倍。
本人本着眼见为实的想法,自己测试一下两者的性能比较。
###测试### POJO对象名字为User,具体代码就不贴了,里面有两个属性,分别是int类型的id和String类型的name,很简单的一个类。
测试程序(只是简单的测试下,这里并未深究其中的各种构造方法)
public class MyMain {
private static final int TEST_CASE_NUM = 1000;
public static void main(String args[]) throws IOException {
List<User> users = new ArrayList<User>();
Random random = new Random();
for (int i = 0; i < TEST_CASE_NUM; i++) {
User user = new User();
user.setId(random.nextInt(10));
user.setName("123");
users.add(user);
}
Monitor.begin();
for (User u : users){
String s = JSON.toJSONString(u);
}
Monitor.end("serilization of fastjson");
Monitor.begin();
/**
* 这里仅创建一个ObjectMapper实例
* 而网上的很多测试程序中,把实例的创建过程
* 加入到了for循环中,因此测出来的序列化性能
* 有10倍之差,其实其中大部分都消耗在了ObejectMapper
* 实例创建上。
*/
ObjectMapper objectMapper = new ObjectMapper();
for (User u : users){
String s = objectMapper.writeValueAsString(u);
}
long endjackson = System.currentTimeMillis();
Monitor.end("serilization of jackson");
List<String> strs = new ArrayList<String>();
for (int j = 0; j < TEST_CASE_NUM; j++) {
String s = new String("{\"id\":1,\"name\":\"123\"}");
strs.add(s);
}
Monitor.begin();
for (String s : strs){
User user = JSON.parseObject(s,User.class);
}
Monitor.end("reading string by fastjson");
Monitor.begin();
ObjectMapper obj = new ObjectMapper();
for (String s : strs){
User user = obj .readValue(s,User.class);
}
Monitor.end("reading string by jackson");
}
}
运行程序得到输出:
serilization of fastjson use 158 ms
serilization of jackson use 339 ms
reading string by fastjson use 49 ms
reading string by jackson use 73 ms
多次运行后结果相差甚微,比例关系基本保持稳定。由此可见fastjson并未如网上传言那般,性能较之于jackson提升10倍。如果将ObjectMapper实例的创建过程也从计时器中提取出来,哪么Jackson与fastjson的序列化性能几乎相同。
然而在反序列方面,fastjson以巨大的优势领先Jackson,将测试的用例个数增加至1000000,得到的输出为:
reading string by fastjson use 505 ms
reading string by jackson use 1051 ms
fastjson几乎只需要Jackson的一半时间,这个表现相当亮眼。
在这里我们反序列化的字符串是按照实体类中属性的顺序排列的,如果打乱一下顺序呢?
这里还是使用1000000个测试用例,得到的输出结果为:
reading string by fastjson use 715 ms
reading string by jackson use 1049 ms
因为fastjson默认开启了sort field martch优化算法
,打乱顺序之后性能下降,但仍然领先Jackson不少。
###总结### 这次测试使用的是1.9.31版本的Jackson和1.1.39版本的fasijson,测试结果表名fastjson和Jackson在序列化性能上相差不大(主要ObjectMapper类新建实例耗费不少时间),但是在反序列化方面,fastjson要明显领先于Jackson。
Jackson真的无法将json反序列化为通用类型吗?
我希望这个问题最终能找到一个答案,使之永远清楚。
有模特儿:
public class AgentResponse<T> {
private T result;
public AgentResponse(T result) {
this.result = result;
}
public T getResult() {
return result;
}
}
JSON输入:
{"result":{"first-client-id":3,"test-mail-module":3,"third-client-id":3,"second-client-id":3}}
以及两种反序列化泛型类型的推荐方法:
mapper.readValue(out,new TypeReference<AgentResponse<Map<String,Integer>>>() {});
要么
JavaType javaType = mapper.getTypeFactory().constructParametricType(AgentResponse.class,Map.class);
mapper.readValue(out,javaType);
Jackson永远无法处理通用类型T,它认为这是JavaType的Map,但由于类型擦除而找到了对象类型构造函数参数,并抛出错误。那是杰克逊的臭虫,还是我做错了什么?TypeReference或JavaType的显式规范还有什么用?
com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type,class com.fg.mail.smtp.AgentResponse<java.util.Map<java.lang.String,java.lang.Integer>>]: can not instantiate from JSON object (need to add/enable type information?)
at [Source: java.io.InputStreamReader@4f2d26d; line: 1,column: 2]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:984)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:276)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2064)
关于使用Java和Jackson将Json序列化为通用结构而无需模式和java json 序列化的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于android – 只使用Jackson将超类字段序列化为JSON、angularjs – 让Jackson将Java 8 Instant序列化为纪元毫秒的有效方法吗?、Fastjson和Jackson序列化和读取json的性能实测、Jackson真的无法将json反序列化为通用类型吗?等相关内容,可以在本站寻找。
本文标签: