Jackson的基本用法
参考链接:https://www.baeldung.com/jackson-object-mapper-tutorial
简介
Jackson是一个简单基于Java应用库,Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。Jackson所依赖的jar包较少,简单易用并且性能也要相对高些,并且Jackson社区相对比较活跃,更新速度也比较快。
其作用:json字符串—>JSON对象;JSON对象—>json字符串
清单1:在pmo.xml中配置的maven依赖
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.8.1</version> </dependency>
Jackson常用注解
表1.Jackson常用注解
@JsonGetter @JsonSetter
@JsonGetter用于标识该方法为该bean对象的getter方法;@JsonSetter用于标识该方法为该Bean对象的setter方法。
1 //用于标识该方法为name属性的Getter方法 2 @JsonGetter("name") 3 public String getNameProperties() { 4 return name; 5 }
@JsonPropertyOrder
用于类, 指定属性在序列化时 json 中的顺序,示例:
1 @JsonPropertyOrder({ "name", "id" }) 2 public class MyBean { 3 public int id; 4 public String name; 5 } 6 输出为: 7 { 8 "name":"My bean", 9 "id":1 10 }
@JsonRawValue
@JsonRawValue按照属性原样序列化该属性
1 public class RawBean { 2 public String name; 3 4 @JsonRawValue 5 public String json; 6 } 7 输出: 8 { 9 "name":"My bean", 10 "json":{ 11 "attr":false 12 } 13 }
@JsonValue
@JsonValue指定一个属性作为序列化后的值
1 package com.guava.bean; 2 import com.fasterxml.jackson.annotation.JsonValue; 3 4 public enum TypeEnumWithValue { 5 TYPE1(1, "Type A"), TYPE2(2, "Type 2"); 6 7 private Integer id; 8 private String name; 9 10 TypeEnumWithValue(Integer id, String name){ 11 this.id = id; 12 this.name = name; 13 } 14 15 @JsonValue 16 public String getName() { 17 return name; 18 } 19 20 public Integer getId(){ 21 return id; 22 } 23 } 24 25 输出为: 26 "Type A"
@JsonProperty
@JsonProperty 用于属性,把属性的名称序列化时转换为另外一个名称。示例:
@JsonProperty("birth_date")
private Date birthDate;
@JsonRootName
@JsonRootName设置序列化后的json字符串名称
1 @Test 2 public void whenSerializingUsingJsonAnyGetter_thenCorrect() 3 throws JsonProcessingException { 4 ExtendableBean bean = new ExtendableBean("{My bean}"); 5 bean.add("attr1", "val1"); 6 bean.add("attr2", "val2"); 7 ObjectMapper objectMapper = new ObjectMapper(); 8 objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE); 9 String result = objectMapper.writeValueAsString(bean); 10 log.info(result); 11 assertThat(result, containsString("attr1")); 12 assertThat(result, containsString("val1")); 13 } 14 15 package com.guava.bean; 16 import com.fasterxml.jackson.annotation.*; 17 import java.util.HashMap; 18 import java.util.Map; 19 20 @JsonRootName(value = "User") 21 public class ExtendableBean { 22 @JsonRawValue 23 public String name; 24 private Map<String, String> properties; 25 26 public ExtendableBean(String my_bean) { 27 this.name = my_bean; 28 this.properties = new HashMap<>(); 29 } 30 31 @JsonGetter("name") 32 public String getNameProperties() { 33 return name; 34 } 35 36 public void setName(String name) { 37 this.name = name; 38 } 39 40 public void setProperties(Map<String, String> properties) { 41 this.properties = properties; 42 } 43 44 45 public Map<String, String> getProperties() { 46 return properties; 47 } 48 49 public void add(String attr1, String val1) { 50 properties.put(attr1, val1); 51 } 52 } 53 54 输出: 55 {"User":{"name":{My bean},"properties":{"attr2":"val2","attr1":"val1"}}}
@JsonFormat
用于属性或者方法,用于序列化Date/Time的类型的属性。示例:
1 public class EventWithFormat { 2 public String name; 3 4 @JsonFormat( 5 shape = JsonFormat.Shape.STRING, 6 pattern = "dd-MM-yyyy hh:mm:ss") 7 public Date eventDate; 8 }
@JsonCreator
@JsonCreator用于修饰构造方法,和 @JsonProperty 配合使用,适用有参数的构造方法。 @JsonCreator在反序列化的过程中,来标明构造器,@JsonProperty 来指定Json字符串的属性名与对象的属性名的映射关系。示例:
1 序列化的json 2 { 3 "id":1, 4 "theName":"My bean" 5 } 6 public class BeanWithCreator { 7 public int id; 8 public String name; 9 10 @JsonCreator 11 public BeanWithCreator( 12 @JsonProperty("id") int id, 13 @JsonProperty("theName") String name) { 14 this.id = id; 15 this.name = name; 16 } 17 } 18 19 @Test 20 public void whenDeserializingUsingJsonCreator_thenCorrect() 21 throws IOException { 22 23 String json = "{\"id\":1,\"theName\":\"My bean\"}"; 24 //反序列化为BeanWithCreator 对象 25 BeanWithCreator bean = new ObjectMapper() 26 .readerFor(BeanWithCreator.class) 27 .readValue(json); 28 assertEquals("My bean", bean.name); 29 }
@JsonAnySetter
@JsonAnySetter用于属性或者方法,设置未反序列化的属性名和值作为键值存储到 map 中
1 public class ExtendableBean { 2 public String name; 3 private Map<String, String> properties; 4 5 @JsonAnySetter 6 public void add(String key, String value) { 7 properties.put(key, value); 8 } 9 } 10 11 @Test 12 public void whenDeserializingUsingJsonAnySetter_thenCorrect() 13 throws IOException { 14 String json 15 = "{\"name\":\"My bean\",\"attr2\":\"val2\",\"attr1\":\"val1\"}"; 16 17 ExtendableBean bean = new ObjectMapper() 18 .readerFor(ExtendableBean.class) 19 .readValue(json); 20 21 assertEquals("My bean", bean.name); 22 assertEquals("val2", bean.getProperties().get("attr2")); 23 } 24 需要序列化的json串: 25 { 26 "name":"My bean", 27 "attr2":"val2", 28 "attr1":"val1" 29 }
@JsonSerialize,@JsonDeserialize
@JsonSerialize用于自定义序列化属性,@JsonDeserialize用于自定义反序列化属性
@JsonAnyGetter
用于Map属性 ,将Map的key序列化为属性值
1 @JsonAnyGetter 2 public Map<String, String> getProperties() { 3 return properties; 4 } 5 使用输出:{"name":"My bean","attr2":"val2","attr1":"val1"} 6 未使用输出:{"name":"My bean","properties":{"attr2":"val2","attr1":"val1"}}
@JsonIgnoreProperties
@JsonIgnoreProperties表示序列化的时候忽略该属性,表示类级别的忽略该属性
1 @JsonIgnoreProperties({ "id" }) 2 public class BeanWithIgnore { 3 public int id; 4 public String name; 5 } 6 @Test 7 public void whenSerializingUsingJsonIgnoreProperties_thenCorrect() 8 throws JsonProcessingException { 9 10 BeanWithIgnore bean = new BeanWithIgnore(1, "My bean"); 11 12 String result = new ObjectMapper() 13 .writeValueAsString(bean); 14 15 assertThat(result, containsString("My bean")); 16 assertThat(result, not(containsString("id"))); 17 }
@JsonIgnore
@JsonIgnore表示忽略该属性
1 public class BeanWithIgnore { 2 @JsonIgnore 3 public int id; 4 5 public String name; 6 }
@JsonIgnoreType
@JsonIgnoreType修饰一个引用对象,被修饰的对象的所有属性都被忽略,不需要进行序列化。
1 public class User { 2 public int id; 3 public Name name; 4 5 //Name对象的所有属性都不被序列化 6 @JsonIgnoreType 7 public static class Name { 8 public String firstName; 9 public String lastName; 10 } 11 }
@JsonInclude
@JsonInclude用来当属性为空/null/默认值的属性时,不序列化该属性
1 @JsonInclude(Include.NON_NULL) 2 public class MyBean { 3 public int id; 4 public String name; 5 }
ObjectMapper的使用
主要功能是实现Java对象与Json字符串之间的互换。
序列化,mapper.writeValue()方法可以将对象序列化到Writer,DataOutput,File等IO流中,或者JsonGenerator中。
mapper.writerValueAsString()可以将对象序列化成为字符串。
package com.guava.bean; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @Data @NoArgsConstructor @AllArgsConstructor @Builder public class Car { private String color; private String type; } @Test public void serializeObject() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); Car car = new Car("blue", "JiLi"); String carJson = mapper.writeValueAsString(car); log.info(carJson); } 输出: {"color":"blue","type":"JiLi"}
反序列化,mapper.readValue()方法,将URL,String,IO流等类型对象序列化成为一个对象。
1 Car car1 = mapper.readValue(carJson, Car.class); 2 输出: 3 Car(color=blue, type=JiLi)
1.使用writeValue()方法将对象序列化成不同格式,
对象的序列化与反序列化
@Test
public void serializeObject() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Car car = new Car("blue", "JiLi");
//将对象序列化成为字符串
String carJson = mapper.writeValueAsString(car);
log.info(carJson);
//将字符串反序列化成为Car对象
Car car1 = mapper.readValue(carJson, Car.class);
//将URL中的json字符串序列化mapper
//Car car2 =
.readValue(
new
URL(
"file:src/test/resources/json_car.json"
), Car.
class
)
log.info(car1.toString());
}
将Json字符串转换为JsonNode
1 String json = "{ \"color\" : \"Black\", \"type\" : \"FIAT\" }"; 2 JsonNode jsonNode = objectMapper.readTree(json); 3 String color = jsonNode.get("color").asText();
集合序列化和反序列化
1 @Test 2 public void serializeCarList() throws JsonProcessingException { 3 ObjectMapper mapper = new ObjectMapper(); 4 List<Car> cars = Lists.newArrayList(); 5 for (int i = 0; i < 3; i++){ 6 Car car = new Car("blue" + i, "JiLi" + i); 7 cars.add(car); 8 } 9 String serialCar = mapper.writeValueAsString(cars); 10 List<Car> deSerialCar = mapper.readValue(serialCar, new TypeReference<List<Car>>(){}); 11 log.info(deSerialCar.toString()); 12 }
JsonUtils工具类
1 import java.util.ArrayList; 2 import java.util.HashMap; 3 import java.util.List; 4 import java.util.Map; 5 6 import com.fasterxml.jackson.annotation.JsonInclude; 7 import com.fasterxml.jackson.core.type.TypeReference; 8 import com.fasterxml.jackson.databind.DeserializationFeature; 9 import com.fasterxml.jackson.databind.JavaType; 10 import com.fasterxml.jackson.databind.ObjectMapper; 11 12 public class JacksonUtils { 13 14 private final static ObjectMapper objectMapper = new ObjectMapper(); 15 16 private JacksonUtils() { 17 18 } 19 20 public static ObjectMapper getInstance() { 21 return objectMapper; 22 } 23 24 /** 25 * javaBean、列表数组转换为json字符串 26 */ 27 public static String obj2json(Object obj) throws Exception { 28 return objectMapper.writeValueAsString(obj); 29 } 30 31 /** 32 * javaBean、列表数组转换为json字符串,忽略空值 33 */ 34 public static String obj2jsonIgnoreNull(Object obj) throws Exception { 35 ObjectMapper mapper = new ObjectMapper(); 36 mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 37 return mapper.writeValueAsString(obj); 38 } 39 40 /** 41 * json 转JavaBean 42 */ 43 44 public static <T> T json2pojo(String jsonString, Class<T> clazz) throws Exception { 45 objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); 46 return objectMapper.readValue(jsonString, clazz); 47 } 48 49 /** 50 * json字符串转换为map 51 */ 52 public static <T> Map<String, Object> json2map(String jsonString) throws Exception { 53 ObjectMapper mapper = new ObjectMapper(); 54 mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); 55 return mapper.readValue(jsonString, Map.class); 56 } 57 58 /** 59 * json字符串转换为map 60 */ 61 public static <T> Map<String, T> json2map(String jsonString, Class<T> clazz) throws Exception { 62 Map<String, Map<String, Object>> map = objectMapper.readValue(jsonString, new TypeReference<Map<String, T>>() { 63 }); 64 Map<String, T> result = new HashMap<String, T>(); 65 for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) { 66 result.put(entry.getKey(), map2pojo(entry.getValue(), clazz)); 67 } 68 return result; 69 } 70 71 /** 72 * 深度转换json成map 73 * 74 * @param json 75 * @return 76 */ 77 public static Map<String, Object> json2mapDeeply(String json) throws Exception { 78 return json2MapRecursion(json, objectMapper); 79 } 80 81 /** 82 * 把json解析成list,如果list内部的元素存在jsonString,继续解析 83 * 84 * @param json 85 * @param mapper 解析工具 86 * @return 87 * @throws Exception 88 */ 89 private static List<Object> json2ListRecursion(String json, ObjectMapper mapper) throws Exception { 90 if (json == null) { 91 return null; 92 } 93 94 List<Object> list = mapper.readValue(json, List.class); 95 96 for (Object obj : list) { 97 if (obj != null && obj instanceof String) { 98 String str = (String) obj; 99 if (str.startsWith("[")) { 100 obj = json2ListRecursion(str, mapper); 101 } else if (obj.toString().startsWith("{")) { 102 obj = json2MapRecursion(str, mapper); 103 } 104 } 105 } 106 107 return list; 108 } 109 110 /** 111 * 把json解析成map,如果map内部的value存在jsonString,继续解析 112 * 113 * @param json 114 * @param mapper 115 * @return 116 * @throws Exception 117 */ 118 private static Map<String, Object> json2MapRecursion(String json, ObjectMapper mapper) throws Exception { 119 if (json == null) { 120 return null; 121 } 122 123 Map<String, Object> map = mapper.readValue(json, Map.class); 124 125 for (Map.Entry<String, Object> entry : map.entrySet()) { 126 Object obj = entry.getValue(); 127 if (obj != null && obj instanceof String) { 128 String str = ((String) obj); 129 130 if (str.startsWith("[")) { 131 List<?> list = json2ListRecursion(str, mapper); 132 map.put(entry.getKey(), list); 133 } else if (str.startsWith("{")) { 134 Map<String, Object> mapRecursion = json2MapRecursion(str, mapper); 135 map.put(entry.getKey(), mapRecursion); 136 } 137 } 138 } 139 140 return map; 141 } 142 143 /** 144 * 与javaBean json数组字符串转换为列表 145 */ 146 public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception { 147 148 JavaType javaType = getCollectionType(ArrayList.class, clazz); 149 List<T> lst = (List<T>) objectMapper.readValue(jsonArrayStr, javaType); 150 return lst; 151 } 152 153 154 /** 155 * 获取泛型的Collection Type 156 * 157 * @param collectionClass 泛型的Collection 158 * @param elementClasses 元素类 159 * @return JavaType Java类型 160 * @since 1.0 161 */ 162 public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) { 163 return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses); 164 } 165 166 167 /** 168 * map 转JavaBean 169 */ 170 public static <T> T map2pojo(Map map, Class<T> clazz) { 171 return objectMapper.convertValue(map, clazz); 172 } 173 174 /** 175 * map 转json 176 * 177 * @param map 178 * @return 179 */ 180 public static String mapToJson(Map map) { 181 try { 182 return objectMapper.writeValueAsString(map); 183 } catch (Exception e) { 184 e.printStackTrace(); 185 } 186 return ""; 187 } 188 189 /** 190 * map 转JavaBean 191 */ 192 public static <T> T obj2pojo(Object obj, Class<T> clazz) { 193 return objectMapper.convertValue(obj, clazz); 194 } 195 } 196 }