HandlerMethodArgumentResolver 参数解析器
附:demo的gitHub地址:
https://github.com/Fly0708/smLearn/tree/master/arguresolver/src/main/java/com/mpt/arguResolver
springMVC中,controller层中的方法中经常会有@RequestParam,@PathVariable这种注解。‘
HandlerMethodArgumentResolver参数解析器可以结合拦截器进行使用,经过自己测试,其执行流程是先被拦截器拦截,再经过参数解析器的处理,
实现接口HandlerMethodArgumentResolver 需要实现两个方法
supportsParameter:用于判定是否需要处理该参数分解,返回true为需要,并会去调用下面的方法resolveArgument。
resolveArgument:真正用于处理参数分解的方法,返回的Object就是controller方法上的形参对象。
简单Demo(SpringBoot项目 启动器:spring-boot-starter-web)
注解:@LoginedUser
package com.mpt.arguResolver.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author huangQiChang
* @date 2019/7/2
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginedUser {
}
拦截器:AuthorityInterceptor.java(springBoot拦截器的拦截路径在配置类中配置)
package com.mpt.arguResolver.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author huangQiChang
* @date 2019/7/2
*/
@Component
public class AuthorityInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
}
参数解析器:LoginUserHandlerMethodArgumentResolver.java
package com.mpt.arguResolver.resolver;
import com.mpt.arguResolver.anno.LoginedUser;
import com.mpt.arguResolver.pojo.User;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import java.lang.reflect.Method;
/**
* @author huangQiChang
* @date 2019/7/2
*/
@Component
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver
{
@Override
public boolean supportsParameter(MethodParameter parameter) {
LoginedUser loginedUser = parameter.getParameterAnnotation(LoginedUser.class);
boolean isAssign = User.class.isAssignableFrom(parameter.getParameterType());//检验isAssignableFrom方法
return (loginedUser != null && isAssign);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Method method = parameter.getMethod();//检验能不能获得参数被注解的参数
Object name = webRequest.getParameter("name");
if (name == null) {
return null;
}
User user = new User();
user.setName((String) name);
user.setAge("20");
return user;//这里为了测试方便直接返回一个User对象,实际写逻辑,比如查数据库
}
}
参数解析器中先执行supportsParameter()方法,判断被拦截器拦截的方法中的参数(依次执行supportsParameter() resolveArgument() ,方法中有两个参数就会执行两遍)。
拦截器 参数解析器配置类:WebMvcConfig.java
package com.mpt.arguResolver.config;
import com.mpt.arguResolver.interceptor.AuthorityInterceptor;
import com.mpt.arguResolver.resolver.LoginUserHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
/**
* @author huangQiChang
* @date 2019/7/2
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private LoginUserHandlerMethodArgumentResolver loginUserResolver;
@Autowired
private AuthorityInterceptor authorityInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册拦截器
registry.addInterceptor(authorityInterceptor).addPathPatterns("/**");
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
//注册参数解析器
resolvers.add(loginUserResolver);
}
}
实体类:User.java
package com.mpt.arguResolver.pojo;
/**
* @author huangQiChang
* @date 2019/7/2
*/
public class User {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
UserController.java
package com.mpt.arguResolver.controller;
import com.mpt.arguResolver.anno.LoginedUser;
import com.mpt.arguResolver.pojo.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author huangQiChang
* @date 2019/7/2
*/
@RestController
public class UserController {
@GetMapping("/test")
public User test(@LoginedUser User user,String haha) {
return user;
}
}
测试:访问test方法,方法返回经过参数解析器处理后的User对象,
spring中的具体执行流程还需要以后研究
网友评论