前言
Web系统里,调接口时,通常需要获取当前登陆系统的用户信息,实现方法有很多,常见的是在aop切面里拦截接口进行是否鉴权验证,然后获取当前用户信息。
本篇文章,主要介绍的是另一种方式,spring的自定义参数解析器HandlerMethodArgumentResolver,结合自定义注解实现。
使用HandlerMethodArgumentResolver可以灵活的给某个接口做统一的参数处理,废话不多说,以下是实现步骤。
一、定义一个注解
改注解是用于标记待处理的参数,这边就是我们的User。
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface SecurityUser {
// http://791202.com/
}
1
2
3
4
5
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public@interfaceSecurityUser{
// http://791202.com/
}
二、自定义参数处理类SecurityUserMethodArgumentResolver
让它实现HandlerMethodArgumentResolver,需要根据自己的业务重写两个方法。
supportsParameter:用于判定是否需要处理该参数分解,返回true为需要,并会去调用下面的方法resolveArgument。
resolveArgument:真正用于处理参数分解的方法,返回的Object就是controller方法上的形参对象。
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
@Slf4j
public class SecurityUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
// 类型是User并且被@SecurityUser修饰的参数才被处理
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().isAssignableFrom(User.class)
&& parameter.hasParameterAnnotation(SecurityUser.class);
}
// 这边我使用的是shiro安全框架,其它的也一样,就是获取到当前登陆用户,然后返回
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container, NativeWebRequest webRequest,
WebDataBinderFactory factory) {
Subject subject = SecurityUtils.getSubject();
if (subject.isAuthenticated()) {
return subject.getPrincipal();
} else {
throw new AuthenticationException("未登录");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
importlombok.extern.slf4j.Slf4j;
importorg.apache.shiro.SecurityUtils;
importorg.apache.shiro.authc.AuthenticationException;
importorg.apache.shiro.subject.Subject;
importorg.springframework.core.MethodParameter;
importorg.springframework.web.bind.support.WebDataBinderFactory;
importorg.springframework.web.context.request.NativeWebRequest;
importorg.springframework.web.method.support.HandlerMethodArgumentResolver;
importorg.springframework.web.method.support.ModelAndViewContainer;
@Slf4j
publicclassSecurityUserMethodArgumentResolverimplementsHandlerMethodArgumentResolver{
// 类型是User并且被@SecurityUser修饰的参数才被处理
@Override
publicbooleansupportsParameter(MethodParameterparameter){
returnparameter.getParameterType().isAssignableFrom(User.class)
&¶meter.hasParameterAnnotation(SecurityUser.class);
}
// 这边我使用的是shiro安全框架,其它的也一样,就是获取到当前登陆用户,然后返回
@Override
publicObjectresolveArgument(MethodParameterparameter,ModelAndViewContainercontainer,NativeWebRequestwebRequest,
WebDataBinderFactoryfactory){
Subjectsubject=SecurityUtils.getSubject();
if(subject.isAuthenticated()){
returnsubject.getPrincipal();
}else{
thrownewAuthenticationException("未登录");
}
}
}
三、controller类里使用
@PostMapping(value = "/xxxxxxx", produces = "application/json;charset=UTF-8")
public void xxxxxx(@RequestBody CustomerDTO customer, @SecurityUser User user) {
user.getXXX...
}
1
2
3
4
@PostMapping(value="/xxxxxxx",produces="application/json;charset=UTF-8")
publicvoidxxxxxx(@RequestBodyCustomerDTOcustomer,@SecurityUserUseruser){
user.getXXX...
}
浏览量:
332
0