• 对象 和 json 互转 四种方式 json-lib、Gson、FastJson、Jackson


    一、 json-lib

    json-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确实是依赖于很多第三方包,
    包括commons-beanutils.jar,commons-collections-3.2.jar,commons-lang-2.6.jar,commons-logging-1.1.1.jar,ezmorph-1.0.6.jar,
    对于复杂类型的转换,json-lib对于json转换成bean还有缺陷,比如一个类里面会出现另一个类的list或者map集合,json-lib从json到bean的转换就会出现问题。
    json-lib在功能和性能上面都不能满足现在互联网化的需求。

    二、 Google的Gson

    1.简介

    (1)Gson是目前功能最全的Json解析神器,Gson当初是为因应Google公司内部需求而由Google自行研发而来 但自从在2008年五月公开发布第一版后已被许多公司或用户应用。
    Gson的应用主要为toJson与fromJson两个转换函数,无依赖,不需要例外额外的jar,能够直接跑在JDK上。
    而在使用这种对象转换之前需先创建好对象的类型以及其成员才能成功的将JSON字符串成功转换成相对应的对象。
    类里面只要有get和set方法,Gson完全可以将复杂类型的json到bean或bean到json的转换,是JSON解析的神器。
    Gson在功能上面无可挑剔,但是性能上面比FastJson有所差距。
    (2)默认是不序列化null值对应的key的,具体案例如下:

    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"}
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    若是想序列化null值对应的key,只需要将以上创建代码改成以下代码就行:

    Gson g = new GsonBuilder().serializeNulls().create();
    
    
    • 1
    • 2

    若是想转行null为空字符串"",则需要手动处理了

    (3)主要类介绍
    Gson类:解析json的最基础的工具类
    JsonParser类:解析器来解析JSON到JsonElements的解析树
    JsonElement类:一个类代表的JSON元素
    JsonObject类:JSON对象类型
    JsonArray类:JsonObject数组
    TypeToken类:用于创建type,比如泛型List

    (4)bean转换json

    Gson gson = new Gson();
    String json = gson.toJson(obj);
    //obj是对象
    
    
    • 1
    • 2
    • 3
    • 4

    (5) json转换bean

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

    (6) json转换复杂的bean,比如List,Set
    将json转换成复杂类型的bean,需要使用TypeToken

    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());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (7) 通过json对象直接操作json以及一些json的工具
    a) 格式化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);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    b) 判断字符串是否是json,通过捕捉的异常来判断是否是json

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    c) 从json串中获取属性

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    d) 除去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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    e) 向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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    f) 修改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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    g) 判断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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    h) json中日期格式的处理

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

    然后使用gson对象进行json的处理,如果出现日期Date类的对象,就会按照设置的格式进行处理

    i) json中对于Html的转义

    Gson gson = new Gson();
    
    • 1

    这种对象默认对Html进行转义,如果不想转义使用下面的方法

    GsonBuilder builder = new GsonBuilder();
    builder.disableHtmlEscaping();
    Gson gson = builder.create();
    
    • 1
    • 2
    • 3

    2. 配置步骤

    1. MAVEN 依赖引入
     <!--gson-->
     <dependency>
         <groupId>com.google.code.gson</groupId>
         <artifactId>gson</artifactId>
         <version>2.8.0</version>
     </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    2. gsonUtil 工具类
    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);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    3. 排除不要序列化的熟悉注解类 Exclude
    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 {
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    三. 阿里巴巴的FastJson

    1.简介

    (1)Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。
    无依赖,不需要例外额外的jar,能够直接跑在JDK上。
    FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。
    FastJson采用独创的算法,将parse的速度提升到极致,超过所有json库。
    (2)fastJson在转换java对象为json的时候,默认是不序列化null值对应的key的,也就是说当对象里面的属性为空的时候,在转换成json时,不序列化那些为null值的属性
    但是如果想把null对应的key序列化出来呢?
    那就要仔细看看fastjson转换java对象为json的时候的入参了:也就是这个方法:

    JSONObject.toJSONString(Object object, SerializerFeature… features)

    Fastjson的SerializerFeature序列化属性:

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

    结合上面,SerializerFeature… features是个数组,那么我们可以传入我们想要的参数,比如想序列化null,案例如下:

    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);
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    (3) bean转换json将对象转换成格式化的json

    JSON.toJSONString(obj,true);
    
    • 1

    (4)将对象转换成非格式化的json

    JSON.toJSONString(obj,false);
    
    • 1

    obj设计对象
    对于复杂类型的转换,对于重复的引用在转成json串后在json串中出现引用的字符,比如 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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (5) json转换bean

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

    (6) json转换复杂的bean,比如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>(){});
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (7)通过json对象直接操作json
    a) 从json串中获取属性

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

    b) 除去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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    c) 向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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    d) 修改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();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    e) 判断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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    f) json中日期格式的处理

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

    简单的使用场景:

    2.配置步骤

    1.引入maven
    <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>fastjson</artifactId>
         <version>1.2.83</version>
     </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    2. 配置 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;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    3. 测试

    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;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    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;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    测试结果:
    在这里插入图片描述

    注意: fastJson 引用2.0.17 版本后 日期格式话失败,退回到1.2.83 版本后正常。

    4. 开源的Jackson

    简介:

    (1)相比json-lib框架,Jackson所依赖的jar包较少,简单易用并且性能也要相对高些。
    而且Jackson社区相对比较活跃,更新速度也比较快。
    Jackson对于复杂类型的json转换bean会出现问题,一些集合Map,List的转换出现问题。
    Jackson对于复杂类型的bean转换Json,转换的json格式不是标准的Json格式

    (2)jackson默认是序列化null对应的key的,也就是说不管你对象属性有没有值,在转换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:......
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2、同理,想要不序列化null也是可以的,具体如下:

    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 不序列化 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    注意:只对VO起作用,Map List不起作用,另外jackson还能过滤掉你设置的属性,具体的就各位自己去研究源码了

    (3)pringboot默认使用Jackson ,@RestController注解,会采用HttpMessageConverter将数据进行转换后写入Response的body数据区

    Jackson配置

    引入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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    1. 通过在application.yml中进行jackson的对应配置去实现

        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
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    2.通过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;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    方式二、重写configureMessageConverters方法

    /**
     * 全局序列化配置类
     */
    @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));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    ObjectMapper 常用工具类

    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 工具类
     * 

    Title: MapperUtils

    *

    Description:

    * */
    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 * * @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 */ 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); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
  • 相关阅读:
    DHCP中继实验(华为)
    C#【必备技能篇】Winform实现多语言切换(.resx文件的应用)
    Linux 环境变量
    Linux SHELL脚本编程
    kafka源码-处理Poll的IO返回结果
    双十二薅羊毛!这几款数码好物不可错过
    SpringBoot教程(十六) SpringBoot集成swagger(全网最全)
    基于UE高渲染的API开发
    Can‘t connect to local MySQL server through socket ‘/tmp/mysql.sock‘ (2)
    从实时监控到智能洞察:Grafana 和 CnosDB 的无限潜力
  • 原文地址:https://blog.csdn.net/u014212540/article/details/127687138