SpringMVC启动
server.port=8090
spring.mvc.servlet.load-on-startup=1
@Configuration
@ComponentScan
@PropertySource("classpath:application.properties")
@EnableConfigurationProperties({ServerProperties.class, WebMvcProperties.class})
public class WebConfig {
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory(ServerProperties serverProperties) {
return new TomcatServletWebServerFactory(serverProperties.getPort());
}
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
@Bean
public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(
DispatcherServlet dispatcherServlet,
WebMvcProperties webMvcProperties
) {
DispatcherServletRegistrationBean registrationBean = new DispatcherServletRegistrationBean(dispatcherServlet, "/");
registrationBean.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
return registrationBean;
}
}
public static void main(String[] args) {
AnnotationConfigServletWebServerApplicationContext applicationContext =
new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
}
HandlerMethod
准备自定义注解
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Token {
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Yml {
}
准备控制器
@Slf4j
@Controller
public class TestController {
@GetMapping("/test1")
public ModelAndView test1() {
log.debug("test1");
return null;
}
@PostMapping("/test2")
public ModelAndView test2(@RequestParam String name) {
log.debug("test2({})", name);
return null;
}
@PutMapping("/test3")
public ModelAndView test3(@Token String token) {
log.debug("test3({})", token);
return null;
}
@RequestMapping("/test4")
@Yml
public User test4() {
log.debug("test4()");
return new User("张三", 30);
}
}
@Data
@AllArgsConstructor
class User {
private String name;
private int age;
public static void main(String[] args) {
String userYaml = new Yaml().dump(new User("张三", 30));
System.out.println(userYaml);
}
}
准备RequestMappingHandlerMapping
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return new RequestMappingHandlerMapping();
}
测试
public static void testHandlerMethod(ApplicationContext applicationContext) {
RequestMappingHandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
handlerMethods.forEach((k, v) -> {
System.out.println(k + "=" + v);
});
}
RequestMappingHandlerAdapter
准备自定义RequestMappingHandlerAdapter Bean
public class MyRequestMappingHandlerAdapter extends RequestMappingHandlerAdapter {
@Override
public ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
return super.invokeHandlerMethod(request, response, handlerMethod);
}
}
@Bean
public MyRequestMappingHandlerAdapter myRequestMappingHandlerAdapter() {
MyRequestMappingHandlerAdapter handlerAdapter = new MyRequestMappingHandlerAdapter();
return handlerAdapter;
}
test1
@SneakyThrows
public static void test1(ApplicationContext applicationContext) {
RequestMappingHandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test1");
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain handlerExecutionChain = handlerMapping.getHandler(request);
System.out.println("handlerExecutionChain = " + handlerExecutionChain);
System.out.println("========>");
MyRequestMappingHandlerAdapter handlerAdapter = applicationContext.getBean(MyRequestMappingHandlerAdapter.class);
handlerAdapter.invokeHandlerMethod(request, response, ((HandlerMethod) handlerExecutionChain.getHandler()));
}
test2
@SneakyThrows
public static void test2(ApplicationContext applicationContext) {
RequestMappingHandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/test2");
request.addParameter("name", "zhou");
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain handlerExecutionChain = handlerMapping.getHandler(request);
System.out.println("========>");
MyRequestMappingHandlerAdapter handlerAdapter = applicationContext.getBean(MyRequestMappingHandlerAdapter.class);
handlerAdapter.invokeHandlerMethod(request, response, ((HandlerMethod) handlerExecutionChain.getHandler()));
}
获取所有参数解析器
public static void testAllArgumentResolver(ApplicationContext applicationContext) {
MyRequestMappingHandlerAdapter handlerAdapter = applicationContext.getBean(MyRequestMappingHandlerAdapter.class);
handlerAdapter.getArgumentResolvers().forEach(System.out::println);
}
自定义入参解析器
public class TokenArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
Token token = parameter.getParameterAnnotation(Token.class);
return Objects.nonNull(token);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return webRequest.getHeader("token");
}
}
@Bean
public MyRequestMappingHandlerAdapter myRequestMappingHandlerAdapter() {
MyRequestMappingHandlerAdapter handlerAdapter = new MyRequestMappingHandlerAdapter();
TokenArgumentResolver tokenArgumentResolver = new TokenArgumentResolver();
handlerAdapter.setCustomArgumentResolvers(CollUtil.newArrayList(tokenArgumentResolver));
return handlerAdapter;
}
test3
@SneakyThrows
public static void test3(ApplicationContext applicationContext) {
RequestMappingHandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
MockHttpServletRequest request = new MockHttpServletRequest("PUT", "/test3");
request.addParameter("token", "混淆视听");
request.addHeader("token", "某个token");
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain handlerExecutionChain = handlerMapping.getHandler(request);
System.out.println("========>");
MyRequestMappingHandlerAdapter handlerAdapter = applicationContext.getBean(MyRequestMappingHandlerAdapter.class);
handlerAdapter.invokeHandlerMethod(request, response, ((HandlerMethod) handlerExecutionChain.getHandler()));
}
自定义返回值处理器
public class YmlReturnValueHandler implements HandlerMethodReturnValueHandler {
@Override
public boolean supportsReturnType(MethodParameter returnType) {
Yml yml = returnType.getMethodAnnotation(Yml.class);
return Objects.nonNull(yml);
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
String ret = new Yaml().dump(returnValue);
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
response.setContentType("text/plain;charset=utf-8");
response.getWriter().print(ret);
mavContainer.setRequestHandled(true);
}
}
@Bean
public MyRequestMappingHandlerAdapter myRequestMappingHandlerAdapter() {
MyRequestMappingHandlerAdapter handlerAdapter = new MyRequestMappingHandlerAdapter();
TokenArgumentResolver tokenArgumentResolver = new TokenArgumentResolver();
handlerAdapter.setCustomArgumentResolvers(CollUtil.newArrayList(tokenArgumentResolver));
YmlReturnValueHandler ymlReturnValueHandler = new YmlReturnValueHandler();
handlerAdapter.setReturnValueHandlers(CollUtil.newArrayList(ymlReturnValueHandler));
return handlerAdapter;
}
test4
@SneakyThrows
public static void test4(ApplicationContext applicationContext) {
RequestMappingHandlerMapping handlerMapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
MockHttpServletRequest request = new MockHttpServletRequest("DELETE", "/test4");
request.addParameter("token", "混淆视听");
request.addHeader("token", "某个token");
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain handlerExecutionChain = handlerMapping.getHandler(request);
System.out.println("========>");
MyRequestMappingHandlerAdapter handlerAdapter = applicationContext.getBean(MyRequestMappingHandlerAdapter.class);
handlerAdapter.invokeHandlerMethod(request, response, ((HandlerMethod) handlerExecutionChain.getHandler()));
byte[] ret = response.getContentAsByteArray();
System.out.println(new String(ret, StandardCharsets.UTF_8));
}