实现 ResponseBodyAdvice 定制化JSON 返回字段

 细粒度定制化JSON返回字段,精确控制每一个接口方法返回的字段

1. 创建注解CustomReturnJson 标注在controller 的方法上。 示例:

    @RequestMapping("/testJson")     @ResponseBody     @CustomReturnJson(include = {"id","topicName","topicImg"})     public Object testJson(@RequestParam("name")String name){         Topic topic = topicService.getByTopicName(name);         return ResultVO.success(topic);     }

只返回 id topicName,topicImg 字段

import java.lang.annotation.*;  /**  * @author XXX  * Date: 2019/4/11  * Description:该注解配合 @ResponseBody 一起使用来细粒度定制返回的json @see {CustomReturnResponseBody.class}  */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CustomReturnJson {      /**      * 返回的json包含哪些字段      */     String[] include() default {};  } 

 2.核心逻辑就是实现 ResponseBodyAdvice  方法beforeBodyWrite ,在json返回前处理

import com.alibaba.druid.support.json.JSONUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.BeanContext; import com.alibaba.fastjson.serializer.ContextValueFilter; import com.linktime.unitimes.annotation.CustomReturnJson; import com.linktime.unitimes.vo.ResultVO; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.lang.Nullable; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;  import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors;  /**  * @author liuxun  * Date: 2019/4/11  * Description: 用来控制定制化json 返回  */ @ControllerAdvice @ConditionalOnProperty(name = "CUSTOM_RETURN_JSON_ADVICE",havingValue = "true") @Slf4j public class CustomReturnJsonAdvice implements ResponseBodyAdvice {      @Override     public boolean supports(MethodParameter methodParameter, Class aClass) {         return methodParameter.getMethodAnnotation(CustomReturnJson.class) != null;     }      @Nullable     @Override     public Object beforeBodyWrite(@Nullable Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass, ServerHttpRequest request, ServerHttpResponse response) {          if(body != null && body instanceof ResultVO){             try {                  ResultVO vo = (ResultVO) body;                 Object data = vo.getData();                  CustomReturnJson methodAnnotation = methodParameter.getMethodAnnotation(CustomReturnJson.class);                 String[] include = methodAnnotation.include();                 List<String> collect = Arrays.stream(include).collect(Collectors.toList());                  ContextValueFilter valueFilter = new ContextValueFilter () {                     @Override                     public Object process(BeanContext context, Object object, String name, Object value) {                         if(collect.contains(name)){                             if(value == null){                                 return "";                             }                             return value;                         }else {                             return null;                         }                     }                 };                 String jsonOutput = JSON.toJSONString(data,valueFilter);                 Object parse = JSONUtils.parse(jsonOutput);                 vo.setData(parse);                 return vo;             } catch (Exception e) {                 log.error("CustomReturnResponseBody方法出错",e);                 // 如果出错,原样返回。(就当该不存在这个流程)             }         }          return body;     }  }