成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

SpringBoot與SpringMVC中參數傳遞的原理解析

瀏覽:6日期:2023-02-22 09:00:27
目錄一:普通參數與基本注解二:復雜參數一:普通參數與基本注解

HandlerMapping中找到能處理請求的Handler(Controller,method())為當前Handler找一個適配器HandlerAdapter:RequestMappingHandlerAdapter

SpringBoot與SpringMVC中參數傳遞的原理解析

1.HandlerAdapter

SpringBoot與SpringMVC中參數傳遞的原理解析

0-支持方法上標注@RequestMapping1-支持函數式編程的xxxx

2.執行目標方法

SpringBoot與SpringMVC中參數傳遞的原理解析SpringBoot與SpringMVC中參數傳遞的原理解析

3.參數解析器:確定要執行的目標方法每一個參數的值是什么

SpringBoot與SpringMVC中參數傳遞的原理解析

SpringBoot與SpringMVC中參數傳遞的原理解析

boolean supportsParameter(MethodParameter parameter);Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,先判斷是否支持該參數類型, 如果支持, 就調用resolveArgument解析方法

4.返回值處理器

SpringBoot與SpringMVC中參數傳遞的原理解析

5.挨個判斷所有參數解析器哪個支持這個參數:HandlerMethodArgumentResolver: 把控著支持的方法參數類型

SpringBoot與SpringMVC中參數傳遞的原理解析

請求進來后, 首先從handlerMapping中查找是否有對應的映射處理, 得到映射適配器Adapter,再通過適配器,查找有哪些方法匹配請求,首先判斷方法名,以及參數類型是否匹配,首先獲得方法中聲明的參數名字, 放到數組里,循環遍歷27種解析器判斷是否有支持處理對應參數名字類型的解析器,如果有的話,根據名字進行解析參數,根據名字獲得域數據中的參數, 循環每個參數名字進行判斷, 從而為每個參數進行賦值.

對于自定義的POJO類參數:ServletRequestMethodArgumentResolver 這個解析器用來解析: 是通過主要是通過判斷是否是簡單類型得到的

@Overridepublic boolean supportsParameter(MethodParameter parameter) {return (parameter.hasParameterAnnotation(ModelAttribute.class) ||(this.annotationNotRequired && !BeanUtils.isSimpleProperty(parameter.getParameterType())));}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));}public final Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {Assert.state(mavContainer != null, 'ModelAttributeMethodProcessor requires ModelAndViewContainer');Assert.state(binderFactory != null, 'ModelAttributeMethodProcessor requires WebDataBinderFactory');String name = ModelFactory.getNameForParameter(parameter);ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);if (ann != null) {mavContainer.setBinding(name, ann.binding());}Object attribute = null;BindingResult bindingResult = null;if (mavContainer.containsAttribute(name)) {attribute = mavContainer.getModel().get(name);}else {// Create attribute instancetry {attribute = createAttribute(name, parameter, binderFactory, webRequest);}catch (BindException ex) {if (isBindExceptionRequired(parameter)) {// No BindingResult parameter -> fail with BindExceptionthrow ex;}// Otherwise, expose null/empty value and associated BindingResultif (parameter.getParameterType() == Optional.class) {attribute = Optional.empty();}else {attribute = ex.getTarget();}bindingResult = ex.getBindingResult();}}if (bindingResult == null) {// Bean property binding and validation;// skipped in case of binding failure on construction.WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);if (binder.getTarget() != null) {if (!mavContainer.isBindingDisabled(name)) {bindRequestParameters(binder, webRequest);}validateIfApplicable(binder, parameter);if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {throw new BindException(binder.getBindingResult());}}// Value type adaptation, also covering java.util.Optionalif (!parameter.getParameterType().isInstance(attribute)) {attribute = binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);}bindingResult = binder.getBindingResult();}// Add resolved attribute and BindingResult at the end of the modelMap<String, Object> bindingResultModel = bindingResult.getModel();mavContainer.removeAttributes(bindingResultModel);mavContainer.addAllAttributes(bindingResultModel);return attribute;}

WebDataBinder binder =binderFactory.createBinder(webRequest,attribute,name)WebDataBinder:web數據綁定器,將請求參數的值綁定到指定的javaBean里面WebDataBinder 利用它里面的Converters將請求數據轉成指定的數據類型,通過反射一系列操作,再次封裝到javabean中

GenericConversionService:在設置每一個值的時候,找它里面所有的converter哪個可以將這個數據類型(request帶來參數的字符串)轉換到指定的類型(javabean—某一個類型)

SpringBoot與SpringMVC中參數傳遞的原理解析SpringBoot與SpringMVC中參數傳遞的原理解析

未來我們可以給WebDataBinder里面放自己的Converter

private static final class StringToNumber implements Converter<String, T> {converter總接口:@FunctionalInterfacepublic interface Converter<S, T> {

//自定義轉換器:實現按照自己的規則給相應對象賦值

@Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new Converter<String, Pet>() {@Overridepublic Pet convert(String source) { if (!StringUtils.isEmpty(source)){Pet pet = new Pet();String[] split = source.split(',');pet.setName(split[0]);pet.setAge(split[1]);return pet; } return null;} }); }二:復雜參數

Map/Model(map/model里面的數據會被放在request的請求域 相當于request.setAttribute)/Errors/BindingResult/RedirectAttributes(重定向攜帶數據)/ServletRespons().SessionStaus.UriComponentsBuilder

6.在上面第五步目標方法執行完成后:將所有的數據都放在ModelAdnViewContainer;包含要去的頁面地址View,還包含Model數據

SpringBoot與SpringMVC中參數傳遞的原理解析

7.處理派發結果

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

在頁面進行響應前, 進行視圖渲染的時候:exposeModelAsRequestAttributes(model, request); 該方法將model中所有參數都放在請求域數據中

protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {// Expose the model object as request attributes.exposeModelAsRequestAttributes(model, request);// Expose helpers as request attributes, if any.exposeHelpers(request);// Determine the path for the request dispatcher.String dispatcherPath = prepareForRendering(request, response);// Obtain a RequestDispatcher for the target resource (typically a JSP).RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);if (rd == null) {throw new ServletException('Could not get RequestDispatcher for [' + getUrl() +']: Check that the corresponding file exists within your web application archive!');}// If already included or response already committed, perform include, else forward.if (useInclude(request, response)) {response.setContentType(getContentType());if (logger.isDebugEnabled()) {logger.debug('Including [' + getUrl() + ']');}rd.include(request, response);}else {// Note: The forwarded resource is supposed to determine the content type itself.if (logger.isDebugEnabled()) {logger.debug('Forwarding to [' + getUrl() + ']');}rd.forward(request, response);}}

通過循環遍歷model中的所有數據放在請求域中

protected void exposeModelAsRequestAttributes(Map<String, Object> model,HttpServletRequest request) throws Exception {model.forEach((name, value) -> {if (value != null) {request.setAttribute(name, value);}else {request.removeAttribute(name);}});}

不管我們在方法形參位置放 Map集合或者Molde 最終在底層源碼都是同一個對象在mvcContainer容器中進行保存

到此這篇關于SpringBoot與SpringMVC中參數傳遞的原理的文章就介紹到這了,更多相關SpringBoot SpringMVC參數傳遞內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
亚洲午夜三级在线| 欧美中文字幕一二三区视频| 国产欧美一区二区精品秋霞影院| 亚洲在线国产日韩欧美| 国产999精品久久| 国产精品少妇自拍| 欧美精品高清视频| 国产嫩草一区二区三区在线观看| 91日韩一区二区三区| 另类小说图片综合网| 亚洲综合免费观看高清完整版| 久久日韩粉嫩一区二区三区| 91精品视频网| 免费国产一区二区| 国产在线日韩| 成人午夜av影视| 韩国av一区二区| 婷婷丁香激情综合| 玉米视频成人免费看| 亚洲欧美一区二区在线观看| 久久久精品综合| 欧美第一区第二区| 在线成人免费视频| 在线欧美日韩精品| 亚洲一区二区三区高清| 伊人久久成人| 狠狠综合久久av一区二区老牛| 91浏览器打开| 国产精品综合在线视频| 麻豆91精品91久久久的内涵| 日本vs亚洲vs韩国一区三区二区| 午夜国产不卡在线观看视频| 亚洲成av人片| 亚洲综合小说图片| 亚洲18色成人| 一区二区三区免费看视频| 亚洲午夜免费电影| 日本 国产 欧美色综合| 久久国产欧美日韩精品| 国产精品一区二区久久精品爱涩 | 欧美在线观看禁18| 欧美亚洲尤物久久| 3atv在线一区二区三区| 欧美成人性福生活免费看| 欧美精品一区二区三区视频| 久久久www免费人成精品| 国产女同互慰高潮91漫画| 一区二区三区加勒比av| 日韩和的一区二区| 激情综合网最新| www.亚洲精品| 亚洲精品九九| 欧美人与性动xxxx| 精品福利在线导航| 国产精品黄色在线观看| 一区二区成人在线观看| 久久超碰97人人做人人爱| 成人av电影免费观看| 91久久久久| 欧美老人xxxx18| 中文字幕乱码久久午夜不卡 | 日韩一区二区三区在线| 一区二区三区四区精品在线视频| 久久精品亚洲乱码伦伦中文 | 欧美aaaaaa午夜精品| 久久超级碰视频| av不卡免费在线观看| 亚洲一区欧美激情| 日韩欧美一区电影| 丝袜美腿一区二区三区| 欧美一区1区三区3区公司| 老鸭窝亚洲一区二区三区| 欧美成人女星排名| 午夜精品久久久久久久久久| 欧美91福利在线观看| 亚洲高清免费| 欧美男同性恋视频网站| 五月天丁香久久| 国产欧美一区二区三区另类精品 | 久久精品免费在线观看| 日韩福利电影在线| 亚洲精品自在在线观看| 精品国产乱码久久| 国产在线乱码一区二区三区| 国产女优一区| 亚洲一区二区三区四区中文字幕| 91免费小视频| 色综合色狠狠综合色| 欧美偷拍一区二区| 国产在线精品免费| 久久久一区二区三区捆绑**| 91在线国产福利| 精品久久久久久久久久久久久久久 | 久久久一区二区三区| 国产一区二区福利视频| 色婷婷精品大在线视频| 亚洲网友自拍偷拍| 国产欧美一区二区色老头| 亚洲香蕉伊在人在线观| 国产毛片久久| 亚洲视频一区二区免费在线观看| 成人美女视频在线观看| 亚洲精品一区二区三区蜜桃下载| 99精品视频在线免费观看| ww久久中文字幕| 欧美高清不卡| 亚洲影院免费观看| 午夜一区不卡| 日韩中文字幕91| 欧美日韩一区高清| 国产精品中文有码| 亚洲精品在线免费观看视频| aaa亚洲精品| 亚洲欧洲精品一区二区精品久久久| 91麻豆免费观看| 亚洲人成网站色在线观看| 亚洲视频二区| 国产资源在线一区| 欧美激情在线一区二区| 国产精品视频| 日本va欧美va欧美va精品| 欧美成人伊人久久综合网| 亚洲精品一区二区三区蜜桃久| 日本欧美加勒比视频| 日韩欧美一级二级| 九九精品一区二区| 欧美美女一区二区三区| 国产精品911| 久久精品在这里| 欧美在线黄色| 亚洲精品国产一区二区精华液| 亚洲免费激情| 麻豆免费精品视频| 91精品国产91久久久久久一区二区| 成人性生交大合| 亚洲视频免费在线观看| 美女诱惑黄网站一区| 成人免费视频国产在线观看| 国产精品进线69影院| 日本大香伊一区二区三区| 成人网男人的天堂| 亚洲精品自拍动漫在线| 欧美日韩色综合| 93久久精品日日躁夜夜躁欧美| 中文字幕av一区二区三区| 亚洲欧美日韩另类精品一区二区三区| 国产综合久久久久久久久久久久| 国产亚洲精品bt天堂精选| 久久人人97超碰国产公开结果| 风流少妇一区二区| 夜夜揉揉日日人人青青一国产精品 | 青娱乐精品视频| 欧美成人性福生活免费看| 99精品欧美一区二区三区| 国产又粗又猛又爽又黄91精品| 久久综合九色欧美综合狠狠| 在线成人黄色| 风间由美中文字幕在线看视频国产欧美 | 中文高清一区| 粉嫩嫩av羞羞动漫久久久| 一区二区三区在线免费视频| 欧美色精品天天在线观看视频| 激情一区二区| 丁香桃色午夜亚洲一区二区三区| 亚洲精品国产精华液| 精品国产sm最大网站免费看| 久久青青草综合| 黄页网站一区| 成人精品视频一区二区三区 | 亚洲一区二区三区四区中文字幕| 日韩亚洲国产中文字幕欧美| 色哟哟国产精品| 影音先锋在线一区| 91性感美女视频| 国产成人无遮挡在线视频| 丝袜诱惑亚洲看片| 亚洲人精品午夜| 亚洲精品一区二区三区四区高清| 久久看片网站| 中文一区在线| 欧美性色综合| 99久久婷婷国产综合精品电影| 久久电影网站中文字幕| 五月激情综合网| 亚洲狠狠丁香婷婷综合久久久| 国产精品美女视频| 久久久亚洲精品石原莉奈| 精品久久久久一区| 日韩免费一区二区| 日韩一级大片在线| 日韩免费电影一区| 精品播放一区二区| 日韩一级免费一区| 欧美日韩另类国产亚洲欧美一级| 久久精品一区| 久久午夜av| 欧美午夜电影一区| 欧美亚洲国产一区在线观看网站 | 一区二区久久| 国产日韩欧美高清免费|