HandlerMethodArgumentResolver存储和获取登录用户信息

一丶传统获取方法

  • 在每次controller中接受token,也就是从请求头中获取token,然后调用tokenUtiils进行解析,出相关的用户信息。进行使用
  • 可以使用AOP。
  • 使用mvc拦截器HandlerInterceptor+方法参数解析器HandlerMethodArgumentResolver

二丶自定义拦截器实现HandlerInterceptor

在实现过程中,主要复写以下方法,前提是自定义一个注解,然后再我们自定义的拦截器中的前置处理方法中,进行注解识别,当有此注解后被拦截,然后从request中获取token,之后处理,将信息进行处理,可以存入线程,或者request域中。

  • 自定义注解
@MustBeDocumented
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class UserAuthValidator```
  • 实现preHandle方法
override fun preHandle(request: HttpServletRequest, response: HttpServletResponse?, handler: Any?): Boolean {
        if (handler is HandlerMethod && handler.hasMethodAnnotation(UserAuthValidator::class.java)) {
            val token = tokenUtils.getToken(request)
            if (StringUtils.isEmpty(token)) {
                throw AuthorizationException()
            }
            setUserInfo(token ?: "")
            setToken(handler, token ?: "")
        }
        return true
    }
  • 实现postHandle方法
    override fun postHandle(
        request: HttpServletRequest?,
        response: HttpServletResponse?,
        handler: Any?,
        modelAndView: ModelAndView?
    ) {
        // 不做任何处理
    }
  • 实现afterCompletion方法
override fun afterCompletion(
        request: HttpServletRequest?,
        response: HttpServletResponse?,
        handler: Any?,
        ex: Exception?
    ) {
        // 资源回收
        try {
            SessionCache.clearResource()
        } catch (e: Throwable) {
            // 不做任何处理
        }
    }
  • 下方是我设置userInfo和token信息的代码
 /**
     * 设置token信息
     */
    private fun setToken(handler: HandlerMethod, token: String) {
        handler.methodParameters.forEach {
            if (it.hasParameterAnnotation(Token::class.java)) {
                if (StringUtils.isEmpty(token)) {
                    throw AuthorizationException()
                }
                SessionCache.saveToken(token)
                return
            }
        }
    }

    /**
     * 设置当前登陆用户信息
     */
    private fun setUserInfo(token: String) {
        val userInfo = try {
            userPlatformService.getUserInfo(token, AuthorizationTypeEnum.STUDENT.authorizationType)
        } catch (e: RestClientException) {
            throw AuthorizationException()
        }
        if (userInfo == null || userInfo.id < 1) {
            throw AuthorizationException()
        }
        SessionCache.saveUserInfo(userInfo)
    }

三丶自定义方法参数解析器实现HandlerMethodArgumentResolver

在使用的时候,我们首先自定义注解,这样方便之后在需要的地方直接加该注解,这样就可以将参数实例化,比如在Controller中需要相关用户信息,我们可以通过在参数位置加该注解进行实例化

  • 自定注解
@MustBeDocumented
@Target(AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.RUNTIME)
annotation class UserInfo
  • 实现该方法,内部复写supportsParameter,只有该方法返回true,才会进行参数解析resolveArgument
    override fun supportsParameter(parameter: MethodParameter?): Boolean {
        if (parameter == null) {
            return false
        }
        // 过滤出符合条件的参数,这里指的是加了UserInfo注解的参数
        if (parameter.hasParameterAnnotation(UserInfo::class.java)) {
            return true
        }
        return false
    }
  • 参数解析,从各种缓存,或者说标题1所提到的存储位置进行获取
    override fun resolveArgument(
        parameter: MethodParameter?,
        mavContainer: ModelAndViewContainer?,
        webRequest: NativeWebRequest,
        binderFactory: WebDataBinderFactory?
    ): Any {
        return SessionCache.getUserInfo() ?: throw throw AuthorizationException()
    }

在上方所提到的,如果是在springboot项目中直接加@Componet进行注解,如果是springmvc项目,需继承WebMvcConfigurationSupport。分别在addInterceptors和addArgumentResolvers方法中,添加自定义的拦截器和参数解析器

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值