jacson的使用
参考链接:
https://blog.csdn.net/qidasheng2012/article/details/105771052
https://www.jianshu.com/p/1917b2a28fc5
https://blog.csdn.net/weixin_44747933/article/details/108301626
参考代码:
实体类:
@Data
public class Person {
// 正常case
private String name;
// 空对象case
private Integer age;
// 日期转换case
// 中国区时间节点
private Date date;
// 默认值case
private int height;
}
@Test
public void test1() throws IOException {
ObjectMapper mapper = new ObjectMapper();
// 造数据
Person person = new Person();
person.setName("Tom");
person.setAge(40);
person.setDate(new Date());
System.out.println("序列化");
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);
System.out.println(jsonString);
System.out.println("反序列化");
Person deserializedPerson = mapper.readValue(jsonString, Person.class);
System.out.println(deserializedPerson);
这里是使用默认的方式来进行操作。
控制台打印输出信息:
/**
* 序列化
* {
* "name" : "Tom",
* "age" : 40,
* "date" : 1642758224562,
* "height" : 0
* }
* 反序列化
* Person(name=Tom, age=40, date=Fri Jan 21 17:43:44 CST 2022, height=0)
*/
可以看到对应的date的类型是一个Long类型的数字,那么这种使用方式看起来无法描述清楚,所以我们可以来对ObjectMapper来进行设置
具体使用如下所示:
@Test
public void test1() throws IOException {
ObjectMapper mapper = new ObjectMapper();
//在反序列化时忽略在json中存在但 Java 对象不存在的属性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//在序列化时日期格式默认为 yyyy-MM-dd'T'HH:mm:ss.SSSZ
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//在序列化时自定义时间日期格式
// mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
//在序列化时忽略值为 null 的属性
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 在序列化时忽略值为默认值的属性
mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_DEFAULT);
// 造数据
Person person = new Person();
person.setName("Tom");
person.setAge(40);
person.setDate(new Date());
System.out.println("序列化");
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);
System.out.println(jsonString);
System.out.println("反序列化");
Person deserializedPerson = mapper.readValue(jsonString, Person.class);
System.out.println(deserializedPerson);
控制台的输出消息如下:
/**
* 在对其进行配置之后,可以看到打印之后的json格式数据如下所示:
* 序列化
* {
* "name" : "Tom",
* "age" : 40,
* "date" : "2022-01-21 17:47:08"
* }
* 反序列化
* Person(name=Tom, age=40, date=Fri Jan 21 17:47:08 CST 2022, height=0)
*/
这是对ObjectMapper的设置,在进行序列化和反序列化的时候进行的操作方式。
demo2
@Test
public void test3() throws IOException {
ObjectMapper mapper = new ObjectMapper();
// 造数据
Map<String, Object> map = new HashMap<>();
map.put("user_name", "Tom");
map.put("date", "2020-07-26 19:28:44");
map.put("age", 100);
map.put("demoKey", "demoValue");
String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
System.out.println("转换成json数据"+jsonString);
System.out.println("==========================");
System.out.println("反序列化");
User user = mapper.readValue(jsonString, User.class);
System.out.println(user);
System.out.println("序列化");
jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user);
System.out.println(jsonString);
}
在这里,自定义一个工具类来进行使用:
public final class JsonUtil {
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final Map<Class<?>, ObjectReader> readerMap = new ConcurrentHashMap();
private static final Map<Class<?>, ObjectWriter> writerMap = new ConcurrentHashMap();
private static final JsonFactory jsonFactory = new JsonFactory();
/**
* 将key进行缓存,每次从这里来面进行获取
*/
private static final Map<Class<?>, JavaType> collectionElementMap = new ConcurrentHashMap();
static {
// 最终会设计到TypeFactory中来
// 序列化的时候不将为null的属性进行序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 序列化的时候,将bigcemal来进行序列化 // 0.00000005---->0.00000005,而不是5E-8
objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
// 序列化的时候将date序列化成timestamp 将这种类型设置成43214324132143,这种Long类型的数字格式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
// 持久化的时候进行的操作设置
// 设置了spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS = false,但Jackson序列化器仍然为DateTime值生成[1942,4,2]而不是“1942-04-02”
objectMapper.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);
}
public JsonUtil() {
}
/**
* 获取得到List中得泛型的类 没有提供map类型的数据操作,但是也不需要来对其进行提供对应的操作方式
*
* @param targetClass 目标类型
* @return
*/
private static JavaType getJavaType(Class<?> targetClass) {
Object javaType;
if ((javaType = (JavaType) collectionElementMap.get(targetClass)) == null) {
synchronized (targetClass) {
if ((javaType = (JavaType) collectionElementMap.get(targetClass)) == null) {
javaType = objectMapper.getTypeFactory().constructCollectionType(List.class, targetClass);
collectionElementMap.put(targetClass, (JavaType) javaType);
}
}
}
return (JavaType) javaType;
}
/**
* 将json字符串转换成指定的类型的list集合数据
*
* @param jsonString json
* @param targetClass 集合中的元素类型
* @param <T> 泛型
* @return
* @throws Exception
*/
public static <T> List<T> parseJsonStringToListObject(String jsonString, Class<T> targetClass) throws Exception {
ObjectReader reader = getObjectReader(List.class);
JavaType javaType = getJavaType(targetClass);
return (List) reader.readValue(jsonFactory.createParser(jsonString), javaType);
}
/**
* 将list集合对象转换成集合对象
*
* @param objectList
* @param targetClass
* @param <T>
* @return
* @throws Exception
*/
public static <T> List parseObjectListType(List<?> objectList, Class<T> targetClass) throws Exception {
List<T> result = new ArrayList(objectList.size());
Iterator var3 = objectList.iterator();
while (var3.hasNext()) {
Object object = var3.next();
result.add(parseObjectToObject(object, targetClass));
}
return result;
}
/**
* 将对象转换成对象
* 防止深拷贝
*/
public static <T> T parseObjectToObject(Object object, Class<T> targetClass) throws Exception {
return parseJsonStringToObject(parseObjectToJsonString(object), targetClass);
}
/**
* 将json转换成对象
* 反序列化
* @param jsonString
* @param targetClass
* @param <T>
* @return
* @throws Exception
*/
public static <T> T parseJsonStringToObject(String jsonString, Class<T> targetClass) throws Exception {
ObjectReader reader = getObjectReader(targetClass);
return reader.readValue(jsonString);
}
/**
* 将对象转换成json
*
* @param object 需要进行转换的对象
* @return
* @throws Exception
*/
public static String parseObjectToJsonString(Object object) throws Exception {
ObjectWriter writer = getObjectWriter(object.getClass());
return writer.writeValueAsString(object);
}
/**
* 获取得到targetClass类型的读取解析器
* @param targetClass 目标类型的解析器来进行解析
* @return
*/
private static ObjectReader getObjectReader(Class<?> targetClass) {
ObjectReader reader;
if ((reader = readerMap.get(targetClass)) == null) {
synchronized (targetClass) {
if ((reader = readerMap.get(targetClass)) == null) {
// 获取得到这种类型的解析器
reader = objectMapper.readerFor(targetClass);
readerMap.put(targetClass, reader);
}
}
}
return reader;
}
/**
* 获取得到targetClass类型的写出解析器
* @param targetClass
* @return
*/
private static ObjectWriter getObjectWriter(Class<?> targetClass) {
ObjectWriter writer;
if ((writer = writerMap.get(targetClass)) == null) {
synchronized (targetClass) {
if ((writer = writerMap.get(targetClass)) == null) {
writer = objectMapper.writerFor(targetClass);
writerMap.put(targetClass, writer);
}
}
}
return writer;
}
}
从理论中来,到实践中去,最终回归理论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?