后端返回前端的值为Null时的几种处理方式

问题描述:
接手了公司一个不知道转了几手的老项目,在与前端联调的时候,发现有很多返回数据,都是用实体类来接收返回的,而这其中,甚至有的实体类属性有几十个,但实际需要返回的参数却只需几个,于是就出现了一大长串 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,而且不会对之前的代码造成影响,不好的是写起来相对前两个解决方案也比较麻烦。

事实上,究竟需要使用什么解决方案,是需要根据自己遇到的实际情况来确定,而且同时使用也是可以的,只要适合即可。

你可能感兴趣的:(项目实战,java,spring)