Object and json conversion in four ways json-lib, Gson, FastJson, Jackson

1. json-lib

json-lib is the most widely used json parsing tool at the beginning. The disadvantage of json-lib is that it depends on many third-party packages, including
commons-beanutils.jar, commons-collections-3.2.jar, commons-lang- 2.6.jar, commons-logging-1.1.1.jar, ezmorph-1.0.6.jar,
for the conversion of complex types, json-lib has defects in converting json to beans, for example, there will be another class in one class List or map collection, json-lib conversion from json to bean will have problems.
json-lib cannot meet the needs of the Internet today in terms of function and performance.

2. Google's Gson

1 Introduction

(1) Gson is currently the most fully functional Json parsing artifact. Gson was originally developed by Google in response to Google's internal needs, but it has been used by many companies or users since the first version was released publicly in May 2008. .
The application of Gson mainly consists of two conversion functions, toJson and fromJson. It has no dependencies, does not require additional jars, and can run directly on the JDK.
Before using this object conversion, you need to create the object type and its members to successfully convert the JSON string into the corresponding object.
As long as there are get and set methods in the class, Gson can completely convert complex types of json to bean or bean to json, and is an artifact of JSON parsing.
Gson is impeccable in terms of functions, but its performance is somewhat different than FastJson.
(2) By default, the key corresponding to the null value is not serialized. The specific cases are as follows:

public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
    
    
		AutoPartsSearchRequest request = new AutoPartsSearchRequest();
		request.setKeywords("123");
		request.setSortingField("234242");
		Gson g = new GsonBuilder().create();
		String str = g.toJson(request);
		System.out.println(str);
		//输出结果:{"sortingField":"234242","keywords":"123"}
	}

If you want to serialize the key corresponding to the null value, you only need to change the above creation code into the following code:

Gson g = new GsonBuilder().serializeNulls().create();

If you want to convert null to an empty string "", you need to handle it manually

(3) Main class introduction
Gson class: the most basic tool class for parsing json
JsonParser class: a parser to parse JSON to the parsing tree of JsonElements
JsonElement class: a JSON element represented by a class
JsonObject class: JSON object type
JsonArray class: JsonObject array
TypeToken class: used to create type, such as generic List<?>

(4) bean conversion json

Gson gson = new Gson();
String json = gson.toJson(obj);
//obj是对象

(5) json conversion bean

Gson gson = new Gson();
String json = "{\"id\":\"2\",\"name\":\"Json技术\"}";
Book book = gson.fromJson(json, Book.class);

(6) json converts complex beans, such as List and Set
to convert json into complex types of beans, and TypeToken is required

Gson gson = new Gson();
String json = "[{\"id\":\"1\",\"name\":\"Json技术\"},{\"id\":\"2\",\"name\":\"java技术\"}]";
//将json转换成List
List list = gson.fromJson(json,new TypeToken<LIST>() {
    
    }.getType());
//将json转换成Set
Set set = gson.fromJson(json,new TypeToken<SET>() {
    
    }.getType());

(7) Directly manipulate json and some json tools through json objects
a) Format Json

String json = "[{\"id\":\"1\",\"name\":\"Json技术\"},{\"id\":\"2\",\"name\":\"java技术\"}]";
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(json);
json = gson.toJson(je);

b) Determine whether the string is json, and judge whether it is json by capturing the exception

String json = "[{\"id\":\"1\",\"name\":\"Json技术\"},{\"id\":\"2\",\"name\":\"java技术\"}]";
boolean jsonFlag;
try {
    
    
new JsonParser().parse(str).getAsJsonObject();
jsonFlag = true;
} catch (Exception e) {
    
    
jsonFlag = false;
}

c) Get attributes from the json string

String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
String propertyName = 'id';
String propertyValue = "";
try {
    
    
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
propertyValue = jsonObj.get(propertyName).toString();
} catch (Exception e) {
    
    
propertyValue = null;
}

d) Remove an attribute in json

String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
String propertyName = 'id';
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.remove(propertyName);
json = jsonObj.toString();

e) Add attributes to json

String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
String propertyName = 'desc';
Object propertyValue = "json各种技术的调研";
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.addProperty(propertyName, new Gson().toJson(propertyValue));
json = jsonObj.toString();

f) Modify the attributes in json

String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
String propertyName = 'name';
Object propertyValue = "json各种技术的调研";
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
jsonObj.remove(propertyName);
jsonObj.addProperty(propertyName, new Gson().toJson(propertyValue));
json = jsonObj.toString();

g) Determine whether there are attributes in json

String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
String propertyName = 'name';
boolean isContains = false ;
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
JsonObject jsonObj = element.getAsJsonObject();
isContains = jsonObj.has(propertyName);

h) Processing of date format in json

GsonBuilder builder = new GsonBuilder();
builder.setDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Gson gson = builder.create();

Then use the gson object to process json. If an object of the Date class appears, it will be processed according to the set format

i) Escaping for Html in json

Gson gson = new Gson();

This kind of object escapes Html by default, if you don't want to escape, use the following method

GsonBuilder builder = new GsonBuilder();
builder.disableHtmlEscaping();
Gson gson = builder.create();

2. Configuration steps

1. MAVEN dependency import

 <!--gson-->
 <dependency>
     <groupId>com.google.code.gson</groupId>
     <artifactId>gson</artifactId>
     <version>2.8.0</version>
 </dependency>

2. gsonUtil tool class

package com.dechnic.common.util;

import com.dechnic.common.anno.gson.Exclude;
import com.dechnic.common.po.ObjectTypeAdapter;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.reflect.TypeToken;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @description:
 * @author:houqd
 * @time: 2022/6/27 17:31
 */

public class GsonUtll {
    
    
    private static Gson gson;
    static {
    
    
        ExclusionStrategy strategy = new ExclusionStrategy() {
    
    
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
    
    
                return f.getAnnotation(Exclude.class) !=null;
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
    
    
                return false;
            }
        };
        gson = new GsonBuilder().disableHtmlEscaping().setExclusionStrategies(strategy).registerTypeAdapter(new TypeToken<Map<String,Object>>(){
    
    }.getType(),new ObjectTypeAdapter()).serializeNulls().create();
    }
    public static Map<String,Object> jsonStr2Map(String jsonStr){
    
    
        return gson.fromJson(jsonStr, new TypeToken<Map<String, Object>>() {
    
    
        }.getType());
    }
    public static List<Map<String,Object>> jsonStr2ListMap(String jsonStr){
    
    
        return gson.fromJson(jsonStr, new TypeToken<List<Map<String, Object>>>() {
    
    
        }.getType());
    }
    public static String toJSON(Object object){
    
    
        return gson.toJson(object);
    }
    public static <T> List<T> json2ListBean(String result, Class<T> t){
    
    
        List list = gson.fromJson(result, new TypeToken<List>() {
    
    
        }.getType());
        List list2 = new ArrayList();
        for (Object o : list) {
    
    
            list2.add(json2Bean(toJSON(o),t));
        }
        return list2;
    }
    public static <T> T json2Bean(String result,Class<T>t){
    
    
        return gson.fromJson(result, t);
    }

}

3. Exclude the familiar annotation class Exclude that does not want to be serialized

package com.dechnic.common.anno.gson;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Exclude {
    
    
}

3. Alibaba's FastJson

1 Introduction

(1) Fastjson is a high-performance JSON processor written in Java, developed by Alibaba.
No dependencies, no need for extra jars, and can run directly on the JDK.
FastJson will have some problems in converting Json of complex types of beans. There may be reference types, which will cause errors in Json conversion, and references need to be formulated.
FastJson uses an original algorithm to increase the speed of parse to the extreme, surpassing all json libraries.
(2) When fastJson converts a java object to json, it does not serialize the key corresponding to the null value by default, that is to say, when the properties in the object are empty, when converting to json, those that are null are not serialized Value attributes
But what if you want to serialize the key corresponding to null?
Then take a closer look at the input parameters when fastjson converts java objects to json: that is, this method:

JSONObject.toJSONString(Object object, SerializerFeature… features)

Fastjson's SerializerFeature serialization attribute:

QuoteFieldNames———-输出key时是否使用双引号,默认为true 
WriteMapNullValue——–是否输出值为null的字段,默认为false 
WriteNullNumberAsZero-数值字段如果为null,输出为0,而非null 
WriteNullListAsEmpty—–List字段如果为null,输出为[],而非null 
WriteNullStringAsEmpty—字符类型字段如果为null,输出为”“,而非null 
WriteNullBooleanAsFalseBoolean字段如果为null,输出为false,而非null

Combined with the above, SerializerFeature... features is an array, then we can pass in the parameters we want, such as serializing null, the case is as follows:

public static void main(String[] args) {
    
    
		AutoPartsSearchRequest request = new AutoPartsSearchRequest();
		request.setKeywords("123");
		request.setSortingField("234242");
		String str = JSONObject.toJSONString(request, SerializerFeature.WriteMapNullValue);
		System.out.println(str);
	}

(3) bean conversion json converts objects into formatted json

JSON.toJSONString(obj,true);

(4) Convert the object to unformatted json

JSON.toJSONString(obj,false);

obj design object
For the conversion of complex types, for repeated references, the referenced characters appear in the json string after being converted into a json string, such as ref":"[0].books[1]

Student stu = new Student();
Set books= new HashSet();
Book book = new Book();
books.add(book);
stu.setBooks(books);
List list = new ArrayList();
for(int i=0;i<5;i++)
list.add(stu);
String json = JSON.toJSONString(list,true);

(5) json conversion bean

String json = "{\"id\":\"2\",\"name\":\"Json技术\"}";
Book book = JSON.parseObject(json, Book.class);

(6) json converts complex beans, such as List, Map

String json = "[{\"id\":\"1\",\"name\":\"Json技术\"},{\"id\":\"2\",\"name\":\"java技术\"}]";
//将json转换成List
List list = JSON.parseObject(json,new TypeReference<ARRAYLIST>(){
    
    });
//将json转换成Set
Set set = JSON.parseObject(json,new TypeReference<HASHSET>(){
    
    });

(7) Manipulate json directly through json object
a) Obtain attributes from json string

String propertyName = 'id';
String propertyValue = "";
String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
JSONObject obj = JSON.parseObject(json);
propertyValue = obj.get(propertyName));

b) Remove an attribute in json

String propertyName = 'id';
String propertyValue = "";
String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
JSONObject obj = JSON.parseObject(json);
Set set = obj.keySet();
propertyValue = set.remove(propertyName);
json = obj.toString();

c) Add attributes to json

String propertyName = 'desc';
Object propertyValue = "json的玩意儿";
String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
JSONObject obj = JSON.parseObject(json);
obj.put(propertyName, JSON.toJSONString(propertyValue));
json = obj.toString();

d) modify the attributes in json

String propertyName = 'name';
Object propertyValue = "json的玩意儿";
String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
JSONObject obj = JSON.parseObject(json);
Set set = obj.keySet();
if(set.contains(propertyName))
obj.put(propertyName, JSON.toJSONString(propertyValue));
json = obj.toString();

e) Determine whether there are attributes in json

String propertyName = 'name';
boolean isContain = false;
String json = "{\"id\":\"1\",\"name\":\"Json技术\"}";
JSONObject obj = JSON.parseObject(json);
Set set = obj.keySet();
isContain = set.contains(propertyName);

f) Processing of date format in json

Object obj = new Date();
String json = JSON.toJSONStringWithDateFormat(obj, "yyyy-MM-dd HH:mm:ss.SSS");

Simple usage scenario:

2. Configuration steps

1. Introduce maven

<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.83</version>
 </dependency>

2. Configure CustomFastjsonConfig

package com.example.demo2.config;/**
 * @className: WebMvcConfig
 * @author: houqd
 * @date: 2022/11/4
 **/

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * @description:
 * @author:houqd
 * @time: 2022/11/4 13:55
 */
@Configuration
public class CustomFastjsonConfig {
    
    
    @Bean
    public FastJsonHttpMessageConverter fastjsonHttpMessageConverters() {
    
    
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setCharset(Charset.forName("UTF-8"));
        fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
        //设置序列化特征
        SerializerFeature[] serializerFeatures = new SerializerFeature[]{
    
    
                //WriteNullStringAsEmpty: 如果字符串等于 null,那么会被序列化成空字符串 ""
                SerializerFeature.WriteNonStringKeyAsString,
                // WriteNullNumberAsZero: 如果数字等于 null,那么会被序列化成 0
                SerializerFeature.WriteNullNumberAsZero,
                // WriteNullBooleanAsFalse: 如果布尔类型等于 null,那么会被序列化成 false
                SerializerFeature.WriteNullBooleanAsFalse,
                // PrettyFormat: 美化JSON
                SerializerFeature.PrettyFormat
        };
        fastJsonConfig.setSerializerFeatures(serializerFeatures);

        // 配置添加到消息转换器里面
        converter.setFastJsonConfig(fastJsonConfig);
        converter.setDefaultCharset(Charset.forName("UTF-8"));
        // 设置响应JSON格式数据
        List<MediaType> mediaTypeList = new ArrayList<>();
        mediaTypeList.add(MediaType.APPLICATION_JSON);
        // 设置消息转换器支持的格式
        converter.setSupportedMediaTypes(mediaTypeList);
        return converter;
    }

}

3. Test

User.java

package com.example.demo2.entity;/**
 * @className: User
 * @author: houqd
 * @date: 2022/11/4
 **/

import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 *@description:
 *@author:houqd
 *@time: 2022/11/4 14:12
 *
 */
@Data
public class User implements Serializable {
    
    
    private String username;
    private Date createTime;
    private Boolean enabled;
    private Integer num;

}

TestController.java

package com.example.demo2.controller;/**
 * @className: TestController
 * @author: houqd
 * @date: 2022/11/4
 **/

import com.example.demo2.entity.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *@description:
 *@author:houqd
 *@time: 2022/11/4 14:13
 *
 */
@RestController
@RequestMapping("/api")
public class TestController {
    
    
    @GetMapping("/json")
    public List<User> json() {
    
    
        List<User> list = this.getUserList();
        return list;
    }
    // 模拟数据
    private List<User> getUserList() {
    
    
        List<User> list = new ArrayList<>();
        for (int i = 0; i < 3; i++) {
    
    
            User user = new User();
            if (i != 1) {
    
    
                user.setUsername("test-00" + i);
                user.setCreateTime(new Date());
                user.setEnabled(true);
                user.setNum(520);
            }
            list.add(user);
        }
        return list;
    }

}

Test Results:
insert image description here

Note: fastJson failed to quote the date format after version 2.0.17, and returned to version 1.2.83 to be normal.

4. Open source Jackson

Introduction:

(1) Compared with the json-lib framework, Jackson relies on fewer jar packages, is easy to use and has relatively high performance.
Moreover, the Jackson community is relatively active and the update speed is relatively fast.
Jackson will have problems converting complex types of json beans, and some collections Map and List conversion problems.
Jackson converts Json for complex types of beans, and the converted json format is not the standard Json format

(2) jackson serializes the key corresponding to null by default, that is to say, no matter whether your object attribute has a value or not, it will be serialized when converting json

public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
    
    
		AutoPartsSearchRequest request = new AutoPartsSearchRequest();
		request.setKeywords("123");
		request.setSortingField("234242");
		ObjectMapper mapper = new ObjectMapper();
		String str = mapper.writeValueAsString(request); 
		System.out.println(str);
		//输出结果(此处就不格式化了):{"sortingField":"234242","partsClassifyId":null,"partsSubClassifyId":null,"sortingDirection":null:......
	}

2. Similarly, it is also possible to not serialize null, as follows:

1.实体上
 
@JsonInclude(Include.NON_NULL) 
 
//将该标记放在属性上,如果该属性为NULL则不参与序列化 
//如果放在类上边,那对这个类的全部属性起作用 
//Include.Include.ALWAYS 默认 
//Include.NON_DEFAULT 属性为默认值不序列化 
//Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化 
//Include.NON_NULL 属性为NULL 不序列化 
 
 
2.代码上
ObjectMapper mapper = new ObjectMapper();
 
mapper.setSerializationInclusion(Include.NON_NULL);  
 
//通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化 
//Include.Include.ALWAYS 默认 
//Include.NON_DEFAULT 属性为默认值不序列化 
//Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化 
//Include.NON_NULL 属性为NULL 不序列化 

Note: It only works for VO, Map List does not work, and jackson can also filter out the attributes you set, you can study the source code yourself for details

(3) Springboot uses Jackson and @RestController annotations by default, and HttpMessageConverter will be used to convert the data and write it into the body data area of ​​Response

Jackson configuration

import maven

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.10.0</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.10.0</version>
        </dependency>

1. Through the corresponding configuration of jackson in application.yml to achieve

    spring:
    jackson:
      # 设置属性命名策略,对应jackson下PropertyNamingStrategy中的常量值,SNAKE_CASE-返回的json驼峰式转下划线,json body下划线传到后端自动转驼峰式
      property-naming-strategy: SNAKE_CASE
      # 全局设置@JsonFormat的格式pattern
      date-format: yyyy-MM-dd HH:mm:ss
      # 当地时区
      locale: zh
      # 设置全局时区
      time-zone: GMT+8
      # 常用,全局设置pojo或被@JsonInclude注解的属性的序列化方式
      default-property-inclusion: NON_NULL #不为空的属性才会序列化,具体属性可看JsonInclude.Include
      # 常规默认,枚举类SerializationFeature中的枚举属性为key,值为boolean设置jackson序列化特性,具体key请看SerializationFeature源码
      serialization:
        WRITE_DATES_AS_TIMESTAMPS: true # 返回的java.util.date转换成timestamp
        FAIL_ON_EMPTY_BEANS: true # 对象为空时是否报错,默认true
      # 枚举类DeserializationFeature中的枚举属性为key,值为boolean设置jackson反序列化特性,具体key请看DeserializationFeature源码
      deserialization:
        # 常用,json中含pojo不存在属性时是否失败报错,默认true
        FAIL_ON_UNKNOWN_PROPERTIES: false
      # 枚举类MapperFeature中的枚举属性为key,值为boolean设置jackson ObjectMapper特性
      # ObjectMapper在jackson中负责json的读写、json与pojo的互转、json tree的互转,具体特性请看MapperFeature,常规默认即可
      mapper:
        # 使用getter取代setter探测属性,如类中含getName()但不包含name属性与setName(),传输的vo json格式模板中依旧含name属性
        USE_GETTERS_AS_SETTERS: true #默认false
      # 枚举类JsonParser.Feature枚举类中的枚举属性为key,值为boolean设置jackson JsonParser特性
      # JsonParser在jackson中负责json内容的读取,具体特性请看JsonParser.Feature,一般无需设置默认即可
      parser:
        ALLOW_SINGLE_QUOTES: true # 是否允许出现单引号,默认false
      # 枚举类JsonGenerator.Feature枚举类中的枚举属性为key,值为boolean设置jackson JsonGenerator特性,一般无需设置默认即可
      # JsonGenerator在jackson中负责编写json内容,具体特性请看JsonGenerator.Feature




2. Implement code configuration through ObjectMapper

/**
 * 全局序列化配置类
 */
@Configuration
public class JsonConfig {
    
    
 
    /**
     * 创建Jackson对象映射器
     *
     * @param builder Jackson对象映射器构建器
     * @return ObjectMapper
     */
    @Bean
    public ObjectMapper getJacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
    
    
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        //序列换成json时,将所有的long变成string.因为js中得数字类型不能包含所有的java long值,超过16位后会出现精度丢失
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        //反序列化的时候如果多了其他属性,不抛出异常
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //日期格式处理
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        return objectMapper;
    }
}

Method 2. Rewrite the configureMessageConverters method

/**
 * 全局序列化配置类
 */
@Configuration
@EnableWebMvc
public class JsonConfig implements WebMvcConfigurer {
    
    
 
    /**
     * 全局序列化方式
     *
     * @param converters
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    
    
        //Jackson的全局序列化方式
        configureJacksonHttpMessageConverter(converters);
    }
 
    /**
     * Jackson的全局序列化方式
     *
     * @param converters
     */
    private void configureJacksonHttpMessageConverter(List<HttpMessageConverter<?>> converters) {
    
    
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        //序列换成json时,将所有的long变成string.因为js中得数字类型不能包含所有的java long值,超过16位后会出现精度丢失
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        //反序列化的时候如果多了其他属性,不抛出异常
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //日期格式处理
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        converter.setObjectMapper(objectMapper);
        converters.add(converter);
        converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
    }
}

ObjectMapper common tool class

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Jackson 工具类
 * <p>Title: MapperUtils</p>
 * <p>Description: </p>
 *
 */
public class MapperUtils {
    
    
    private final static ObjectMapper objectMapper = new ObjectMapper();

    public static ObjectMapper getInstance() {
    
    
        return objectMapper;
    }

    /**
     * 转换为 JSON 字符串
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static String obj2json(Object obj) throws Exception {
    
    
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        return mapper.writeValueAsString(obj);
    }

    /**
     * 转换为 JSON 字符串,忽略空值
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static String obj2jsonIgnoreNull(Object obj) throws Exception {
    
    
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.writeValueAsString(obj);
    }

    /**
     * 转换为 JavaBean
     *
     * @param jsonString
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> T json2pojo(String jsonString, Class<T> clazz) throws Exception {
    
    
        objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        return objectMapper.readValue(jsonString, clazz);
    }

    /**
     * 字符串转换为 Map<String, Object>
     *
     * @param jsonString
     * @return
     * @throws Exception
     */
    public static <T> Map<String, Object> json2map(String jsonString) throws Exception {
    
    
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.readValue(jsonString, Map.class);
    }

    /**
     * 字符串转换为 Map<String, T>
     */
    public static <T> Map<String, T> json2map(String jsonString, Class<T> clazz) throws Exception {
    
    
        Map<String, Map<String, Object>> map = objectMapper.readValue(jsonString, new TypeReference<Map<String, T>>() {
    
    
        });
        Map<String, T> result = new HashMap<String, T>();
        for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
    
    
            result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));
        }
        return result;
    }

    /**
     * 深度转换 JSON 成 Map
     *
     * @param json
     * @return
     */
    public static Map<String, Object> json2mapDeeply(String json) throws Exception {
    
    
        return json2MapRecursion(json, objectMapper);
    }

    /**
     * 把 JSON 解析成 List,如果 List 内部的元素存在 jsonString,继续解析
     *
     * @param json
     * @param mapper 解析工具
     * @return
     * @throws Exception
     */
    private static List<Object> json2ListRecursion(String json, ObjectMapper mapper) throws Exception {
    
    
        if (json == null) {
    
    
            return null;
        }

        List<Object> list = mapper.readValue(json, List.class);

        for (Object obj : list) {
    
    
            if (obj != null && obj instanceof String) {
    
    
                String str = (String) obj;
                if (str.startsWith("[")) {
    
    
                    obj = json2ListRecursion(str, mapper);
                } else if (obj.toString().startsWith("{")) {
    
    
                    obj = json2MapRecursion(str, mapper);
                }
            }
        }

        return list;
    }

    /**
     * 把 JSON 解析成 Map,如果 Map 内部的 Value 存在 jsonString,继续解析
     *
     * @param json
     * @param mapper
     * @return
     * @throws Exception
     */
    private static Map<String, Object> json2MapRecursion(String json, ObjectMapper mapper) throws Exception {
    
    
        if (json == null) {
    
    
            return null;
        }

        Map<String, Object> map = mapper.readValue(json, Map.class);

        for (Map.Entry<String, Object> entry : map.entrySet()) {
    
    
            Object obj = entry.getValue();
            if (obj != null && obj instanceof String) {
    
    
                String str = ((String) obj);

                if (str.startsWith("[")) {
    
    
                    List<?> list = json2ListRecursion(str, mapper);
                    map.put(entry.getKey(), list);
                } else if (str.startsWith("{")) {
    
    
                    Map<String, Object> mapRecursion = json2MapRecursion(str, mapper);
                    map.put(entry.getKey(), mapRecursion);
                }
            }
        }

        return map;
    }

    /**
     * 将 JSON 数组转换为集合
     *
     * @param jsonArrayStr
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception {
    
    
        JavaType javaType = getCollectionType(ArrayList.class, clazz);
        List<T> list = (List<T>) objectMapper.readValue(jsonArrayStr, javaType);
        return list;
    }


    /**
     * 获取泛型的 Collection Type
     *
     * @param collectionClass 泛型的Collection
     * @param elementClasses  元素类
     * @return JavaType Java类型
     * @since 1.0
     */
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
    
    
        return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    /**
     * 将 Map 转换为 JavaBean
     *
     * @param map
     * @param clazz
     * @return
     */
    public static <T> T map2pojo(Map map, Class<T> clazz) {
    
    
        return objectMapper.convertValue(map, clazz);
    }

    /**
     * 将 Map 转换为 JSON
     *
     * @param map
     * @return
     */
    public static String mapToJson(Map map) {
    
    
        try {
    
    
            return objectMapper.writeValueAsString(map);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 将 JSON 对象转换为 JavaBean
     *
     * @param obj
     * @param clazz
     * @return
     */
    public static <T> T obj2pojo(Object obj, Class<T> clazz) {
    
    
        return objectMapper.convertValue(obj, clazz);
    }
}

Guess you like

Origin blog.csdn.net/u014212540/article/details/127687138