SpringBoot关于JSON交互问题

一、Json交互的优势

1.JSON本来就是javascript里的内容,客户端可以很容易对JSON数据解析.

2.数据格式简单、易于读写、带宽占用小、不错的可读性、可表示各类复杂性的数据。

3.服务端也能直接使用JSON格式数据,简化了代码开发量,易于维护。

二、SpringBoot之Controller中的使用

1.实际项目中,前后端分离成为主流趋势,后台负责业务逻辑处理,前端负责数据展示。后台接口返回数据一般使用json格式,也可能使用xml。使用json报文。了解下面注解。

@Controller :处理http请求。

@ResponseBody :返回的结果直接写入 HTTP 响应正文,@Responsebody 后返回结果不会被解析为跳转路径,        直接写入HTTP 响应正文中。

@RestController :注解相当于@ResponseBody + @Controller合在一起的作用。(Spring4之后新加的注解)。

@Controller
@RequestMapping("/user")
public class UsersController
{
    @GetMapping("/getUser")
    @ResponseBody 
    public User getUser()
    {
        User user=new User();
        user.setId(24);            
        user.setLoginName("Kobe");
        user.setRealName("Bryant");
        user.setPasswd("123456");
        return user;
    }
}



访问url:http://localhost:9090/oms/user/getUser
返回结果:
    {
        "id": 24,
        "lastModifyUId": 0,
        "lastModifyTime": null,
        "lastLoginTime": null,
        "loginIP": null,
        "loginName": "Kobe",
        "nickName": null,
        "realName": "Bryant",
        "passwd": "123456",
        "phone": null,
        "email": null,
        "areaId": null,
        "areaName": null,
        "status": null,
        "onlineStatus": 0,
        "salt": null,
        "isPreinstall": 0,
        "roleIds": null,
        "roles": null,
        "userPermissions": null,
        "rememberMe": false
    }

三、SpringBoot的默认JSON解析器(Jackson)

1.由上面例子可见并未做任何配置,返回值为User对象,直接转换为JSON格式输出。Spring-Boot对json做了默认实现,使用的是内置Jackson转换器。

2.从上面返回结果可以发现两个问题,第一、许多为null的字段也输出。第二、有些字段不想返回给前端(比如说密码)。

1.在Bean类上添加注@JsonInclude(Include.NON_NULL)配置.

@JsonInclude(Include.NON_NULL)
public class User implements Serializable{

    private static final long serialVersionUID = 1L;
    private int id;
    private int lastModifyUId;
    private Date lastModifyTime;
    private String lastLoginTime; //登陆时间
    private String loginIP;  //登陆IP
    private String loginName;
    ......

其中枚举类型属性:

    1.Include.Include.ALWAYS : 默认

    2.Include.NON_DEFAULT : 默认值不序列化

    3.Include.NON_EMPTY : 属性为 空("") 或者为 NULL 都不序列化

    4.Include.NON_NULL : 属性为NULL 不序列化

返回结果:
    {
        "id": 24,
        "lastModifyUId": 0,
        "loginName": "Kobe",
        "realName": "Bryant",
        "passwd": "123456",
        "onlineStatus": 0,
        "isPreinstall": 0,
        "rememberMe": false
    }

2.从返回结果看值为null的字段没有序列化,但是passwd还是返回出来.可以再Bean类的不需要序列化的字段上加@JsonIgnore注解.

返回结果:
    {
    "id": 24,
    "lastModifyUId": 0,
    "loginName": "Kobe",
    "realName": "Bryant",
    "onlineStatus": 0,
    "isPreinstall": 0,
    "rememberMe": false
}

四、SpringBoot自定义JSON解析器(fastjson)

1.一般开发中习惯使用阿里的fastjson解析工具,fastjson具有极快的性能.fastjson是一个java库集合,可以操作任何java对象,直接使用泛型.fastJson默认将null的字段去除。

添加依赖(注意解决冲突)

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

配置fastjson有两种方式

第一种:

    ① 启动类继承 WebMvcConfigurerAdapter 。

    ②覆盖configureMessageConverters方法。

@SpringBootApplication  //申明让spring boot自动给程序进行必要的配置
public class AppStart extends WebMvcConfigurerAdapter {

    public static void main(String[] args) {
        SpringApplication.run(AppStart.class, args);
    }

    /**
     * 替换框架json为fastjson
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.PrettyFormat, 
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullNumberAsZero, 
                SerializerFeature.WriteNullStringAsEmpty
            );
        // 处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        fastConverter.setFastJsonConfig(fastJsonConfig);

        //处理字符串, 避免直接返回字符串的时候被添加了引号
        StringHttpMessageConverter smc = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        converters.add(smc);

        converters.add(fastConverter);
    }
}

第二种:

@Bean注入第三方的json解析框架

@Bean//使用@Bean注入fastJsonHttpMessageConvert
public HttpMessageConverters fastJsonHttpMessageConverters(){
//1.需要定义一个Convert转换消息的对象
FastJsonHttpMessageConverter fastConverter=new FastJsonHttpMessageConverter();
//2.添加fastjson的配置信息,比如是否要格式化返回的json数据
FastJsonConfig fastJsonConfig=new FastJsonConfig();
//SerializerFeature.WriteMapNullValue序列化null的字段
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
//3.在convert中添加配置信息
fastConverter.setFastJsonConfig(fastJsonConfig);
HttpMessageConverter<?> converter=fastConverter;
return new HttpMessageConverters(converter);
}

实体类中不需要序列化的字段可添加注解@JSONField(serialize=false)。

如果需要序列化null的字段,也可进行配置。具体可查阅fastJson的配置。