最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用HandlerMethodArgumentResolver用于統(tǒng)一獲取當(dāng)前登錄用戶

 更新時(shí)間:2022年12月28日 15:15:30   作者:DayDayUp丶  
這篇文章主要介紹了使用HandlerMethodArgumentResolver用于統(tǒng)一獲取當(dāng)前登錄用戶實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
  • 環(huán)境:SpringBoot 2.0.4.RELEASE
  • 需求:很多Controller方法,剛進(jìn)來要先獲取當(dāng)前登錄用戶的信息,以便做后續(xù)的用戶相關(guān)操作。
  • 準(zhǔn)備工作:前端每次請求都傳token,后端封裝一方法tokenUtils.getUserByToken(token),根據(jù)token解析得到currentUserInfo。

這是一個(gè)常見的業(yè)務(wù)需求,為實(shí)現(xiàn)這個(gè)需求,有以下幾種解決方案:

一、最原始直接

即,每個(gè)Controller開始,先調(diào)用tokenUtils.getUserByToken(token),不夠優(yōu)雅。

二、AOP

AOP可以解決很多切面類問題,思路同Spring AOP來自定義注解實(shí)現(xiàn)審計(jì)或日志記錄(完整代碼),將currentUser放到request里;比起攔截器稍重。

三、攔截器+方法參數(shù)解析器

使用mvc攔截器HandlerInterceptor+方法參數(shù)解析器HandlerMethodArgumentResolver最合適。

SpringMVC提供了mvc攔截器HandlerInterceptor,包含以下3個(gè)方法:

  • preHandle
  • postHandle
  • afterCompletion

HandlerInterceptor經(jīng)常被用來解決攔截事件,如用戶鑒權(quán)等。

另外,Spring也向我們提供了多種解析器Resolver,如用來統(tǒng)一處理異常的HandlerExceptionResolver,以及今天的主角HandlerMethodArgumentResolver

HandlerMethodArgumentResolver是用來處理方法參數(shù)的解析器,包含以下2個(gè)方法:

  • supportsParameter(滿足某種要求,返回true,方可進(jìn)入resolveArgument做參數(shù)處理)
  • resolveArgument

知識儲備已到位,接下來著手實(shí)現(xiàn),主要分為三步走:

  • 自定義權(quán)限攔截器AuthenticationInterceptor攔截所有request請求,并將token解析為currentUser,最終放到request中;
  • 自定義參數(shù)注解@CurrentUser,添加至controller的方法參數(shù)user之上;
  • 自定義方法參數(shù)解析器CurrentUserMethodArgumentResolver,取出request中的user,并賦值給添加了@CurrentUser注解的參數(shù)user。

3.1 自定義權(quán)限攔截器

自定義權(quán)限攔截器AuthenticationInterceptor,需實(shí)現(xiàn)HandlerInterceptor。

在preHandle中調(diào)用tokenUtils.getUserByToken(token),獲取到當(dāng)前用戶,最后塞進(jìn)request中,如下:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
 
import edp.core.utils.TokenUtils;
import edp.core.consts.Consts;
import edp.davinci.model.User;
 
public class AuthenticationInterceptor implements HandlerInterceptor {
 
    @Autowired
    private TokenUtils tokenUtils;
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");
        User user = tokenUtils.getUserByToken(token);
        request.setAttribute(Consts.CURRENT_USER, user);
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }
}

3.2 自定義參數(shù)注解

自定義方法參數(shù)上使用的注解@CurrentUser,代表被它注解過的參數(shù)的值都需要由方法參數(shù)解析器CurrentUserMethodArgumentResolver來“注入”,如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
/**
 * 自定義 當(dāng)前用戶 注解
 * 注解 參數(shù)
 * 此注解在驗(yàn)證token通過后,獲取當(dāng)前token包含用戶
 */
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}

給各Controller類中RequestMapping方法的參數(shù)添加此注解,如下:

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import edp.davinci.core.common.Constants;
import edp.core.annotation.CurrentUser;
import javax.servlet.http.HttpServletRequest;
 
@RestController
@RequestMapping(value = Constants.BASE_API_PATH + "/download")
public class DownloadController {
 
    @GetMapping(value = "/page", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity getDownloadRecordPage(@CurrentUser User user, HttpServletRequest request) {
        ...
    }
}

3.3 自定義方法參數(shù)解析器

自定義方法參數(shù)解析器CurrentUserMethodArgumentResolver,需實(shí)現(xiàn)HandlerMethodArgumentResolver

import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
 
import edp.core.annotation.CurrentUser;
import edp.core.consts.Consts;
import edp.davinci.model.User;
 
/**
 * @CurrentUser 注解 解析器
 */
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(User.class)
                && parameter.hasParameterAnnotation(CurrentUser.class);
    }
 
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        return  (User) webRequest.getAttribute(Consts.CURRENT_USER, RequestAttributes.SCOPE_REQUEST);
    }
}

As we all know,攔截器定義好以后,在SpringMVC項(xiàng)目中,需要去SpringMVC的配置文件springmvc.xml添加該攔截器;但是在SpringBoot中,省去了很多配置文件,取而代之的是被注解@Configuration標(biāo)識的配置類,SpringMVC配置文件對應(yīng)的配置類需繼承WebMvcConfigurationSupport。

同理,解析器定義好以后,也需被添加到SpringMVC的配置文件或配置類中。最后,額外的一步,配置mvc。

3.4 配置MVC

定義MVC配置類,需繼承WebMvcConfigurationSupport。分別在addInterceptors和addArgumentResolvers方法中,添加自定義的攔截器和參數(shù)解析器,如下:

import static edp.core.consts.Consts.EMPTY;
 
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
 
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 
import edp.davinci.core.common.Constants;
import edp.davinci.core.inteceptor.AuthenticationInterceptor;
import edp.davinci.core.inteceptor.CurrentUserMethodArgumentResolver;
 
 
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
 
    @Value("${file.userfiles-path}")
    private String filePath;
 
    /**
     * 登錄校驗(yàn)攔截器
     *
     * @return
     */
    @Bean
    public AuthenticationInterceptor loginRequiredInterceptor() {
        return new AuthenticationInterceptor();
    }
 
    /**
     * CurrentUser 注解參數(shù)解析器
     *
     * @return
     */
    @Bean
    public CurrentUserMethodArgumentResolver currentUserMethodArgumentResolver() {
        return new CurrentUserMethodArgumentResolver();
    }
 
    /**
     * 參數(shù)解析器
     *
     * @param argumentResolvers
     */
    @Override
    protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(currentUserMethodArgumentResolver());
        super.addArgumentResolvers(argumentResolvers);
    }
 
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginRequiredInterceptor())
                .addPathPatterns(Constants.BASE_API_PATH + "/**")
                .excludePathPatterns(Constants.BASE_API_PATH + "/login");
        super.addInterceptors(registry);
    }
 
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/META-INF/resources/")
                .addResourceLocations("classpath:/static/page/")
                .addResourceLocations("classpath:/static/templates/")
                .addResourceLocations("file:" + filePath);
    }
 
    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(SerializerFeature.QuoteFieldNames,
                SerializerFeature.WriteEnumUsingToString,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat,
                SerializerFeature.DisableCircularReferenceDetect);
        fastJsonConfig.setSerializeFilters((ValueFilter) (o, s, source) -> {
            if (null != source && (source instanceof Long || source instanceof BigInteger) && source.toString().length() > 15) {
                return source.toString();
            } else {
                return null == source ? EMPTY : source;
            }
        });
 
        //處理中文亂碼問題
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastConverter.setSupportedMediaTypes(fastMediaTypes);
        fastConverter.setFastJsonConfig(fastJsonConfig);
        converters.add(fastConverter);
    }
}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java關(guān)鍵字this使用方法詳細(xì)講解(通俗易懂)

    Java關(guān)鍵字this使用方法詳細(xì)講解(通俗易懂)

    這篇文章主要介紹了Java關(guān)鍵字this使用方法的相關(guān)資料,Java關(guān)鍵字this主要用于在方法體內(nèi)引用當(dāng)前對象,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-01-01
  • springboot 使用ThreadLocal的實(shí)例代碼

    springboot 使用ThreadLocal的實(shí)例代碼

    這篇文章主要介紹了springboot 使用ThreadLocal的實(shí)例代碼,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • java運(yùn)算符實(shí)例用法總結(jié)

    java運(yùn)算符實(shí)例用法總結(jié)

    在本篇文章里,我們給大家分享的是關(guān)于java運(yùn)算符實(shí)例用法及實(shí)例代碼,需要的朋友們參考下。
    2020-02-02
  • APT?注解處理器實(shí)現(xiàn)?Lombok?常用注解功能詳解

    APT?注解處理器實(shí)現(xiàn)?Lombok?常用注解功能詳解

    這篇文章主要為大家介紹了使用APT?注解處理器實(shí)現(xiàn)?Lombok?常用注解功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Mybatis-Plus實(shí)現(xiàn)多主鍵批量保存及更新詳情

    Mybatis-Plus實(shí)現(xiàn)多主鍵批量保存及更新詳情

    這篇文章主要介紹了Mybatis-Plus實(shí)現(xiàn)多主鍵批量保存及更新詳情,文章通過圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09
  • 解決MyBatis @param注解參數(shù)類型錯(cuò)誤異常的問題

    解決MyBatis @param注解參數(shù)類型錯(cuò)誤異常的問題

    這篇文章主要介紹了解決MyBatis @param注解參數(shù)類型錯(cuò)誤異常的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 深入剖析Java中String類的concat方法

    深入剖析Java中String類的concat方法

    這篇文章主要介紹了Java中String類的concat方法,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java設(shè)計(jì)模式之模板方法模式Template Method Pattern詳解

    Java設(shè)計(jì)模式之模板方法模式Template Method Pattern詳解

    在我們實(shí)際開發(fā)中,如果一個(gè)方法極其復(fù)雜時(shí),如果我們將所有的邏輯寫在一個(gè)方法中,那維護(hù)起來就很困難,要替換某些步驟時(shí)都要重新寫,這樣代碼的擴(kuò)展性就很差,當(dāng)遇到這種情況就要考慮今天的主角——模板方法模式
    2022-11-11
  • maven打包如何指定jdk的版本

    maven打包如何指定jdk的版本

    這篇文章主要介紹了maven打包如何指定jdk的版本問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Linux服務(wù)器Java進(jìn)程消失問題解決

    Linux服務(wù)器Java進(jìn)程消失問題解決

    這篇文章主要介紹了Linux服務(wù)器Java進(jìn)程消失問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11

最新評論

工布江达县| 西乌珠穆沁旗| 朝阳区| 图们市| 泰来县| 彩票| 广元市| 资兴市| 呼伦贝尔市| 长宁区| 枞阳县| 定州市| 巴南区| 平度市| 喀喇| 平舆县| 荃湾区| 永丰县| 昌吉市| 明光市| 巴青县| 兰州市| 抚州市| 菏泽市| 古浪县| 杭锦旗| 遂平县| 巩义市| 常山县| 临湘市| 凌云县| 普兰县| 汉阴县| 饶阳县| 闻喜县| 永丰县| 台北市| 卢氏县| 江永县| 右玉县| 杨浦区|