欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

深入理解SpringMVC參數(shù)解析器

這篇文章主要講解了“深入理解SpringMVC參數(shù)解析器”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“深入理解SpringMVC參數(shù)解析器”吧!

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:域名與空間、網(wǎng)站空間、營銷軟件、網(wǎng)站建設、富裕網(wǎng)站維護、網(wǎng)站推廣。

1.參數(shù)解析器

HandlerMethodArgumentResolver  就是我們口口聲聲說的參數(shù)解析器,它的實現(xiàn)類還是蠻多的,因為每一種類型的參數(shù)都對應了一個參數(shù)解析器:

深入理解SpringMVC參數(shù)解析器

為了理解方便,我們可以將這些參數(shù)解析器分為四大類:

  • xxxMethodArgumentResolver:這就是一個普通的參數(shù)解析器。

  • xxxMethodProcessor:不僅可以當作參數(shù)解析器,還可以處理對應類型的返回值。

  • xxxAdapter:這種不做參數(shù)解析,僅僅用來作為 WebArgumentResolver 類型的參數(shù)解析器的適配器。

  • HandlerMethodArgumentResolverComposite:這個看名字就知道是一個組合解析器,它是一個代理,具體代理其他干活的那些參數(shù)解析器。

大致上可以分為這四類,其中最重要的當然就是前兩種了。

2.參數(shù)解析器概覽

接下來我們來先來大概看看這些參數(shù)解析器分別都是用來干什么的。

MapMethodProcessor

這個用來處理 Map/ModelMap 類型的參數(shù),解析完成后返回 model。

PathVariableMethodArgumentResolver

這個用來處理使用了 @PathVariable 注解并且參數(shù)類型不為 Map 的參數(shù),參數(shù)類型為 Map 則使用  PathVariableMapMethodArgumentResolver 來處理。

PathVariableMapMethodArgumentResolver

見上。

ErrorsMethodArgumentResolver

這個用來處理 Error 參數(shù),例如我們做參數(shù)校驗時的 BindingResult。

AbstractNamedValueMethodArgumentResolver

這個用來處理 key/value 類型的參數(shù),如請求頭參數(shù)、使用了 @PathVariable 注解的參數(shù)以及 Cookie 等。

RequestHeaderMethodArgumentResolver

這個用來處理使用了 @RequestHeader 注解,并且參數(shù)類型不是 Map 的參數(shù)(參數(shù)類型是 Map 的使用  RequestHeaderMapMethodArgumentResolver)。

RequestHeaderMapMethodArgumentResolver

見上。

RequestAttributeMethodArgumentResolver

這個用來處理使用了 @RequestAttribute 注解的參數(shù)。

RequestParamMethodArgumentResolver

這個功能就比較廣了。使用了 @RequestParam 注解的參數(shù)、文件上傳的類型  MultipartFile、或者一些沒有使用任何注解的基本類型(Long、Integer)以及 String 等,都使用該參數(shù)解析器處理。需要注意的是,如果  @RequestParam 注解的參數(shù)類型是 Map,則該注解必須有 name 值,否則解析將由  RequestParamMapMethodArgumentResolver 完成。

RequestParamMapMethodArgumentResolver

見上。

AbstractCookieValueMethodArgumentResolver

這個是一個父類,處理使用了 @CookieValue 注解的參數(shù)。

ServletCookieValueMethodArgumentResolver

這個處理使用了 @CookieValue 注解的參數(shù)。

MatrixVariableMethodArgumentResolver

這個處理使用了 @MatrixVariable 注解并且參數(shù)類型不是 Map 的參數(shù),如果參數(shù)類型是 Map,則使用  MatrixVariableMapMethodArgumentResolver 來處理。

MatrixVariableMapMethodArgumentResolver

見上。

SessionAttributeMethodArgumentResolver

這個用來處理使用了 @SessionAttribute 注解的參數(shù)。

ExpressionValueMethodArgumentResolver

這個用來處理使用了 @Value 注解的參數(shù)。

ServletResponseMethodArgumentResolver

這個用來處理 ServletResponse、OutputStream 以及 Writer 類型的參數(shù)。

ModelMethodProcessor

這個用來處理 Model 類型參數(shù),并返回 model。

ModelAttributeMethodProcessor

這個用來處理使用了 @ModelAttribute 注解的參數(shù)。

SessionStatusMethodArgumentResolver

這個用來處理 SessionStatus 類型的參數(shù)。

PrincipalMethodArgumentResolver

這個用來處理 Principal 類型參數(shù),這個松哥在前面的文章中和大家介紹過了(SpringBoot 中如何自定義參數(shù)解析器?)。

AbstractMessageConverterMethodArgumentResolver

這是一個父類,當使用 HttpMessageConverter 解析 requestbody 類型參數(shù)時,相關的處理類都會繼承自它。

RequestPartMethodArgumentResolver

這個用來處理使用了 @RequestPart 注解、MultipartFile 以及 Part 類型的參數(shù)。

AbstractMessageConverterMethodProcessor

這是一個工具類,不承擔參數(shù)解析任務。

RequestResponseBodyMethodProcessor

這個用來處理添加了 @RequestBody 注解的參數(shù)。

HttpEntityMethodProcessor

這個用來處理 HttpEntity 和 RequestEntity 類型的參數(shù)。

ContinuationHandlerMethodArgumentResolver

AbstractWebArgumentResolverAdapter

這種不做參數(shù)解析,僅僅用來作為 WebArgumentResolver 類型的參數(shù)解析器的適配器。

ServletWebArgumentResolverAdapter

這個給父類提供 request。

UriComponentsBuilderMethodArgumentResolver

這個用來處理 UriComponentsBuilder 類型的參數(shù)。

ServletRequestMethodArgumentResolver

這個用來處理  WebRequest、ServletRequest、MultipartRequest、HttpSession、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId  類型的參數(shù)。

HandlerMethodArgumentResolverComposite

這個看名字就知道是一個組合解析器,它是一個代理,具體代理其他干活的那些參數(shù)解析器。

RedirectAttributesMethodArgumentResolver

這個用來處理 RedirectAttributes 類型的參數(shù),RedirectAttributes 松哥在之前的文章中和大家介紹過:SpringMVC  中的參數(shù)還能這么傳遞?漲姿勢了!。

好了,各個參數(shù)解析器的大致功能就給大家介紹完了,接下來我們選擇其中一種,來具體說說它的源碼。

3.AbstractNamedValueMethodArgumentResolver

AbstractNamedValueMethodArgumentResolver  是一個抽象類,一些鍵值對類型的參數(shù)解析器都是通過繼承它實現(xiàn)的,它里邊定義了很多這些鍵值對類型參數(shù)解析器的公共操作。

AbstractNamedValueMethodArgumentResolver 中也是應用了很多模版模式,例如它沒有實現(xiàn)  supportsParameter 方法,該方法的具體實現(xiàn)在不同的子類中,resolveArgument 方法它倒是實現(xiàn)了,我們一起來看下:

@Override @Nullable public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,   NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {  NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);  MethodParameter nestedParameter = parameter.nestedIfOptional();  Object resolvedName = resolveEmbeddedValuesAndExpressions(namedValueInfo.name);  if (resolvedName == null) {   throw new IllegalArgumentException(     "Specified name must not resolve to null: [" + namedValueInfo.name + "]");  }  Object arg = resolveName(resolvedName.toString(), nestedParameter, webRequest);  if (arg == null) {   if (namedValueInfo.defaultValue != null) {    arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);   }   else if (namedValueInfo.required && !nestedParameter.isOptional()) {    handleMissingValue(namedValueInfo.name, nestedParameter, webRequest);   }   arg = handleNullValue(namedValueInfo.name, arg, nestedParameter.getNestedParameterType());  }  else if ("".equals(arg) && namedValueInfo.defaultValue != null) {   arg = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);  }  if (binderFactory != null) {   WebDataBinder binder = binderFactory.createBinder(webRequest, null, namedValueInfo.name);   try {    arg = binder.convertIfNecessary(arg, parameter.getParameterType(), parameter);   }   catch (ConversionNotSupportedException ex) {    throw new MethodArgumentConversionNotSupportedException(arg, ex.getRequiredType(),      namedValueInfo.name, parameter, ex.getCause());   }   catch (TypeMismatchException ex) {    throw new MethodArgumentTypeMismatchException(arg, ex.getRequiredType(),      namedValueInfo.name, parameter, ex.getCause());   }   // Check for null value after conversion of incoming argument value   if (arg == null && namedValueInfo.defaultValue == null &&     namedValueInfo.required && !nestedParameter.isOptional()) {    handleMissingValue(namedValueInfo.name, nestedParameter, webRequest);   }  }  handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest);  return arg; }
  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術社區(qū)

  2. 首先根據(jù)當前請求獲取一個 NamedValueInfo  對象,這個對象中保存了參數(shù)的三個屬性:參數(shù)名、參數(shù)是否必須以及參數(shù)默認值。具體的獲取過程就是先去緩存中拿,緩存中如果有,就直接返回,緩存中如果沒有,則調(diào)用  createNamedValueInfo 方法去創(chuàng)建,將創(chuàng)建結(jié)果緩存起來并返回。createNamedValueInfo  方法是一個模版方法,具體的實現(xiàn)在子類中。

  3. 接下來處理 Optional 類型參數(shù)。

  4. resolveEmbeddedValuesAndExpressions 方法是為了處理注解中使用了 SpEL 表達式的情況,例如如下接口:

@GetMapping("/hello2") public void hello2(@RequestParam(value = "${aa.bb}") String name) {     System.out.println("name = " + name); }

參數(shù)名使用了表達式,那么 resolveEmbeddedValuesAndExpressions  方法的目的就是解析出表達式的值,如果沒用到表達式,那么該方法會將原參數(shù)原封不動返回。4. 接下來調(diào)用 resolveName  方法解析出參數(shù)的具體值,這個方法也是一個模版方法,具體的實現(xiàn)在子類中。5. 如果獲取到的參數(shù)值為  null,先去看注解中有沒有默認值,然后再去看參數(shù)值是否是必須的,如果是,則拋異常出來,否則就設置為 null 即可。6. 如果解析出來的參數(shù)值為空字符串  "",則也去 resolveEmbeddedValuesAndExpressions 方法中走一遭。7. 最后則是 WebDataBinder  的處理,解決一些全局參數(shù)的問題,WebDataBinder 松哥在之前的文章中也有介紹過,傳送門:@ControllerAdvice 的三種使用場景。

大致的流程就是這樣。

在這個流程中,我們看到主要有如下兩個方法是在子類中實現(xiàn)的:

  • createNamedValueInfo

  • resolveName

在加上 supportsParameter 方法,子類中一共有三個方法需要我們重點分析。

那么接下來我們就以 RequestParamMethodArgumentResolver 為例,來看下這三個方法。

4.RequestParamMethodArgumentResolver

4.1 supportsParameter

@Override public boolean supportsParameter(MethodParameter parameter) {  if (parameter.hasParameterAnnotation(RequestParam.class)) {   if (Map.class.isAssignableFrom(parameter.nestedIfOptional().getNestedParameterType())) {    RequestParam requestParam = parameter.getParameterAnnotation(RequestParam.class);    return (requestParam != null && StringUtils.hasText(requestParam.name()));   }   else {    return true;   }  }  else {   if (parameter.hasParameterAnnotation(RequestPart.class)) {    return false;   }   parameter = parameter.nestedIfOptional();   if (MultipartResolutionDelegate.isMultipartArgument(parameter)) {    return true;   }   else if (this.useDefaultResolution) {    return BeanUtils.isSimpleProperty(parameter.getNestedParameterType());   }   else {    return false;   }  } } public static boolean isSimpleProperty(Class<?> type) {  return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType())); } public static boolean isSimpleValueType(Class<?> type) {  return (Void.class != type && void.class != type &&    (ClassUtils.isPrimitiveOrWrapper(type) ||    Enum.class.isAssignableFrom(type) ||    CharSequence.class.isAssignableFrom(type) ||    Number.class.isAssignableFrom(type) ||    Date.class.isAssignableFrom(type) ||    Temporal.class.isAssignableFrom(type) ||    URI.class == type ||    URL.class == type ||    Locale.class == type ||    Class.class == type)); }

從 supportsParameter 方法中可以非常方便的看出支持的參數(shù)類型:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術社區(qū)

  2. 首先參數(shù)如果有 @RequestParam 注解的話,則分兩種情況:參數(shù)類型如果是 Map,則 @RequestParam 注解必須配置 name  屬性,否則不支持;如果參數(shù)類型不是 Map,則直接返回 true,表示總是支持(想想自己平時使用的時候是不是這樣)。

  3. 參數(shù)如果含有 @RequestPart 注解,則不支持。

  4. 檢查下是不是文件上傳請求,如果是,返回 true 表示支持。

  5. 如果前面都沒能返回,則使用默認的解決方案,判斷是不是簡單類型,主要就是 Void、枚舉、字符串、數(shù)字、日期等等。

  6. 這塊代碼其實很簡單,支持誰不支持誰,一目了然。

4.2 createNamedValueInfo

@Override protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {  RequestParam ann = parameter.getParameterAnnotation(RequestParam.class);  return (ann != null ? new RequestParamNamedValueInfo(ann) : new RequestParamNamedValueInfo()); } private static class RequestParamNamedValueInfo extends NamedValueInfo {  public RequestParamNamedValueInfo() {   super("", false, ValueConstants.DEFAULT_NONE);  }  public RequestParamNamedValueInfo(RequestParam annotation) {   super(annotation.name(), annotation.required(), annotation.defaultValue());  } }

獲取注解,讀取注解中的屬性,構(gòu)造 RequestParamNamedValueInfo 對象返回。

4.3 resolveName

@Override @Nullable protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {  HttpServletRequest servletRequest = request.getNativeRequest(HttpServletRequest.class);  if (servletRequest != null) {   Object mpArg = MultipartResolutionDelegate.resolveMultipartArgument(name, parameter, servletRequest);   if (mpArg != MultipartResolutionDelegate.UNRESOLVABLE) {    return mpArg;   }  }  Object arg = null;  MultipartRequest multipartRequest = request.getNativeRequest(MultipartRequest.class);  if (multipartRequest != null) {   List<MultipartFile> files = multipartRequest.getFiles(name);   if (!files.isEmpty()) {    arg = (files.size() == 1 ? files.get(0) : files);   }  }  if (arg == null) {   String[] paramValues = request.getParameterValues(name);   if (paramValues != null) {    arg = (paramValues.length == 1 ? paramValues[0] : paramValues);   }  }  return arg; }

這個方法思路也比較清晰:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術社區(qū)

  2. 前面兩個 if 主要是為了處理文件上傳請求。

  3. 如果不是文件上傳請求,則調(diào)用 request.getParameterValues 方法取出參數(shù)返回即可。

整個過程還是比較 easy 的。小伙伴們可以在此基礎之上自行分析 PathVariableMethodArgumentResolver  的原理,也很容易。

感謝各位的閱讀,以上就是“深入理解SpringMVC參數(shù)解析器”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對深入理解SpringMVC參數(shù)解析器這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關知識點的文章,歡迎關注!

網(wǎng)頁標題:深入理解SpringMVC參數(shù)解析器
轉(zhuǎn)載來于:http://aaarwkj.com/article46/ipdehg.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設、微信公眾號企業(yè)建站、電子商務全網(wǎng)營銷推廣、網(wǎng)站收錄

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設計
日韩一区二区三区免费播放| 日韩中文字幕视频一区| 国产亚洲精品视频热| 亚洲天堂中文字幕麻豆| 熟女乱熟乱熟妇综合网二区| 好吊毛片一区二区三区| 国产欧美日韩精品一区| 日韩成人高清免费在线| 成人性生交视频免费看| 91av国产一区二区| 涩五月婷婷开心中文字幕| 五月婷婷av综合激情| 日韩一区二区三区免费播放| 日韩av网址在线免费观看| 国产精品午夜福利天堂| 国产精品盗摄一区二区三区| 色哟哟网站在线精品视频| 日韩av在线国产观看| 国产午夜在线影院一区二区| 欧美日韩免费爱爱视频| 亚洲精品一区二区三区不卡| 欧美精品成人在线一区| 青青草原免费在线观看| 国产又粗又长又大无遮挡| 国产真实精品对白又爽欧美| 99蜜桃臀成人美女视频| 日本一欧美一欧美一亚洲| av在线中文字幕乱码| 日韩毛片中文字幕在线观看| 中国的性生活黄片免费观看| 欧美日韩黄色人人小视频| 日韩成人在线视频观看| 毛茸茸的阴户在线观看| 欧美aⅴ精品一区二区三区| 久久夜色噜噜噜av一区| 在线观看亚洲激情av| 国产亚洲精品麻豆一区二区| 欧美高清在线观看视频| 精品亚洲一区二区在线| 少妇被啪出水在线视频| 精品一二三区在线天堂|