参考:
https://juejin.cn/post/6844904166809157639
https://blog.csdn.net/f641385712/category_10175312.html
https://juejin.cn/post/6844904113017192456
<!-- 根据自己需要引入相关版本依赖。 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.10</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.10</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
public class User implements Serializable {
private String name;
private Integer age;
private int sex;
private int height = 160;
private Date birth;
private boolean valid;
/*private User user; // 不能自引用,否则write不出来
public User() {
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}*/
/* // 一些get和is方法,但是没有对应的属性
public Object isHandsome() {
return "帅";
}
public Object getXx() {
return "123";
}*/
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
", height=" + height +
", birth=" + birth +
", valid=" + valid +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public boolean isValid() {
return valid;
}
public void setValid(boolean valid) {
this.valid = valid;
}
}
package com.zzhua;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.zzhua.pojo.User;
import org.junit.Before;
import org.junit.Test;
import java.io.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
public class ObjectMapperTest {
User user;
@Before
public void init() {
User user = new User();
user.setName("曾zzhua");
user.setAge(25);
user.setSex(1);
user.setHeight(55);
user.setBirth(new Date());
user.setValid(true);
this.user = user;
}
@Test
public void test_00() {
ObjectMapper mapper = new ObjectMapper();
String s = null;
try {
s = mapper.writeValueAsString(new User());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
/*{"name":null,"age":null,"sex":0,"height":160,"birth":null,"valid":false,"user":null}*/
System.out.println(s);
try {
byte[] bytes = mapper.writeValueAsBytes(new User());
/*{"name":null,"age":null,"sex":0,"height":160,"birth":null,"valid":false,"user":null}*/
System.out.println(new String(bytes));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
// mapper.writeValue(Writer,Object);
// mapper.writeValue(OutputStream, Object);
// mapper.writeValue(File,Object);
// mapper.writeValue(JsonGenerator, Object);
ObjectWriter objectWriter = mapper.writerWithDefaultPrettyPrinter();
try {
/**
// 输出
{
"name" : "曾zzhua",
"age" : 25,
"sex" : 1,
"height" : 55,
"birth" : 1625897473042,
"valid" : true,
"user" : null
}
*/
String t = objectWriter.writeValueAsString(user);
System.out.println(t);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
@Test
public void test_01() {
ObjectMapper mapper = new ObjectMapper();
String s = null;
try {
// user.setUser(user); // 注意:User中不能自引用,否则导致循环,抛出异常
s = mapper.writeValueAsString(user);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(s); //{"name":"曾zzhua","age":25,"sex":1,"height":55,"birth":1625895996173,"valid":true}
}
@Test
public void test_02() {
ObjectMapper mapper = new ObjectMapper();
// 开启序列化时的美化
mapper.enable(SerializationFeature.INDENT_OUTPUT);
String s = null;
try {
s = mapper.writeValueAsString(user);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
/*
// 美化输出方式
{
"name" : "曾zzhua",
"age" : 25,
"sex" : 1,
"height" : 55,
"birth" : 1625896198831,
"valid" : true
}
*/
System.out.println(s);
}
@Test
public void test_03() {
ObjectMapper mapper = new ObjectMapper();
// 关闭自引用,但是还是不能直接设置本身,否则还是会递归下去
mapper.configure(SerializationFeature.FAIL_ON_SELF_REFERENCES, false);
String s = null;
try {
// user.setUser(new User()); // 注意:User中不能自引用,否则导致循环,抛出异常
s = mapper.writeValueAsString(user);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(s);
}
@Test
public void test_04() {
ArrayList<User> list = new ArrayList<>();
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
list.add(user);
list.add(new User());
String s = null;
try {
/**
* [ {
"name" : "曾zzhua",
"age" : 25,
"sex" : 1,
"height" : 55,
"birth" : 1625897250264,
"valid" : true,
"user" : null
}, {
"name" : null,
"age" : null,
"sex" : 0,
"height" : 160,
"birth" : null,
"valid" : false,
"user" : null
} ]
*/
s = mapper.writeValueAsString(list);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(s);
}
@Test
public void test_05() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
// 写一些其它的数据类型
// 输出:1625901330439
System.out.println(mapper.writeValueAsString(new Date()));
// 输出:1
System.out.println(mapper.writeValueAsString(1));
// 输出:1
System.out.println(mapper.writeValueAsString(new Integer(1)));
// 输出:true
System.out.println(mapper.writeValueAsString(true));
// 输出:true
System.out.println(mapper.writeValueAsString(Boolean.TRUE));
// 输出:{"hour":15,"minute":16,"nano":412000000,"second":39,"dayOfMonth":10,
// "dayOfWeek":"SATURDAY","month":"JULY","year":2021,"dayOfYear":191,
// "monthValue":7,"chronology":{"id":"ISO","calendarType":"iso8601"}}
System.out.println(mapper.writeValueAsString(LocalDateTime.now()));
// 输出:"ab\u0003"
char[] chars = {'a','b',3};
System.out.println(mapper.writeValueAsString(chars));
// 输出:""
System.out.println(mapper.writeValueAsString(""));
// 输出:null
System.out.println(mapper.writeValueAsString(null));
}
@Test
public void test_06() throws JsonProcessingException {
// 给user添加了一个isHandsome()和getXx()方法,但是没有对应的属性
ObjectMapper mapper = new ObjectMapper();
String s = mapper.writeValueAsString(user);
// 输出: {"name":"曾zzhua","age":25,"sex":1,"height":55,"birth":1625901740557,"valid":true,"xx":"123"}
System.out.println(s);
}
@Test
public void test_07() throws IOException {
ObjectMapper mapper = new ObjectMapper();
/*{"name":null,"age":null,"sex":0,"height":160,"birth":null,"valid":false}*/
String defaultUserStr = mapper.writeValueAsString(new User());
System.out.println(defaultUserStr);
// 读取默认user的字符串
User defaultUser = mapper.readValue(defaultUserStr, User.class);
// User{name='null', age=null, sex=0, height=160, birth=null, valid=false}
System.out.println(defaultUser);
}
@Test
public void test_08() throws IOException {
ObjectMapper mapper = new ObjectMapper();
// json字符串中少了个valid(布尔类型),看能不能读出来
String userStr = "{\"name\":null,\"age\":null,\"sex\":0,\"height\":160,\"birth\":null}";
// User{name='null', age=null, sex=0, height=160, birth=null, valid=false}
User defaultUser = mapper.readValue(userStr, User.class);
System.out.println(defaultUser);
// json字符串中多了数据,能否读出来
String userStr2 = "{\"name\":\"曾zzhua\",\"age\":25,\"sex\":1,\"height\":55,\"birth\":1625901740557,\"valid\":true,\"xx\":\"123\"}";
// 报错!!!
/*com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:
Unrecognized field "xx" (class com.zzhua.pojo.User), not marked as ignorable
(6 known properties: "sex", "height", "name", "valid", "age", "birth"])
at [Source: (String)"{"name":"曾zzhua","age":25,"sex":1,"height":55,
"birth":1625901740557,"valid":true,"xx":"123"}"; line: 1, column: 88]
(through reference chain: com.zzhua.pojo.User["xx"])*/
// 这里有两种解决方案:
// 1、mapper2.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 即可
// 2、或者在类上添加注解@JsonIgnoreProperties(ignoreUnknown = true);即可
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
User user2 = mapper.readValue(userStr2, User.class);
System.out.println(user2);
// 如果用Object类型来接受,能获取到正确的类型么?
Object o = mapper.readValue(userStr2, Object.class);
// 输出:class java.util.LinkedHashMap
System.out.println(o.getClass());
// 输出:{name=曾zzhua, age=25, sex=1, height=55, birth=1625901740557, valid=true, xx=123}
System.out.println(o);
LinkedHashMap map = (LinkedHashMap) o;
/* 输出:
name class java.lang.String 曾zzhua
age class java.lang.Integer 25
sex class java.lang.Integer 1
height class java.lang.Integer 55
birth class java.lang.Long 1625901740557
valid class java.lang.Boolean true
xx class java.lang.String 123*/
map.forEach((key,val)->{
System.out.print(key + " ");
System.out.print(val.getClass() + " ");
System.out.println(val);
});
}
@Test
public void test_09() throws IOException {
ObjectMapper mapper = new ObjectMapper();
// 全部没有,能否读出来
String userStr = "{}";
User defaultUser = mapper.readValue(userStr, User.class);
// User{name='null', age=null, sex=0, height=160, birth=null, valid=false}
System.out.println(defaultUser);
}
@Test
public void test_10() throws IOException {
ObjectMapper mapper = new ObjectMapper();
// 空字符串,能否读出来
String userStr2 = "";
// 报错!!!
/*com.fasterxml.jackson.databind.exc.MismatchedInputException:
No content to map due to end-of-input
at [Source: (String)""; line: 1, column: 0]*/
User defaultUser2 = mapper.readValue(userStr2, User.class);
System.out.println(defaultUser2);
}
@Test
public void test_11() throws IOException {
ObjectMapper mapper = new ObjectMapper();
// null,能否读出来
String userStr = null;
// 报错,空指针异常
User defaultUser = mapper.readValue(userStr, User.class);
System.out.println(defaultUser);
}
@Test
public void test_12() {
LocalDateTime now = LocalDateTime.now();
ObjectMapper mapper = new ObjectMapper();
try {
String s = mapper.writeValueAsString(now);
System.out.println(s);
/* 报错
* com.fasterxml.jackson.databind.exc.InvalidDefinitionException:
* Cannot construct instance of `java.time.LocalDateTime`
* (no Creators, like default construct, exist): cannot deserialize from Object value
* (no delegate- or property-based Creator)
at [Source: (String)"{"dayOfMonth":10,"dayOfWeek":"SATURDAY","month":"JULY",
"year":2021,"dayOfYear":191,"hour":16,"minute":58,"monthValue":7,
"nano":869000000,"second":42,"chronology":{"id":"ISO","calendarType":"iso8601"}}";
line: 1, column: 2]
* */
LocalDateTime localDateTime = mapper.readValue(s, LocalDateTime.class);
System.out.println(localDateTime);
} catch (JsonProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test_13() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
// 输出:{"name":"曾zzhua","age":25,"sex":1,"height":55,"birth":1636788268941,"valid":true}
String userJson = objectMapper.writeValueAsString(user);
System.out.println(userJson);
User user = objectMapper.readValue(userJson, User.class);
// 输出:User{name='曾zzhua', age=25, sex=1, height=55, birth=Sat Nov 13 15:27:11 CST 2021, valid=true}
System.out.println(user);
Map map = objectMapper.readValue(userJson, Map.class);
/*
输出:
【name->曾zzhua】- 【class java.lang.String->class java.lang.String】
【age->25】- 【class java.lang.String->class java.lang.Integer】
【sex->1】- 【class java.lang.String->class java.lang.Integer】
【height->55】- 【class java.lang.String->class java.lang.Integer】
【birth->1636788723062】-【class java.lang.String->class java.lang.Long】
【valid->true】- 【class java.lang.String->class java.lang.Boolean】
*/
map.forEach((k,v)->{
System.out.println("【"+k +"->"+ v + "】-【" + k.getClass() + "->" + v.getClass() +"】");
});
}
@Test
public void test_14() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
String dateStr = objectMapper.writeValueAsString(new Date());
System.out.println(dateStr); // 输出:1636789190919
Date date = objectMapper.readValue(dateStr, Date.class);
System.out.println(date); // 输出:Sat Nov 13 15:39:50 CST 2021
}
@Test
public void testSaveObject() {
// 创建user对象
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
System.out.println(now.hashCode());
// 使用ObjectOutputStream包装ByteArrayOutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(baos);
} catch (IOException e) {
e.printStackTrace();
}
try {
// 使用ObjectOutputStream写对象
oos.writeObject(now);
oos.flush();
} catch (IOException e) {
e.printStackTrace();
}
byte[] userBytes = baos.toByteArray();
// 使用ObjectInputStream包装ByteArrayInputStream
ByteArrayInputStream bais = new ByteArrayInputStream(userBytes);
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(bais);
} catch (IOException e) {
e.printStackTrace();
}
try {
// 使用ObjectInputStream读取对象
Object o = ois.readObject();
System.out.println(o.getClass());
System.out.println(o);
System.out.println(o.hashCode());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 测试反序列化数组json
@Test
public void testDeserializeArray() {
Person p1 = new Person("zzhua",25);
Person p2 = new Person("zj",24);
ArrayList<Person> list = new ArrayList<>();
list.add(p1);
list.add(p2);
ObjectMapper mapper = new ObjectMapper();
String personListJson = mapper.writeValueAsString(list);
System.out.println(personListJson); // [{"name":"zzhua","age":25},{"name":"zj","age":24}]
TypeFactory typeFactory = mapper.getTypeFactory();
JavaType javaType = typeFactory.constructParametricType(List.class, Person.class);
List<Person> personList = mapper.readValue(personListJson, javaType);
System.out.println(personList); // [PropertyUtil.Person(name=zzhua, age=25), PropertyUtil.Person(name=zj, age=24)]
List<Person> personList2 = mapper.readValue(personListJson, new TypeReference<List<Person>>(){});
System.out.println(personList2); //[PropertyUtil.Person(name=zzhua, age=25), PropertyUtil.Person(name=zj, age=24)]
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Person {
private String name;
private Integer age;
}
}
来源:https://juejin.cn/post/6844904113017192456
1、使用ObjectMapper,将json字符串转成对象:
String str = "{\"id\":1,\"name\":\"haha\",\"elements\":[{\"age\":1,\"elName\":\"zll\"},{\"age\":2,\"elName\":\"zll1\"}]}";
ObjectMapper objectMapper = new ObjectMapper();
TestBean testBean = objectMapper.readValue(str, TestBean.class);
System.out.println(testBean.toString());
// 输出:TestBean(id=1, name=haha, elements=[Element(age=1, elName=zll), Element(age=2, elName=zll1)])
2、使用ObjectMapper,读取json某些字段值
String str = "{\"id\":1,\"name\":\"haha\",\"elements\":[{\"age\":1,\"elName\":\"zll\"},{\"age\":2,\"elName\":\"zll1\"}]}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(str);
//获取name字段值
JsonNode name = jsonNode.get("name");
String s = name.asText();
System.out.println(s);
//获取elements字段下数组第二个对象的age
JsonNode elements = jsonNode.get("elements");
JsonNode object2 = elements.get(1);//从0开始哦
JsonNode age = object2.get("age");
int i = age.asInt();
System.out.println(i);
// 输出:haha 2
Element element = new Element();
element.setAge(1);
element.setElName("zll");
ObjectMapper objectMapper = new ObjectMapper();
String elementStr = objectMapper.writeValueAsString(element);
System.out.println(elementStr);
// 输出:{"age":1,"elName":"zll"}
其他常用序列化方法:
writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中
writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。
teValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组
writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。
可以根据自己的需要创建相应结构的json
ByteArrayOutputStream bout = new ByteArrayOutputStream();
//JsonFactory jsonFactory = new JsonFactory();
//创建jsonfactory 2种方法
ObjectMapper objectMapper = new ObjectMapper();
JsonFactory jsonFactory = objectMapper.getFactory();
JsonGenerator generator = jsonFactory.createGenerator(bout);
//创建自己需要的json
//创建对象获取数组要写开始和结束
generator.writeStartObject();
//创建一个字段 第一个参数key 第二个参数value
generator.writeStringField("name","value");
generator.writeNumberField("numberName",1);
//或者直接创建object
generator.writeObjectField("ObjectName","ObjectValue");
//创建数组
generator.writeArrayFieldStart("arrayName");
//里面可以是对象、数组、字符串、数字
generator.writeString("element1");
generator.writeNumber(1);
generator.writeNumber(1);
generator.writeEndArray();
generator.writeEndObject();
generator.flush();
generator.close();
String s = bout.toString();
System.out.println(s);
// 输出:{"name":"value","numberName":1,"ObjectName":"ObjectValue","arrayName":["element1",1,1]}
ObjectMapper objectMapper = new ObjectMapper();
//序列化的时候序列对象的所有属性
objectMapper.setSerializationInclusion(Include.ALWAYS);
//反序列化的时候如果多了其他属性,不抛出异常
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//如果是空对象的时候,不抛异常
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
//属性为null的转换
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
@JsonIgnoreProperties(ignoreUnknown = true):
将这个注解加载类上,不存在的字段将被忽略。
@JsonIgnoreProperties({ “password”, “secretKey” }):
指定忽略字段
@JsonIgnore:
标在注解上,将忽略此字段
@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm:ss”):
标在时间自端上序列化是使用制定规则格式化(默认转化成时间戳)
@JsonInclude(参数)
JsonInclude.Include.NON_EMPTY:属性为空或者null都不参与序列化
JsonInclude.Include.NON_NULL:属性为null不参与序列化
@JsonProperty("firstName")
标在字段上,指定序列化后的字段名
@JsonDeserialize(using= T extends JsonDeserializer.class)和@JsonSerialize(using= T extends JsonSerializer.class)
自定义某些类型字段的序列化与反序列化规则
还有很多的注解在:
com.fasterxml.jackson.annotation包下:
@JacksonAnnotation
@JacksonAnnotationsInside
@JacksonAnnotationValue
@JacksonInject
@JsonAlias
@JsonAnyGetter
@JsonAnySetter
@JsonAutoDetect
@JsonBackReference
@JsonClassDescription
@JsonCreator
@JsonEnumDefaultValue
@JsonFilter
@JsonFormat
@JsonGetter
@JsonIdentityInfo
@JsonIdentityReference
@JsonIgnore
@JsonIgnoreProperties
@JsonIgnoreType
@JsonInclude
@JsonManagedReference
@JsonMerge
@JsonProperty
@JsonPropertyDescription
@JsonPropertyOrder
@JsonRawValue
@JsonRootName
@JsonSetter
@JsonSubTypes
@JsonTypeId
@JsonTypeInfo
@JsonTypeName
@JsonUnwrapped
@JsonValue
@JsonView
在com.fasterxml.jackson.databind.annotation包下:
@JacksonStdImpl
@JsonAppend
@JsonDeserialize
@JsonNaming
@JsonPOJOBuilder
@JsonSerialize
@JsonTypeIdResolver
@JsonTypeResolver
@JsonValueInstantiator