溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringMVC中的HandlerMethodArgumentResolver接口實現(xiàn)自定義參數類型解析

發(fā)布時間:2021-09-04 16:13:32 來源:億速云 閱讀:172 作者:chen 欄目:大數據

本篇內容主要講解“SpringMVC中的HandlerMethodArgumentResolver接口實現(xiàn)自定義參數類型解析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“SpringMVC中的HandlerMethodArgumentResolver接口實現(xiàn)自定義參數類型解析”吧!

HandlerMethodArgumentResolver 接口

HandlerMethodArgumentResolver 接口看起來很陌生,實際上在SpringMVC中很多地方我們都會直接或者間接的接觸到

例如:

  • @RequestParam 解析 RequestParamMethodArgumentResolver (基礎類型的默認解析器)

  • @PathVariable 解析 PathVariableMethodArgumentResolver

  • @RequestBody 解析 RequestResponseBodyMethodProcessor

  • @CookieValue 解析 ServletCookieValueMethodArgumentResolver ...

通過查看SpringMVC的源碼, 可以看到以下代碼片段,這就是SpringMVC初始化時,默認的所有HandlerMethodArgumentResolver實現(xiàn)

// org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
    List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();

    // Annotation-based argument resolution
    resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
    resolvers.add(new RequestParamMapMethodArgumentResolver());
    resolvers.add(new PathVariableMethodArgumentResolver());
    resolvers.add(new PathVariableMapMethodArgumentResolver());
    resolvers.add(new MatrixVariableMethodArgumentResolver());
    resolvers.add(new MatrixVariableMapMethodArgumentResolver());
    resolvers.add(new ServletModelAttributeMethodProcessor(false));
    resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
    resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
    resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
    resolvers.add(new RequestHeaderMapMethodArgumentResolver());
    resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
    resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
    resolvers.add(new SessionAttributeMethodArgumentResolver());
    resolvers.add(new RequestAttributeMethodArgumentResolver());

    // Type-based argument resolution
    resolvers.add(new ServletRequestMethodArgumentResolver());
    resolvers.add(new ServletResponseMethodArgumentResolver());
    resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
    resolvers.add(new RedirectAttributesMethodArgumentResolver());
    resolvers.add(new ModelMethodProcessor());
    resolvers.add(new MapMethodProcessor());
    resolvers.add(new ErrorsMethodArgumentResolver());
    resolvers.add(new SessionStatusMethodArgumentResolver());
    resolvers.add(new UriComponentsBuilderMethodArgumentResolver());

    // Custom arguments
    if (getCustomArgumentResolvers() != null) {
        resolvers.addAll(getCustomArgumentResolvers());
    }

    // Catch-all
    resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
    resolvers.add(new ServletModelAttributeMethodProcessor(true));

    return resolvers;
}

HandlerMethodArgumentResolver 接口就兩個方法,一個用來判斷是否支持參數類型,一個是解析的具體實現(xiàn)

public interface HandlerMethodArgumentResolver {

    // 返回是否支持該參數
	boolean supportsParameter(MethodParameter parameter);

    // 返回解析后的參數值
	@Nullable
	Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;

}

使用場景

這個接口主要的使用場景就是來實現(xiàn)自定義的參數注入。例如在很多前后端分離的項目中,我們不會去使用Session,而是自己維護一個token來實現(xiàn)狀態(tài)管理,

這種時候,如果需要取得用戶數據,正常操作,我們可能需要手動去取得token,然后去查詢用戶數據

例如以下這個例子,我們從Header中取得token數據,然后從Redis中查詢到用戶標識,接著從數據庫查詢到用戶基本信息

@PostMapping("get-user-info")
public UserInfo getUserInfo(@RequestHeader String token) {
    // 偽代碼
    Long userId = redisClient.get(token);
    UserInfo useInfo = userDao.getById(userId);
    return userInfo;
}

這樣寫沒什么問題,不過在實際的項目中,我們可能很多地方都需要用到用戶的一些基本信息,每次都這樣去手動編碼去取,就顯得得很繁瑣了

我們使用HandlerMethodArgumentResolver接口來實現(xiàn)

// 1. 實現(xiàn)HandlerMethodArgumentResolver接口
public class UserInfoArgumentResolver implements HandlerMethodArgumentResolver{
    private final RedisClient redisClient;
    private final UserDao userDao;
    public UserInfoArgumentResolver(RedisClient redisClient, UserDao userDao) {
        this.redisClient = redisClient;
        this.userDao = userDao;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return UserInfo.class.isAssignableFrom(parameter.getParameterType());
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest nativeRequest = (HttpServletRequest) webRequest.getNativeRequest();
        String token = nativeRequest.getHeader("token");
        Long userId = redisClient.get(token);
        UserInfo useInfo = userDao.getById(userId);
        return userInfo;
    }
}

// 2. 添加到配置中
@Configuration
@EnableWebMvc
public class FastMvcConfiguration implements WebMvcConfigurer {
    @Autowrite
    UserDao userDao;
    @Autowrite
    RedisClient redisClient;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new UserInfoArgumentResolver(redisClient, userDao));
    }
}

// 3. 在Controller中使用
@RestController
public class UserInfoController {
    @PostMapping("get-user-info")
    public UserInfo getUserInfo(UserInfo userInfo) {
        return userInfo;
    }

    @PostMapping("say-hello")
    public String sayHello(UserInfo userInfo) {
        return "hello " + userInfo.getNickName();
    }
}

添加了 UserInfoArgumentResolver 解釋器以后,當我們需要使用UserInfo時,只需要使用指定的類型就可以取得,不需要做其他任何操作

到此,相信大家對“SpringMVC中的HandlerMethodArgumentResolver接口實現(xiàn)自定義參數類型解析”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI