前言
在工作中,我們可能需要封裝一下返回值
比如將返回值封裝爲
{
code: "200",
data: "www"
}
演示
自定義註解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseData {
}
返回www,等待上層封裝
@RestController
public class TestController {
@GetMapping("test")
@ResponseData // 自定義註解
public String test(){
return "www";
}
}
自定義處理器 HandlerMethodReturnValueHandler
public class MyHandlerMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
private final RequestResponseBodyMethodProcessor target;
public MyHandlerMethodReturnValueHandler(RequestResponseBodyMethodProcessor target) {
this.target = target;
}
@Override
public boolean supportsReturnType(MethodParameter methodParameter) {
System.out.println("TestReturnValueHandler:supportsReturnType");
// 是否爲自定義註解,以及默認的 ResponseData
return methodParameter.hasMethodAnnotation(ResponseData.class)||
methodParameter.hasMethodAnnotation(ResponseBody.class);
}
@Override
public void handleReturnValue(Object o, MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest) throws Exception {
System.out.println("TestReturnValueHandler:handleReturnValue");
if(methodParameter.hasMethodAnnotation(ResponseData.class)){
//使用了自定義註解 ResponseData,那麼對返回值進行封裝
Map<String,Object> res = new HashMap<>();
res.put("code","200");
res.put("data",o);
target.handleReturnValue
(res,methodParameter,modelAndViewContainer,nativeWebRequest);
} else {
// 其他情況,默認
target.handleReturnValue(
o,methodParameter,modelAndViewContainer,nativeWebRequest);
}
}
}
初始化切面,主要是爲了在啓動時,替換原來的類爲自己的類
其實爲什麼這麼做是因爲spring-mvc中array然後往裏加,你自定義的類正常是排不到前面的,也就是系統類已經處理了,就輪不到你了
@Configuration
public class InitializingAdvice implements InitializingBean {
@Autowired
private RequestMappingHandlerAdapter adapter;
@Override
public void afterPropertiesSet() throws Exception {
List<HandlerMethodReturnValueHandler> returnValueHandlers = adapter.getReturnValueHandlers();
List<HandlerMethodReturnValueHandler> handlers = new ArrayList(returnValueHandlers);
this.decorateHandlers(handlers);
adapter.setReturnValueHandlers(handlers);;
}
private void decorateHandlers(List<HandlerMethodReturnValueHandler> handlers) {
for (HandlerMethodReturnValueHandler handler : handlers) {
if (handler instanceof RequestResponseBodyMethodProcessor) {
MyHandlerMethodReturnValueHandler decorator =
new MyHandlerMethodReturnValueHandler(
(RequestResponseBodyMethodProcessor) handler);
int index = handlers.indexOf(handler);
handlers.set(index, decorator);
break;
}
}
}
}
啓動
@SpringBootApplication
public class SpringbootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class, args);
}
}
訪問:http://localhost:8080/test
{
code: "200",
data: "www"
}