Spring 學習 - 對結果進行處理

前言

在工作中,我們可能需要封裝一下返回值

比如將返回值封裝爲

{
  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"
}
發佈了193 篇原創文章 · 獲贊 35 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章