springboot springmvc 返回对象 为null的时候 

默认ajax前台接收的时候会进入到error中。不想返回null。如果是对象,理想的是返回为[] 

网上也有碰到这种问题的,百度不到,google

看里面答案中的评论,应该是参考下面的:

@JsonSerialize public class EmptyJsonResponse { }
@RestController public class CompanyController { @RequestMapping(value = "/api/something", method = RequestMethod.GET) public ResponseEntity something() { return new ResponseEntity(new EmptyJsonResponse(), HttpStatus.OK); } }

 

总的来说,就是判断是否为null,然后封装一下。感觉每个地方都这么处理的话,有点啰嗦了。

要不然还是过滤器或者其他地方拦截下,如果是ajax请求,是null或者空字符的情况,返回EmptyJsonResponse  类吧。

@JsonSerialize public class EmptyJsonResponse { }  

方法一

第一种方式是替换掉RequestResponseBodyMethodProcessor,这需要使用一个MethodReturnValueHandler的装饰类:

方法二

第二种方式基于ControllerAdvice和HttpMessageConverter实现。

首先用一个ResponseBodyAdvice类的实现包装Controller的返回值:

如果Controller类的返回值没有String类型的,仅有上面这个类就够了。如果有String类型的返回值,就有可能遇到类型不匹配的问题。HttpMessageConverter是根据Controller的原始返回值类型进行处理的,而我们在ResponseAdvisor中改变了返回值的类型。如果HttpMessageConverter处理的目标类型是Object还好说,如果是其它类型就会出现问题,其中最容易出现问题的就是String类型,因为在所有的HttpMessageConverter实例集合中,StringHttpMessageConverter要比其它的Converter排得靠前一些。我们需要尝试将处理Object类型的HttpMessageConverter放得靠前一些,这可以在Configuration类中完成:

 

我这里参考方法二,另外要处理string这种情况的问题,否则返回string有问题

另外使用了这种方式(converters.add(0,mappingJackson2HttpMessageConverter);)后,如果想控制其他的,比如json返回实体中有null属性的,自动不返回。全局的配置default-property-inclusion: non_null 无效。属性上面加@JsonInclude(JsonInclude.Include.NON_NULL) 有用,但是不可能一个个加。

后面查了下。如下,设置下mapper即可(后面有完整代码)(后面发现这种方法,针对返回null的情况不行,不会进入到beforeBodyWrite方法中。后面是采用了FastJsonHttpMessageConverter,详情见后面)

ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

最终如下:

@ControllerAdvice
public class ResponseAdvisor implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?> > converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body,
                                  MethodParameter returnType,
                                  MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request,
                                  ServerHttpResponse response) {
        //null 或者空的处理 返回json 空对象[] 
        if (body==null||body.equals("")) {
            return new EmptyJsonResponse();
        }
        //如果直接返回string 或者数字 ,包装一下
        if(body instanceof  String ||body instanceof Number){
            return ResultUtil.success(body);
        }
        return body;
    }

    @JsonSerialize
    public class EmptyJsonResponse { }
}

 下面这种方式,对null的返回没办法。进入不到上面的方法。

@Override
  public void configureMessageConverters(List<HttpMessageConverter<?> > converters) {
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); //属性为NULL不序列化
    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter= new MappingJackson2HttpMessageConverter();
    mappingJackson2HttpMessageConverter.setObjectMapper(mapper);
    converters.add(0,mappingJackson2HttpMessageConverter);//返回是string的话,默认把object的处理放在最前,否则ResponseAdvisor 处理字符串返回时会报类型不一致的问题
  }

采用如下方式 fastjson


@Override
public void configureMessageConverters(List<HttpMessageConverter<?> > converters) {
    //针对字段的处理
    FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
    FastJsonConfig fastJsonConfig = new FastJsonConfig();
    fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullListAsEmpty,// List字段如果为null,输出为[],而非null
            SerializerFeature.WriteMapNullValue,//加上后,字段为null的也会输出
            SerializerFeature.WriteNullStringAsEmpty,//字符类型字段如果为null,输出为”“,而非null
            SerializerFeature.WriteNullBooleanAsFalse,//Boolean字段如果为null,输出为false,而非null
            SerializerFeature.PrettyFormat  //结果是否格式化,默认为false
    );
    //日期格式化
    fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
    converter.setFastJsonConfig(fastJsonConfig);
    converters.add(0,converter);//返回是string的话,默认把这个放在最前,否则ResponseAdvisor 处理字符串返回时会报类型不一致的问题
}