让springboot序列化空值null为"null"而不是空报文体(jackson)

springboot以@RestController@ResponseBody注解自动处理的接口会将方法返回的对象序列化为json字符串返回给前端,但是默认情况下,如果返回的对象为null,并不会进行json序列化,而是返回空报文体
如果前端使用类似fetch的json()方法这种严格校验json格式的方式获取数据,遇到空报文体就会报错
解决办法:

  • 首先定义一个单例对象用于表示这种需要json序列化的null值
@JsonSerialize(using = NullSerializer::class)
object JsonNull
  • 然后为springboot注册一个controller advice,专门用于处理json接口返回null的情况(如果值非null,则原封不动直接返回,框架会交给下一个advice处理)
@ControllerAdvice
class JsonNullBodyAdvice : ResponseBodyAdvice<Any?> {
  override fun supports(returnType: MethodParameter, converterType: Class<out HttpMessageConverter<*>>): Boolean {
    return AbstractJackson2HttpMessageConverter::class.java.isAssignableFrom(converterType)
  }

  override fun beforeBodyWrite(
    body: Any?, returnType: MethodParameter, contentType: MediaType,
    converterType: Class<out HttpMessageConverter<*>>, request: ServerHttpRequest, response: ServerHttpResponse
  ): Any? {
    return body ?: JsonNull
  }
}

这里之所以需要用一个占位的对象来代替null本身,是因为AbstractMessageConverterMethodProcessor中对所有advice(包括默认的)预处理完的body进行了判断,如果为null,跳过序列化,直接返回空报文体给客户端,改为使用占位对象后,则可以进入jackson的序列化逻辑中,通过注解判断使用NullSerializer向客户端回写合法的json字符串"null"(不包括引号)

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。