自定義 之 使用參數註解獲取當前用戶(基於參數解析器HandlerMethodArgumentResolver)

    之前寫了篇自定義註解,這次的註解原理依舊是java的annotation以及反射機制,不過是結合了spring mvc框架而已

做一個簡單的比較常用的參數註解,用來獲取當前的登錄用戶

首先定義一個參數類型的註解CurrentUser

/**
 * @author uiao
 * @Title: 自定義參數類型的註解
 * @date 2018/8/315:36
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CurrentUser {
}

之後要實現HandlerMethodArgumentResolver,重寫resolveArgument方法。在這要注意重寫的supportsParameter方法一定要加上自定義的註解,否則並不會起到作用。

/**
 * @author uiao
 * @Title: CurrentUserArgumentResolver
 * @Description: 重寫參數解析器,獲取當前用戶
 * @date 2018/8/717:34
 */
public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver{
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterAnnotation(CurrentUser.class) != null;
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        String user = (String) request.getSession().getAttribute("username");
        if (StringUtil.isEmpty(user)) {
            user = "遊客";
        }
        return user;
    }
}

    其次還要將我們自己實現的CurrentUserArgumentResolver加入到參數解析器集中,本文的例子我們是用spring boot做的,用spring boot時一般我們都會自己寫一個mvc適配器,繼承自WebMvcConfigurerAdapter,然後我們會在這個適配器裏引入各種我們自己實現的配置,例如攔截器,靜態資源,頁面跳轉等。注意:這個適配器必須要加@Configuration這個註解,在項目啓動纔會加載我們自己實現的配置。

**
 * 適配器 要加上@Configuration纔可以起作用
 * Created by Administrator on 2017/9/20.
 */
@Configuration
public class MyWebMvcConfigureAdapter extends WebMvcConfigurerAdapter {

    /**
     * 添加攔截器
     * 優先級爲:靜態資源 > 攔截器exclude > 攔截器pattern > 頁面跳轉(addViewControllers)
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor())
                .addPathPatterns("/**") // 這些會被攔截
                .excludePathPatterns("/", "/login", "/login/prelogin", "/login/dologin"); // 這些不會攔截
        super.addInterceptors(registry);
    }

    /**
     * 添加自定義的參數解析器
     *
     * @param argumentResolvers
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new CurrentUserArgumentResolver());
    }
}

使用@CurrentUser註解

/**
 * @author uiao
 * @Title: CurrentDemoController
 * @Description: currentUser註解測試類
 * @date 2018/8/717:49
 */
@Controller
@RequestMapping(value = "current", method = RequestMethod.GET)
public class CurrentDemoController {

    org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(CurrentDemoController.class);

    @GetMapping("getname")
    public String converter(Map<String, Object> model, @CurrentUser String user) {
        logger.info("當前用戶爲 ==>>");
        logger.info(user);
        model.put("name", user);
        return "home";
    }
}

登錄後控制檯及頁面輸出的結果

請求url :  http://localhost:8080/current/getname
請求uri :  /current/getname
請求方法 : GET
權限驗證成功
2018-08-07 23:59:27.696 [http-nio-8080-exec-4] INFO  c.u.s.c.CurrentDemoController - 當前用戶爲 ==>>
2018-08-07 23:59:27.696 [http-nio-8080-exec-4] INFO  c.u.s.c.CurrentDemoController - cuihao

 

end。。。

另外,如果我們的項目是spring mvc,實現過程大同小異,只是需要把在適配器中使用addArgumentResolvers方法引入自建參數解析器。換成在xml內配置參數解析器就行。可以參考這篇博文。http://www.cnblogs.com/yangzhilong/p/6282218.html

我自己也補上吧,xml配置如下:

<mvc:annotation-driven conversion-service="conversionService">
    <mvc:argument-resolvers>
            <beans:bean class="com.uiao.stone.resolver.UserIdParameterResolver"></beans:bean>
            <beans:bean class="com.uiao.stone.resolver.CurrentUserArgumentResolver"></beans:bean>
    </mvc:argument-resolvers>
</mvc:annotation-driven>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章