Spring Boot接收请求参数问题记录

本文主要记录Spring Boot接收前端请求参数转为实体类过程中碰到的一些问题。

我们在客户端传递了JSON数据,Spring Boot就会自动调用Jackson框架,把JSON字符串数据转为实体类。首先先简要介绍下Jackson框架。

Jackson介绍

Spring Boot提供了与三个JSON映射库的集成:Gson、Jackson、JSON-B。其中Jackson是首选的默认库。

通常,我们将Java对象转成Json时称之为序列化,反之将Json转成Java对象时称之为反序列化。

如何引入

SpringBoot提供了JSON依赖,我们可以按下面方式引入

  1. 直接引入JSON依赖
1
2
3
4
5
<!-- springboot-json -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
  1. 一般情况下我们引入MVC,MVC里面帮我们引入了JSON依赖
1
2
3
4
5
<!-- springboot web(MVC)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

Jackson常用注解

  • @JsonProperty 序列化、反序列化时,属性的名称
  • @JsonIgnoreProperties 序列化、反序列化忽略属性,多个时用“,”隔开
  • @JsonIgnore 序列化、反序列化忽略属性
  • @JsonAlias 为反序列化期间要接受的属性定义一个或多个替代名称,可以与@JsonProperty一起使用
  • @JsonInclude 当属性的值为空(null或者””)时,不进行序列化,可以减少数据传输
  • @JsonFormat 序列化、反序列化时,格式化时间

解析字段注解@JsonIgnoreProperties

当接口的数据无法完全的预知,使得实体类字段有可能不完整。当返回的JSON数据里包含了实体类没有的字段时解析就有可能出错。

我们只需要在实体类上加上注解即可解决。

1
2
3
4
5
6
7
8
9
10
11
12
@JsonIgnoreProperties(ignoreUnknown = true)
class ExtraBean {
private boolean is_museuser;

public boolean isIs_museuser() {
return is_museuser;
}

public void setIs_museuser(boolean is_museuser) {
this.is_museuser = is_museuser;
}
}

实体类属性大小写问题

今天碰到的问题,前台传参后台却接收不到,原来是返回的时候返回小写,但是前台依旧大写传参。其实是JSON返回的时候把首字母变小写了。

我们可以用@JsonProperty注解解决这个问题。不过需要注意一点,如果注解放到属性上,则返回的时候既有大写也有小写

1
2
@JsonProperty("Ao")
private Integer Ao;
1
Result:{Ao:xxx,ao:xxx}

注解放在getter上完美解决,返回只有大写不再自动变为小写的问题。

1
2
3
4
@JsonProperty("Ao")
public Integer getAo() {
return Ao;
}
1
Result:{Ao:xxx}

实体类布尔类型属性is开头的问题

实体类中布尔类型属性转JSON时,如果是is开头,会把is自动去掉,例如:isSuccess会变成success。

原因分析

这是因为:

  • 非boolean类型的参数,getter和setter方法命名的规范是以get和set开头
  • boolean类型的参数,setter方法是以set开头,但是getter方法命名的规范是以is开头

所以,虽然这种方式在某些时候是可以正常运行的,但是在一些rpc框架里面,当反向解析读取到isSuccess()方法的时候,rpc框架会以为其对应的属性值是success,而实际上其对应的属性值是isSuccess,导致属性值获取不到,从而抛出异常。

解决办法

有以下几种解决办法:

  1. 在get方法上面加入@JsonProperty(value = "isSuccess")注解
  2. 布尔类型的字段命名的时候不要以is开头

日期时间格式化问题

我们存储在Mysql中的数据是date类型的,当我们读取出来封装在实体类中的时候,就会变成英文时间格式,而不是yyyy-MM-dd HH:mm:ss这样的中文时间,因此我们需要用到JsonFormat注解来格式化我们的时间。

JSON入参及返回值全局处理

application.propertities文件中增加如下内容:

1
2
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

这种方法:

  1. 支持(content-type=application/json)请求中格式为yyyy-MM-dd HH:mm:ss的字符串,后台用@RequestBody接收,返回值date转为yyyy-MM-dd HH:mm:ss格式string
  2. 不支持(content-type=application/json)请求中yyyy-MM-dd等类型的字符串转为date
  3. 不支持Java8日期api

JSON入参及返回值局部差异化处理

场景:假如全局日期时间处理格式为:yyyy-MM-dd HH:mm:ss,但是某个字段要求接收或返回日期(yyyy-MM-dd)。

我们可以使用注解@JsonFormat(pattern = "yyyy-MM-dd")@JsonFormat可以有两种用法,在对象属性上,或者在属性的 getter 方法上。

  1. 增加到属性上:
1
2
@JsonFormat(pattern = "yyyy-MM-dd", timezone="GMT+8")
private Date updateTime;
  1. 增加到getter方法上:
1
2
3
4
@JsonFormat(pattern="yyyy-MM-dd", timezone="GMT+8")
public Date getUpdateTime() {
return updateTime;
}

参考


----------- 本文结束啦感谢您阅读 -----------

赞赏一杯咖啡

欢迎关注我的其它发布渠道