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"
(不包括引号)
网友评论