自定義注解實現后台獲取當前登陸的用戶信息


思路:

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;
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM