善用HttpMessageConverter修改返回值
近日,公司前台的小伙伴说我的返回值不对,处理起来太难了,他平白无故的增加了很多的工作量。我寻思:“纳尼?”。凑近一看,原来是接口的返回值,value为空的返回值都是null,增加了非空判断。
例:
{ "code": "1", "msg": "success", "data": { "orderId": "1313132", "address": null, "goods": null, "createTime": null } }
为了彰显我世界上最好的语言——java的无所不能(主要是看在星巴克的面子上),我决定替他修改了这个返回值了。
1.项目架构
项目整体的架构是采用SpringBoot2.2.6.RELEASE。
2.解决方案
针对上面提出的问题,总结有两种方案:
- 构造返回值时,直接填充
- 前后台交互使用的json,可以在将返回值转换为json时,进行填充处理。
比较一下两种方案的优缺点:
- 方案一:工作量大,不利于系统的扩展,每个接口的返回值都需要处理。
- 方案二:优秀。
NO B B ! SHOW U CODE!
@Configuration @Slf4j public class MvcConfiguration implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.stream().forEach(c -> { if (c instanceof MappingJackson2HttpMessageConverter) { MappingJackson2HttpMessageConverter converter = (MappingJackson2HttpMessageConverter) c; SerializerProvider serializerProvider = converter.getObjectMapper().getSerializerProvider(); serializerProvider.setNullValueSerializer(new NullValueJsonSerializer()); } }); } private class NullValueJsonSerializer extends JsonSerializer<Object> { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { String fieldName = gen.getOutputContext().getCurrentName(); try { Class<?> aClass = gen.getCurrentValue().getClass(); // 获取所有的属性字段,包含其父类的 Map<String, Field> fieldMap = ReflectUtil.getFieldMap(aClass); Field field = fieldMap.get(fieldName); if (null == field) { throw new NoSuchFieldException(String.format(" no such #%s# field", fieldName)); } Class<?> fieldType = field.getType(); // 空字符串 if (fieldType == String.class) { gen.writeString(""); } else if (fieldType == List.class) { gen.writeStartArray(); gen.writeEndArray(); } else if (fieldType.isArray()) { // 空数组 gen.writeStartArray(); gen.writeEndArray(); } else if (fieldType == Map.class) { // 空map gen.writeStartObject(); gen.writeEndObject(); } else { gen.writeNull(); } } catch (NoSuchFieldException e) { e.printStackTrace(); log.error(e.getLocalizedMessage()); } } } }
这段代码的核心思想就是增加了配置类来管理SpringMVC的HttpMessageConverter,修改关于json序列化的对象MappingJackson2HttpMessageConverter,通过修改ObjectMapper的SerializerProvider类,保证了在转换为json的过程中,直接修改生成的值。
给大家看看修改后的成果吧!
{ "code": "1", "msg": "success", "data": { "orderId": "", "address": "", "goods": [], "createTime": null } }
可能到这里大家是不是想跃跃欲试的修改下自己的接口返回值的日期格式。