Jackson
库,是基于java语言的开源json格式解析工具。Jackson两大分支codehaus
、fasterxml
。参考:Jackson两大分支codehaus、fasterxml的区别Jackson
从2.0开始改用新的包名fasterxml
,1.x版本的包名是codehaus。若是是新项目,建议直接用2x,即fasterxml jackson
。
整个库包含3个jar包:html
<!-- Jackson依赖库 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <!--2.8.8--> <version>${dependency.version.jackson}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${dependency.version.jackson}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>${dependency.version.jackson}</version> </dependency>
说明:java
jackson-core
——核心包(必须),提供基于“流模式”解析的API。jackson-databind
——数据绑定包(可选),提供基于“对象绑定”和“树模型”相关API。jackson-annotations
——注解包(可选),提供注解功能。其余:数据库
在时候用mybatis时,还有如下包,用于映射LocalDateTime与数据库中的time:json
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-typehandlers-jsr310</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency>
@JsonSerialize
该注解部分源码以下:mybatis
package com.fasterxml.jackson.databind.annotation; @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotation public @interface JsonSerialize { Class<? extends JsonSerializer> using() default None.class; Class<? extends JsonSerializer> contentUsing() default None.class; Class<? extends JsonSerializer> keyUsing() default None.class; ...
说明:app
RUNTIME
时,可反射获取;using
字段,传入格式为继承了JsonSerializer
的类的字节码Class<? extends JsonSerializer>
。JsonSerializer
类中,有一个抽象方法须要实现:ide
public abstract class JsonSerializer<T> implements JsonFormatVisitable { ... public abstract void serialize(T var1, JsonGenerator var2, SerializerProvider var3) throws IOException, JsonProcessingException; ... }
其中:工具
T
为待转换的数据对象;JsonGenerator
主要用于生成目标json
,有一系列的写
方法,如:writeStartObject()
、writeString()
等。(见下参考)
JsonGenerator
参考:测试
JsonGenerator
write
后的数据,即为转化后的数据。示例见下。.net
说明:
只有在调用序列化方法后,注解才会生效。仅仅注解某个元素后,打印结果,该注解并不会生效。
默认序列化,仅使用com.fasterxml.jackson.databind.ObjectMapper
下的writeValueAsString(yourEntity)
,便可序列化。如:
package jackson; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.annotation.JsonSerialize; public class CustomDoubleTest { private Double price; private String name; // getter and setter and toString... public static void main(String[] args) { CustomDoubleTest t = new CustomDoubleTest(); t.setPrice(3.14159); try { String serialized = new ObjectMapper().writeValueAsString(t); System.out.println(serialized); } catch (JsonProcessingException e) { e.printStackTrace(); } } }
该bean
的默认序列化结果格式:
{"price":"3.14159","name":null}
根据标题2.1
中所述,使用注解@JsonSerialize
时,传入using
参数的类,需实现JsonSerializer
。
/** * 将Double类型转换成保留两位小数的格式的字符串 */ public class CustomDoubleSerialize extends JsonSerializer<Double> { @Override public void serialize(Double aDouble, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { /** jsonGenerator写后的数据即为转换后的数据 */ jsonGenerator.writeString(new DecimalFormat("##.00").format(aDouble)); //jsonGenerator.writeString("test"); } }
public class CustomDoubleTest { /** * 该注解能够放在字段、getter或setter上 */ @JsonSerialize(using = CustomDoubleSerialize.class) private Double price; private String name; // 相似上述... public static void main(String[] args) { CustomDoubleTest t = new CustomDoubleTest(); t.setPrice(3.14159); /** 1.直接打印被注解的字段,即便有注解也不起做用 */ System.out.println("不调用序列化方法即便有注解也不会生效:"+t.getPrice()); /** 2.直接打印对象,按toString打印。即便有注解也不起做用 */ System.out.println(t); try { /** 该方法调用序列化方法,会以json格式展现 * 1.若是没有注解,仍然按默认的json格式展现 * 2.若是有注解(打开注释),按注解格式展现 * */ String serialized = new ObjectMapper().writeValueAsString(t); // 3.只有在调用序列化方法时,才会触发该注解。 System.out.println("调用序列化方法后,注解才生效:"+serialized); } catch (JsonProcessingException e) { e.printStackTrace(); } }
结果:
不调用序列化方法即便有注解也不会生效:3.14159 CustomDoubleTest{price=3.14159, name='null'} 调用序列化方法后,注解才生效:{"price":"3.14","name":null}
默认的序列化,能够将复杂的对象按默认格式序列化。如:
public class CustomDoubleTest1 { private int id; private String name; private List<CustomDoubleTest> list; private Map<Integer,String> pair; private Set<String> set; private Boolean flag; ... }
使用默认序列化后:
public static void main(String[] args) { CustomDoubleTest1 t = new CustomDoubleTest1(); // 给对象t赋值 t.setId(1); t.setName("hobe"); Map pair = new HashMap(); pair.put(1,"wang"); pair.put(2,"hong"); pair.put(3,"bing"); t.setPair(pair); List<CustomDoubleTest> list = new ArrayList<>(); list.add(new CustomDoubleTest()); t.setList(list); Set<String> set = new HashSet(); set.add("whbing.cn"); t.setSet(set); t.setFlag(true); try { /** * com.fasterxml.jackson.databind.ObjectMapper * 仅一个方法便可【将对象解析成json字符串】 */ String serialized = new ObjectMapper().writeValueAsString(t); // 只有在调用序列化方法时,才会触发该注解。 System.out.println(serialized); } catch (JsonProcessingException e) { e.printStackTrace(); } }
将会默认序列化为如下格式:
{ "id": 1, "name": "hobe", "list": [{ "price": null, "name": null }], "pair": { "1": "wang", "2": "hong", "3": "bing" }, "set": ["whbing.cn"], "flag": true }
即对象
和Map
将会以{}
包裹,List
和Set
将会以[]包裹。
高级自定义序列化
参考: jackson中自定义处理序列化和反序列化
public class CustomBeanSerialize extends JsonSerializer<CustomDoubleTest1> { @Override public void serialize(CustomDoubleTest1 entity, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { jsonGenerator.writeStartObject(); jsonGenerator.writeNumberField("id",entity.getId()); jsonGenerator.writeStringField("mapValue",entity.getList().get(0).getName()); jsonGenerator.writeEndObject(); } }
@JsonSerialize(using = CustomBeanSerialize.class) public class CustomDoubleTest1 { ...
String serialized = new ObjectMapper().writeValueAsString(t);
显示结果以下:
{"id":1,"mapValue":null}