SpringBoot項目實用功能之實現(xiàn)自定義參數(shù)解析器
核心點
1、實現(xiàn)接口
org.springframework.web.method.support.HandlerMethodArgumentResolver
- supportsParameter 方法根據(jù)當(dāng)前方法參數(shù)決定是否需要應(yīng)用當(dāng)前這個參數(shù)解析器
- resolveArgument 執(zhí)行具體的解析過程
2、將自實現(xiàn)的參數(shù)解析器類
添加到Spring容器中
3、實現(xiàn)
org.springframework.web.servlet.config.annotation.WebMvcConfigurer
接口addArgumentResolvers方法,將自己的參數(shù)解析器加入到列表中
動手實現(xiàn)
有點懶,也不想直接找一個例子了,之前正好寫過一個,允許前端定義查詢表達式,可以讓前端自定義查詢字段查詢條件和查詢值,然后進行and和or的組合,那么就每個條件就是一個查詢對象,多個的話就組成一個查詢對象列表對象,這里只展示思路,就補貼實際的類的代碼了。
簡單說明一下, 這個參數(shù)解析器是用來解析List<QueryParam>這個形式的參數(shù)類型的。
1、實現(xiàn)
org.springframework.web.method.support.HandlerMethodArgumentResolver
public class QueryParamArgumentResolver implements HandlerMethodArgumentResolver {
/**
* 判斷當(dāng)前參數(shù)是否需要解析,該解析器用來解析參數(shù)類型為List<QueryParam>
*
* @param parameter
* @return
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
boolean isList = List.class.equals(parameter.getParameterType());
if (isList) {
Type genericType = parameter.getGenericParameterType();
if (genericType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type actualTypeArgument = parameterizedType.getActualTypeArguments()[0];
return actualTypeArgument.getTypeName().equals(QueryParam.class.getName());
}
}
return false;
}
/**
* 將前端參數(shù)名稱為{@link ContextKey#queryParams}的字符串值解析為List<QueryParam>,用于查詢
*
* @param parameter
* @param mavContainer
* @param webRequest
* @param binderFactory
* @return
* @throws Exception
*/
@Override
public List<QueryParam> resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String queryParamsStr = webRequest.getParameter(ContextKey.queryParams.name());
if (StrUtil.isBlank(queryParamsStr)) {
return Collections.emptyList();
}
final List<QueryParam> params = JsonUtil.getInstance()
.readValue(queryParamsStr, new TypeReference<List<QueryParam>>() {
@Override
public Type getType() {
return super.getType();
}
});
if (CollectionUtil.isNotEmpty(params)) {
for (QueryParam param : params) {
if (param.getRelative() == null) {
param.setRelative(QueryParam.Relative.AND);
}
if (param.getOp() == null) {
param.setOp(QueryParam.Op.EQ);
}
}
}
return params;
}
}
2、在配置類中注冊當(dāng)前自定義的參數(shù)解析器
這里采用直接實現(xiàn)org.springframework.web.servlet.config.annotation.WebMvcConfigurer接口,通過增加@Configuration注解,即充當(dāng)了配置類,又可以實現(xiàn)添加webmvc功能的接口
@Configuration
public class CoreWebConfig implements WebMvcConfigurer {
/**
* 注冊解析器
*
* @return
*/
@Bean
public QueryParamArgumentResolver queryParamArgumentResolver() {
return new QueryParamArgumentResolver();
}
/**
* 配置自定義參數(shù)解析器
*
* @param resolvers
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(queryParamArgumentResolver());
}
}
項目實例
在某些對外的接口中,可能會存在這樣一種情況
相同的一個接口,即需要滿足對方用Content-Type: application/json這種格式傳輸,那么對應(yīng)的后臺接口就需要用@RequestBody來注解參數(shù);還有一些老的用戶用application/x-www-form-urlencoded這種傳參的話,那么后臺參數(shù)一定不能使用@RequestBody來注釋參數(shù),因為這兩種請求方式對應(yīng)的后臺的參數(shù)解析器是不一樣的。
那么如果我們想要相同的寫法,兩種參數(shù)都支持的話,就需要自定義參數(shù)解析器了。
當(dāng)然需要明確一點,這個自定義的參數(shù)解析器和其它可能會有點不一樣,因為其實對應(yīng)的兩種參數(shù)解析,SpringMVC都有了自己對應(yīng)的參數(shù)解析器,我們現(xiàn)在只是在前面攔截一層,根據(jù)根據(jù)Content-Type做一層轉(zhuǎn)發(fā),最后還是委托給對應(yīng)的參數(shù)解析器來完成這個工作。
關(guān)于這一塊,之前寫過一篇文章了,可以參考自定義參數(shù)解析器同一個參數(shù)支持多種Content-Type。
好了,以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實現(xiàn)小i機器人api接口調(diào)用示例
這篇文章主要介紹了java實現(xiàn)小i機器人api接口調(diào)用示例,需要的朋友可以參考下2014-04-04
SpringBoot整合Mybatis-Plus+Druid實現(xiàn)多數(shù)據(jù)源配置功能
本文主要講解springboot?+mybatisplus?+?druid?實現(xiàn)多數(shù)據(jù)源配置功能以及一些必要的準(zhǔn)備及代碼說明,具有一定的參考價值,感興趣的小伙伴可以借鑒一下2023-06-06
MyBatis-plus報錯Property ‘sqlSessionFactory‘ or 
這篇文章主要給大家介紹了MyBatis-plus 報錯 Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required的兩種解決方法,如果遇到相同問題的朋友可以參考借鑒一下2023-12-12
鎖超時發(fā)現(xiàn)parallelStream并行流線程上下文坑解決
這篇文章主要為大家介紹了鎖超時發(fā)現(xiàn)parallelStream并行流線程上下文坑解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08
SpringBoot中如何統(tǒng)一接口返回與全局異常處理詳解
全局異常處理是個比較重要的功能,一般在項目里都會用到,這篇文章主要給大家介紹了關(guān)于SpringBoot中如何統(tǒng)一接口返回與全局異常處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下2021-09-09
java中File類的三種創(chuàng)建文件夾方法總結(jié)
這篇文章主要給大家介紹了關(guān)于java中File類的三種創(chuàng)建文件夾方法,File類代表文件或目錄路徑名的抽象表達形式,通過File類提供的方法,我們可以很方便地創(chuàng)建文件夾,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-04-04

