先来看下如何自定义把某个对象序列化为json:
先是对象:
- public class User {
- public int id;
- public String name;
- }
- public class Item {
- public int id;
- public String itemName;
- public User owner;
- }
JACKSON一般的使用很容易,如;
Item myItem = new Item(1, "theItem", new User(2, "theUser"));
String serialized = new ObjectMapper().writeValueAsString(myItem);
结果为:
{
"id": 1,
"itemName": "theItem",
"owner": {
"id": 2,
"name": "theUser"
}
}
如果要输出为如下的样子,比如;
{
"id": 25,
"itemName": "FEDUfRgS",
"owner": 15
}
则要自定义了,要继承JsonSerializer类,如下:
- public class ItemSerializer extends JsonSerializer<Item> {
- @Override
- public void serialize(Item value, JsonGenerator jgen, SerializerProvider provider)
- throws IOException, JsonProcessingException {
- jgen.writeStartObject();
- jgen.writeNumberField("id", value.id);
- jgen.writeStringField("itemName", value.itemName);
- jgen.writeNumberField("owner", value.owner.id);
- jgen.writeEndObject();
- }
- }
然后
- Item myItem = new Item(1, "theItem", new User(2, "theUser"));
- ObjectMapper mapper = new ObjectMapper();
- SimpleModule module = new SimpleModule();
- module.addSerializer(Item.class, new ItemSerializer());
- mapper.registerModule(module);
- String serialized = mapper.writeValueAsString(myItem);
看,相当复杂,然后看有无办法简单点,其实是有的哦;方法为:
- @JsonSerialize(using = ItemSerializer.class)
- public class Item {
- ...
- }
就是使用注解@JsonSerialize,然后:
- Item myItem = new Item(1, "theItem", new User(2, "theUser"));
- String serialized = new ObjectMapper().writeValueAsString(myItem);
接下来看如何反序列化了,
同样,要反序列化的两个pojo为:
- public class User {
- public int id;
- public String name;
- }
- public class Item {
- public int id;
- public String itemName;
- public User owner;
- }
反序列化代码为:
Item itemWithOwner = new ObjectMapper().readValue(json, Item.class);
如果要自定义反序列化,比如要反序列化的JSON为;
{
"id": 1,
"itemName": "theItem",
"owner": 2
}
则上面这样会报错:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "createdBy" (class org.baeldung.jackson.dtos.Item),
not marked as ignorable (3 known properties: "id", "owner", "itemName"])
at [Source: java.io.StringReader@53c7a917; line: 1, column: 43]
(through reference chain: org.baeldung.jackson.dtos.Item["createdBy"])
代码:
- public class ItemDeserializer extends JsonDeserializer<Item> {
- @Override
- public Item deserialize(JsonParser jp, DeserializationContext ctxt)
- throws IOException, JsonProcessingException {
- JsonNode node = jp.getCodec().readTree(jp);
- int id = (Integer) ((IntNode) node.get("id")).numberValue();
- String itemName = node.get("itemName").asText();
- int userId = (Integer) ((IntNode) node.get("id")).numberValue();
- return new Item(id, itemName, new User(userId, null));
- }
- }
- ObjectMapper mapper = new ObjectMapper();
- SimpleModule module = new SimpleModule();
- module.addDeserializer(Item.class, new ItemDeserializer());
- mapper.registerModule(module);
- Item readValue = mapper.readValue(json, Item.class);
也可以用注解:
@JsonDeserialize(using = ItemDeserializer.class)
public class Item {
...
}
package com.qunar.search.evaltool.vo;
import java.io.IOException;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializerProvider;
public class EvalTargetVOSerializer extends JsonSerializer<EvalTargetVO>{
@Override
public void serialize(EvalTargetVO value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(jgen, value.getEvalFields());
}
}
我们简单将EvalTargetVO的evalFields的hashmap使用ObjectMapper写入JsonGenerator即可转换成目标格式。
我们在使用注解来指定Json序列化为我们自定义个序列化类:
- @JsonSerialize(using=EvalTargetVOSerializer.class)
- public class EvalTargetVO
EvalTargetVOSerializer甚至可以写在属性上。。。