自定义方法参数解析器HandlerMethodArgumentResolver
操作方法如下:(案例)
1.创建自定义注解(即在方法参数上的注解名)
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TokenToAdminUser {
}
2.创建自定义参数解析器(解析参数逻辑代码)
重点关键:继承HandlerMethodArgumentResolver类
返回值为参数解析后的结果,最后返回值放入controller方法参数中赋值
@Component //自定义方法参数解析器
public class TokenToAdminUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private AdminUserTokenMapper adminUserTokenMapper;
public TokenToAdminUserMethodArgumentResolver() {
}
/**
* 当前解析器是否支持解析这种参数
* @param parameter
* @return
*/
public boolean supportsParameter(MethodParameter parameter) {
if (parameter.hasParameterAnnotation(TokenToAdminUser.class)) {
return true;
}
return false;
}
/** supportsParameter()返回值为true时,会执行本方法
* 如果支持,就调用 resolveArgument
* @param parameter
* @param mavContainer
* @param webRequest
* @param binderFactory
* @return
*/
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
if (parameter.getParameterAnnotation(TokenToAdminUser.class) instanceof TokenToAdminUser) {
//解析参数代码逻辑
String token = webRequest.getHeader("Authorization");//获取请求所需参数
//解析
if (null != token && !"".equals(token) && token.length() == Constants.TOKEN_LENGTH) {
AdminUserToken adminUserToken = adminUserTokenMapper.selectByToken(token);
if (adminUserToken == null) {
MallException.fail("管理员未登录!");
} else if (adminUserToken.getExpireTime().getTime() <= System.currentTimeMillis()) {
MallException.fail("管理员登录过期!请重新登录!");
}
//返回解析值,赋值给对应方法上该注解的参数
return adminUserToken;
} else {
MallException.fail("管理员未登录!");
}
}
return null;
}
}
注:此时需要自定义一个参数类型注解,方便创建参数解析器时创建该返回值类型
@Data
public class AdminUserToken {
private Long adminUserId;
private String token;
private Date updateTime;
private Date expireTime;
}
3.添加自定义参数解析器
将我们自定义的解析器添加到web配置中去
@Configuration
public class MallWebMvcConfigurer implements WebMvcConfigurer {
@Autowired
private TokenToAdminUserMethodArgumentResolver tokenToAdminUserMethodArgumentResolver;
/**
* 注册自定义参数解析器
* 配置方法解析器
* @tip @TokenToAdminUser 注解处理方法
* @param argumentResolvers
*/
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(tokenToAdminUserMethodArgumentResolver);
}
}
4.测试
以上配置完成后,在Controller中使用就可以@TokenToAdminUser注解进行参数的转换了
这样就能用adminUser接受自定义解析的参数,只需在方法参数上添加注解@TokenToAdminUser即可,
@RequestMapping("/manage-api/v1")
public class AdminUserAPI {
@Resource
private AdminUserService adminUserService;
@RequestMapping(value = "/logout", method = RequestMethod.DELETE)
public Result logout(@TokenToAdminUser AdminUserToken adminUser) {
adminUserService.logout(adminUser.getAdminUserId());
return ResultGenerator.genSuccessResult();
}
}
好处:
1.可以减少很多代码转换的逻辑,不用每个参数都使用@RequestParam注解去解析参数了,特别是对于一些参数很多的接口,这样无疑极大的减少了很多冗余的代码,让代码看起来比较清爽,只需一个注解即可完成参数逻辑的解析。