问题描述:
接手了公司一个不知道转了几手的老项目,在与前端联调的时候,发现有很多返回数据,都是用实体类来接收返回的,而这其中,甚至有的实体类属性有几十个,但实际需要返回的参数却只需几个,于是就出现了一大长串 null 的情况,简直不能忍!!!
// 原本的返回代码示例,来感受一下这种源自内心的颤抖吧
{
"id": 1,
"loginId": 123456,
"loginName": null,
"medicalInstId": null,
"medicalInstName": "阿尔山林业局职工医院",
"licenceCode": null,
"licenceImage": null,
"licenceImageMatch": null,
"province": null,
"city": null,
"district": null,
"address": null,
"contactsName": null,
"contactsPhone": null,
"servicePhone": null,
"institutionsImage": null,
"institutionsImageMatch": null,
"nature": null,
"type": null,
"roleType": null,
"status": null,
"healthInsurance": null,
"parentId": null,
"operator": null,
"mdate": null,
"pDate": null,
"send": null,
"name": null,
"provinceName": null,
"cityName": null,
"districtName": null,
"totalPrice": null,
"longitude": null,
"latitudel": null,
"goodsMedicalCheckUp": [],
"serviceId": null,
"goodsList": null
}
解决方案一:
通过在 DTO 或实体类上添加注解:@JsonInclude(JsonInclude.Include.NON_NULL)
// 当该属性为null时,不返回该属性
@JsonInclude(JsonInclude.Include.NON_NULL)
解决方案二:
当然,如果发现各种实体类各种 DTO 特别多,一个个去找一个个设置很麻烦的时候,也可以在配置文件中进行全局配置。
# 在配置文件中配置后,全局有效
spring.
jackson:
default-property-inclusion: NON_NULL
效果展示:
{
"id": 2,
"loginId": 234567,
"medicalInstName": "爱基因基因检测中心",
"goodsMedicalCheckUp": [
{
"id": 1,
"name": "临床检验",
"mdate": "2017-09-29 14:32:03",
"modifyId": 0,
"userId": 200003,
},
{
"id": 2,
"name": "X线检查",
"mdate": "2017-10-23 13:51:31",
"modifyId": 102,
"userId": 200004,
}
]
}
警告!!!
以上两种解决方案虽然方便有效,但并非适合所有情况!!!
举个遇到的实际例子:
在老项目中,有一个接口是通过用户实体类返回用户信息数据,其中有一个年龄(age)的属性返回的全是null,但这个却并不能去掉,因为数据在返回给前端之前,还会有一个根据出生日期计算年龄的操作,并将这个计算出的值赋给 age 这个属性,然后才真正返回给前端。
当然,这并不是什么严重的问题,也很好解决,比如对可以为 null 且需要保留的属性设置默认值,使其不会被过滤掉。
设置默认值示例:
{
"id": 1,
"loginId": 123456,
"medicalInstName": "阿尔山林业局职工医院",
# 该属性虽然没有值,但并未被过滤掉
"goodsMedicalCheckUp": []
}
但关键在于,你并不知道在别人负责的模块,是否也用到了这个实体类,而且也有另一个类似年龄这样的属性存在,这就使你在使用注解或是全局配置的时候,必须要考虑更多可能存在的情况。
解决方案三:
自己写接收返回数据的 VO(和实体类一样)。
这样的好处是,可以根据自己的需求定制对应的 VO,而且不会对之前的代码造成影响,不好的是写起来相对前两个解决方案也比较麻烦。
事实上,究竟需要使用什么解决方案,是需要根据自己遇到的实际情况来确定,而且同时使用也是可以的,只要适合即可。