自定义注解实现后台获取当前登陆的用户信息

思路:

1.自定义注解

2.将用户信息存储在session中  ,当然如果是shiro的话直接通过shiro用户登陆即可。

3.实现HandlerMethodArgumentResolver参数解析类

4.配置拦截器注册自定义的参数解析器

原理:

用户登陆 -> 获取session存储用户信息或者shiro登陆

    ->解析每个请求,判断是否有自定义注解,有 、解析自定义注解的参数,将session或shiro中的用户获取返回给自定义注解中的参数

注意:解析返回的数据类型一定要是自定义注解参数本身或者他的子类 

   同时拦截器应该实现 WebMvcConfigurer 因为WebMvcConfigurerAdapter已经过期 继承WebMvcConfigurationSupport也可以(不推荐)

   因为:【会使静态资源失效,静态资源路径找不到。需要重写addResourceHandlers()方法来手动映射路径:】

   在jdk1.8后接口增加了default方法,接口中的方法不必被实现类全部实现,所以直接实现WebMvcConfigurer即可,不需要通过抽象类WebMvcConfigurerAdapter来过渡。

   代码实现:

   自定义注解:  

import java.lang.annotation.*;

/**
 *
 * 功能描述: 登录用户注解
 *
 * @auther: zhao
 * @date: 2019/8/1 18:04
 * 1.@Target 指定注解的使用范围,这里我们指定ElementType为PARAMETER,也就是参数即可。
 * 2.@Retention作用是定义该注解能保留多久,一共有三种策略,这里我们指定为RUNTIME,也就是运行时。
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.PARAMETER)
public @interface LoginUser {
    /**
     * 当前用户在session对象中的key,"user"  //  session.setAttribute("user",one);
     */
     String value() default "user" ;

}

自定义参数解析器:

loginUser.value()值就是定义的”user“
import com.could.demo.entity.User;
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;


/**
 *
 * 功能描述: 登录用户的MethodArgumentResolver
 *
 * @auther: zhao
 * @date: 2019/8/1 18:06
 */
public class LoginUserMethodArgumentResolver implements HandlerMethodArgumentResolver {

    /**
     *若不想自定义注解,可以直接在实现HandlerMethodArgumentResolver的supportsParameter直接返回true 这样每一个请求过来的都会分解该参数
     * 功能描述: 用于判定是否需要处理该参数分解,返回true为需要,并会去调用下面的方法resolveArgument。
     * @param: [methodParameter]
     * @return: boolean
     * @auther: zhao
     * @date: 2019/8/1 18:06
     * supportsParameter方法,
     * 判断什么时候要执行下面的resolveArgument方法。这里我们判断当一个方法的参数含有@LoginUser
     * 并且方法的参数是我们的用户类时返回true。
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
       return methodParameter.hasParameterAnnotation(LoginUser.class) && User.class.isAssignableFrom(methodParameter.getParameterType());
//       return methodParameter.hasParameterAnnotation(LoginUser.class);
    }

    /**
     *
     * 功能描述: 真正用于处理参数分解的方法,返回的Object就是controller方法上的形参对象。(获得登录用户信息)
     * @param: [methodParameter, modelAndViewContainer, nativeWebRequest, webDataBinderFactory]
     * @return: java.lang.Object
     * @auther: zhao
     * @date: 2019/8/1 18:05
     * resolveArgument方法,在这里我们直接把放在session中的用户信息放回去即可。
     */
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        /**
         * 如果是shiro的话直接通过shiro获取用户信息即可
         */
        LoginUser loginUser = methodParameter.getParameterAnnotation(LoginUser.class);
        if( loginUser != null){
            return nativeWebRequest.getAttribute(loginUser.value(), NativeWebRequest.SCOPE_SESSION);
        }
        return null;

    }

}

注册拦截器:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

/**
 *
 * 功能描述: 获得登录用户的配置类
 *WebMvcConfigurerAdapter已过时
 * 在jdk1.8后增加了default,接口中的方法不必被实现类全部实现,所以直接实现WebMvcConfigurer即可,不需要通过抽象类WebMvcConfigurerAdapter来过渡。
 * @auther: zhao
 * @date: 2019/8/1 18:04
 */
@Configuration
public class LoginUserConfigurer implements WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        // 注册loginUserMethodArgumentResolver的参数分解器
        argumentResolvers.add(loginUserMethodArgumentResolver());
    }

    @Bean(name = "loginUserMethodArgumentResolver")
    public LoginUserMethodArgumentResolver loginUserMethodArgumentResolver(){
        return new LoginUserMethodArgumentResolver();
    }

}
有@Configuration的类可以很多,他们加载时会合并,但要注解@Bean(name = "loginUserMethodArgumentResolver")中的name不要重复。

Controller类:
import com.could.demo.config.security.LoginUser;
import com.could.demo.entity.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

/**
 * AUTHOR :zhao
 * 日期:2020/3/21 20:47
 */
@RestController
public class UserAnnotationController {
    @GetMapping("/loginUser")
    public String login(HttpSession session){
        User user = new User();
        user.setName("头皮发麻");
        user.setPassword("10086");
        session.setAttribute("user",user);
        return "ok";
    }

    /**
     * 测试注解是否能拿到值
     * @param managers
     * @return
     */

    @GetMapping(value = "/testUser")
    public Object testUser(@LoginUser User managers) {
        return managers;
    }

    @GetMapping(value = "/test")
    public Object test(User managers) {
        return managers;
    }
}
posted @ 2020-03-22 16:05  Angry-rookie  阅读(2605)  评论(0编辑  收藏  举报