springboot2 - ResponseBodyAdvice
对于 Controller 返回值,一般需要进行二次打包。
比如:code 是结果码(0 表示成功,其它表示异常...),data 为携带数据
{
"code": "1",
"data": {
"name": "xiaoming",
"age": "30"
}
}
下面这种封装方式很常见,但是做得还不够好:
- 需要手动调用 Result 工具类;
- 所有的 Controller 都会与 Result 产生强耦合;
- 代码复用性减弱,如果产生新的想法,不方便调整。
class Controller {
@ResponseBody
@RequestMapping("result")
public Result result() {
// do sth.
// 如果业务成功,手动调用表示成功状态的函数
return Result.succeed();
}
}
更优的策略,写一个 AOP 切面统一处理,代码样例如下:
- 这个类不要手动注册,spring 会自动扫描;
- ResponseBodyAdvice 只能处理正常业务流,抛出异常的情况,需要在异常切面中处理。
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.HashMap;
import java.util.Map;
/**
* 指定 basePackages,对特定的程序生效
*/
@ControllerAdvice(basePackages = "cn.seaboot")
public class TestResponseAdvice implements ResponseBodyAdvice<Object> {
/**
* 设置一个标志位,返回 true 才执行 beforeBodyWrite()
*/
@Override
public boolean supports(MethodParameter methodParameter,
Class<? extends HttpMessageConverter<?>> aClass) {
return methodParameter.hasMethodAnnotation(ResponseBody.class);
}
/**
* 数据重新打包
*
* @param o Controller 返回值
* @return 打包之后的数据
*/
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter,
MediaType mediaType,
Class<? extends HttpMessageConverter<?>> aClass,
ServerHttpRequest serverHttpRequest,
ServerHttpResponse serverHttpResponse) {
Map<String, Object> res = new HashMap<>();
res.put("code", 0);
res.put("data", o);
return res;
}
}
疯狂的妞妞 :每一天,做什么都好,不要什么都不做!