Spring Boot中默认的Json解析

我们知道所有JSON数据的生成都离不开HttpMessageConverter,HttpMessageConverter这是一个消息转换工具,主要有两方面的功能:
1、将服务端返回的对象序列化成JSON字符串
2、将前端传来的JSON字符串反序列化成Java对象
在springmvc中也是自动帮我们配置了Jackson和Gson的HttpMessageConverter,在springboot中又对这两个做了自动化配置,一个是JacksonHttpMessageConvertersConfiguration,一个是GsonHttpMessageConvertersConfiguration
我们要是使用jackson和gson的话,没有额外的配置,只需要添加依赖即可

JacksonHttpMessageConvertersConfiguration源码

@Configuration
class JacksonHttpMessageConvertersConfiguration {
    JacksonHttpMessageConvertersConfiguration() {
    }

    @Configuration
    @ConditionalOnClass({XmlMapper.class})
    @ConditionalOnBean({Jackson2ObjectMapperBuilder.class})
    protected static class MappingJackson2XmlHttpMessageConverterConfiguration {
        protected MappingJackson2XmlHttpMessageConverterConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean
        public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter(Jackson2ObjectMapperBuilder builder) {
            return new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build());
        }
    }
	//配置类注解
    @Configuration
    //条件注解,主要导入ObjectMapper相关依赖,后面的配置就会生效
    @ConditionalOnClass({ObjectMapper.class})
    @ConditionalOnBean({ObjectMapper.class})
    @ConditionalOnProperty(
        name = {"spring.http.converters.preferred-json-mapper"},
        havingValue = "jackson",
        matchIfMissing = true
    )
    //主要是这个类
    protected static class MappingJackson2HttpMessageConverterConfiguration {
        protected MappingJackson2HttpMessageConverterConfiguration() {
        }
		//如果我们配置了MappingJackson2HttpMessageConverter就按照我们配置的来,没有配置就按照它这个配置来,默认帮我们生成
        @Bean
        @ConditionalOnMissingBean(
            value = {MappingJackson2HttpMessageConverter.class},
            ignoredType = {"org.springframework.hateoas.mvc.TypeConstrainedMappingJackson2HttpMessageConverter", "org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter"}
        )
        public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
            return new MappingJackson2HttpMessageConverter(objectMapper);
        }
    }

以上只要我们定义一个配置类,定义MappingJackson2HttpMessageConverter实例,定义我们自己的格式,比如说对日期的处理等

GsonHttpMessageConvertersConfiguration源码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.boot.autoconfigure.http;

import com.google.gson.Gson;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase;
import org.springframework.http.converter.json.GsonHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

@Configuration
@ConditionalOnClass({Gson.class})
class GsonHttpMessageConvertersConfiguration {
    GsonHttpMessageConvertersConfiguration() {
    }

    private static class JacksonAndJsonbUnavailableCondition extends NoneNestedConditions {
        JacksonAndJsonbUnavailableCondition() {
            super(ConfigurationPhase.REGISTER_BEAN);
        }

        @ConditionalOnProperty(
            name = {"spring.http.converters.preferred-json-mapper"},
            havingValue = "jsonb"
        )
        static class JsonbPreferred {
            JsonbPreferred() {
            }
        }

        @ConditionalOnBean({MappingJackson2HttpMessageConverter.class})
        static class JacksonAvailable {
            JacksonAvailable() {
            }
        }
    }

    private static class PreferGsonOrJacksonAndJsonbUnavailableCondition extends AnyNestedCondition {
        PreferGsonOrJacksonAndJsonbUnavailableCondition() {
            super(ConfigurationPhase.REGISTER_BEAN);
        }

        @Conditional({GsonHttpMessageConvertersConfiguration.JacksonAndJsonbUnavailableCondition.class})
        static class JacksonJsonbUnavailable {
            JacksonJsonbUnavailable() {
            }
        }

        @ConditionalOnProperty(
            name = {"spring.http.converters.preferred-json-mapper"},
            havingValue = "gson"
        )
        static class GsonPreferred {
            GsonPreferred() {
            }
        }
    }

    @Configuration
    @ConditionalOnBean({Gson.class})
    @Conditional({GsonHttpMessageConvertersConfiguration.PreferGsonOrJacksonAndJsonbUnavailableCondition.class})
    protected static class GsonHttpMessageConverterConfiguration {
        protected GsonHttpMessageConverterConfiguration() {
        }

        @Bean
        @ConditionalOnMissingBean
        public GsonHttpMessageConverter gsonHttpMessageConverter(Gson gson) {
            GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
            converter.setGson(gson);
            return converter;
        }
    }
}

和JacksonHttpMessageConvertersConfiguration 也是差不多的,这里不做过多介绍
下面我们来看看json的解析是如何实现的

定义User类

package com.zhouym.jsondemo;

import com.fasterxml.jackson.annotation.JsonFormat;

import java.util.Date;

/**
 * 〈User类〉
 *
 * @author zhouym
 * @create 2019/8/7
 * @since 1.0.0
 */
public class User {
    private Integer id;
    private String name;
    private String address;
   @JsonFormat(pattern = "yyyy/MM/dd")
    private Date date;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", date=" + date +
                '}';
    }
}

通过上面的JsonFormat注解也是可以实现对日期的格式化,但是如果一个类中有多个,就需要配置多个注解,显然不利于维护,下面我们创建controller类

package com.zhouym.jsondemo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
 * 〈〉
 *
 * @author zhouym
 * @create 2019/8/7
 * @since 1.0.0
 */
@RestController
public class HelloController {

    @GetMapping("/query")
    public List<User> query(){
        List<User> list = new ArrayList<>();
        for (int i=0;i < 10;i++){
            User user = new User();
            user.setId(i);
            user.setName("zhangsan--"+i);
            user.setAddress("sz---"+i);
            user.setDate(new Date());
            list.add(user);
        }

        return list;

    }
}

启动服务器,我们来看看页面输出
Spring Boot中默认的Json解析_第1张图片
我们再来使用配置类定义的格式看看

package com.zhouym.jsondemo;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.text.SimpleDateFormat;

/**
 * 〈〉
 *
 * @author zhouym
 * @create 2019/8/7
 * @since 1.0.0
 */
@Configuration
public class WebMvcConfig{

    @Bean
    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper om = new ObjectMapper();
        om.setDateFormat(new SimpleDateFormat("yyyy/MM/dd"));
        converter.setObjectMapper(om);
        return converter;
    }

启动服务器看看
Spring Boot中默认的Json解析_第2张图片
显然也是可以的

但是发现没有在配置类中,ObjectMapper才是核心的格式转化,我们只需要构建ObjectMapper实例来看看能否实现

package com.zhouym.jsondemo;


import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.text.SimpleDateFormat;

/**
 * 〈〉
 *
 * @author zhouym
 * @create 2019/8/7
 * @since 1.0.0
 */
@Configuration
public class WebMvcConfig{

//    @Bean
//    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
//        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
//        ObjectMapper om = new ObjectMapper();
//        om.setDateFormat(new SimpleDateFormat("yyyy/MM/dd"));
//        converter.setObjectMapper(om);
//        return converter;
//    }

    @Bean
    ObjectMapper objectMapper(){
        ObjectMapper om = new ObjectMapper();
        om.setDateFormat(new SimpleDateFormat("yyyy年MM月dd日"));
        return om;

    }
}

Spring Boot中默认的Json解析_第3张图片

你可能感兴趣的:(Spring,Boot)