细粒度定制化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; } }