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