搭建自定义返回值处理器demo
新建springboot项目
修改pom.xml
<!-- 新增依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
MyResponseBody注解
package com.example.handlermethodreturnvaluehandlerdemo;
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyResponseBody {
}
UserController类
package com.example.handlermethodreturnvaluehandlerdemo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class UserController {
@MyResponseBody
@GetMapping("/user")
public int getUser() {
return 1;
}
}
MyReturnValueHandler类
package com.example.handlermethodreturnvaluehandlerdemo;
import com.alibaba.fastjson.JSON;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.HttpServletResponse;
public class MyReturnValueHandler implements HandlerMethodReturnValueHandler {
@Override
public boolean supportsReturnType(MethodParameter returnType) {
return returnType.hasMethodAnnotation(MyResponseBody.class);
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
mavContainer.setRequestHandled(true);
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
response.getWriter().write(JSON.toJSONString(2));
}
}
MyReturnValueHandlerRegister类
package com.example.handlermethodreturnvaluehandlerdemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class MyReturnValueHandlerRegister implements WebMvcConfigurer {
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
@PostConstruct
public void init(){
// 注册PropertiesHandlerMethodReturnValueHandler
List<HandlerMethodReturnValueHandler> handlers = requestMappingHandlerAdapter.getReturnValueHandlers();
List<HandlerMethodReturnValueHandler> newHandlers = new ArrayList<>(handlers.size() + 1) ;
newHandlers.addAll(handlers);
newHandlers.add(new MyReturnValueHandler());
// 重置Handler对象集合
requestMappingHandlerAdapter.setReturnValueHandlers(newHandlers);
}
}
返回2
自定义返回值处理器执行流程
HandlerMethodReturnValueHandler接口处理controller返回值
public interface HandlerMethodReturnValueHandler {
// 是否支持返回值类型
boolean supportsReturnType(MethodParameter returnType);
// 处理返回值
void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;
}
debug接口http://127.0.0.1:8080/user
HandlerMethodReturnValueHandler有15种,包括自定义返回值处理器。
每个请求在HandlerMethodReturnValueHandler列表中从前向后遍历,选择一个HandlerMethodReturnValueHandler来处理。
选择过程
第1步:ServletInvocableHandlerMethod类中invokeAndHandle方法
第2步:HandlerMethodReturnValueHandlerComposite类中handleReturnValue方法
搭建异步处理模式DeferredResult demo
package com.example.demo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
@RestController
@RequestMapping("/deferredResult")
public class DeferredResultTestController {
private DeferredResult<String> deferredResult = new DeferredResult<>();
@RequestMapping("/hold")
public DeferredResult<String> hold() {
return deferredResult;
}
@RequestMapping("/release")
public void release() {
deferredResult.setResult("");
}
}
调用hold接口后一直卡住,直到调用release接口或者http请求超时。
DeferredResult执行流程
1. 第1次收到请求,保存返回的DeferredResult对象,用于后续访问。
2. tomcat请求线程被回收到线程池中。
3. tomcat线程每隔1秒遍历waitingProcessors里面的processor,确认是否过期。如果过期了,就把超时默认值写入DeferredResult对象;否则,业务线程把结果写入之前的DeferredResult对象。
4. 内部自动发起第2次请求,再次调用DispatcherServlet,由ResponseBody返回值处理器返回DeferredResult对象中的数据。
参考资料
https://blog.csdn.net/agonie201218/article/details/123954205
标签:web,自定义,SpringMVC,demo,springframework,import,DeferredResult,org,public From: https://www.cnblogs.com/WJQ2017/p/17778001.html