一.参数解析器
参数解析器HandlerMethodArgumentResovler,可以对参数进行解析,例如@RequestParam,@Header等,下面我们来自定义实现一个@Token解析器,用于接受请求头中携带的token信息
二.自定义Token解析器
1.定义@Token
//在方法参数上使用
@Target(ElementType.PARAMETER)
//在运行时使用
@Retention(RetentionPolicy.RUNTIME)
public @interface Token {
}
2.自定义token解析器
public class TokenResovler implements HandlerMethodArgumentResolver {
/**
* 判断是否存在注解
* @param parameter
* @return
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
Token token = parameter.getParameterAnnotation(Token.class);
return token != null;
}
//返回获取到的参数值
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
//从头信息中获取
return webRequest.getHeader("token");
}
}
3.将token解析器添加到适配器中
//自定义RequestMappingHandlerAdapter
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(){
MyRequestMappingHandlerAdapter adapter = new MyRequestMappingHandlerAdapter();
//添加token参数解析器
ArrayList<HandlerMethodArgumentResolver> list = new ArrayList<>();
list.add(new TokenResovler());
adapter.setCustomArgumentResolvers(list);
return adapter;
}
4.写好controller方法
@PostMapping("/test4")
public String test4(@Token String token){
log.info("token:"+token);
return "test4";
}
5.模拟请求调用
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/test4");
request.addHeader("token","张三");
HttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain chain = handlerMapping
.getHandler(request);
MyRequestMappingHandlerAdapter handlerAdapter = context
.getBean(MyRequestMappingHandlerAdapter.class);
//调用该方法
handlerAdapter.invokeHandlerMethod(request,response, (HandlerMethod) chain.getHandler());
6.运行
11:10:34.872 [main] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.jjh.config.MyController#test4(String)
11:10:34.884 [main] INFO com.jjh.config.MyController - token:张三
可以看到已经成功通过我们自定义的token头信息解析器获取到头信息的值了!
三.自定义yaml返回值解析器
1.自定义@Yml
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Yml {
}
2.自定义yml返回值解析器
public class YmlReturnValueHandler implements HandlerMethodReturnValueHandler {
@Override
public boolean supportsReturnType(MethodParameter returnType) {
Yml yml = returnType.getMethodAnnotation(Yml.class);
return yml !=null;
}
@Override
public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
//将结果对象转化为yaml字符串
String yaml = new Yaml().dump(returnValue);
//将yaml字符串写入响应对象
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
assert response != null;
response.setContentType("text/plain;charset=utf-8");
response.getWriter().print(yaml);
//设置请求处理完成
mavContainer.setRequestHandled(true);
}
}
3.将yml返回值解析器添加到适配器中
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(){
MyRequestMappingHandlerAdapter adapter = new MyRequestMappingHandlerAdapter();
//添加token参数解析器
ArrayList<HandlerMethodArgumentResolver> list = new ArrayList<>();
list.add(new TokenResovler());
adapter.setCustomArgumentResolvers(list);
//添加yaml结果解析器
ArrayList<HandlerMethodReturnValueHandler> returnlist = new ArrayList<>();
returnlist.add(new YmlReturnValueHandler());
adapter.setCustomReturnValueHandlers(returnlist);
return adapter;
}
4.写好controller方法
@RequestMapping("/test5")
@Yml
public User test5(){
log.info("test5...");
return new User("jjh123","123456");
}
5.模拟请求调用
MockHttpServletRequest request = new MockHttpServletRequest("GET","/test5");
MockHttpServletResponse response = new MockHttpServletResponse();
HandlerExecutionChain chain = handlerMapping.getHandler(request);
MyRequestMappingHandlerAdapter handlerAdapter =
context.getBean(MyRequestMappingHandlerAdapter.class);
assert chain != null;
handlerAdapter.invokeHandlerMethod(request,response, (HandlerMethod) chain.getHandler());
//检查响应
byte[] content = response.getContentAsByteArray();
java.lang.String str = StringUtils.defaultToString(content);
System.out.println(str);