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

SpringBoot與SpringMVC中參數(shù)傳遞的原理解析

 更新時(shí)間:2021年07月28日 10:47:51   作者:感謝一切給予  
這篇文章主要介紹了SpringBoot與SpringMVC中參數(shù)傳遞的原理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

一:普通參數(shù)與基本注解

HandlerMapping中找到能處理請(qǐng)求的Handler(Controller,method())
為當(dāng)前Handler找一個(gè)適配器HandlerAdapter:RequestMappingHandlerAdapter

在這里插入圖片描述

1.HandlerAdapter

在這里插入圖片描述

0-支持方法上標(biāo)注@RequestMapping
1-支持函數(shù)式編程的
xxxx

2.執(zhí)行目標(biāo)方法

在這里插入圖片描述
在這里插入圖片描述

3.參數(shù)解析器:確定要執(zhí)行的目標(biāo)方法每一個(gè)參數(shù)的值是什么

在這里插入圖片描述

在這里插入圖片描述

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

4.返回值處理器

在這里插入圖片描述

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

在這里插入圖片描述

請(qǐng)求進(jìn)來(lái)后, 首先從handlerMapping中查找是否有對(duì)應(yīng)的映射處理, 得到映射適配器Adapter,再通過(guò)適配器,查找有哪些方法匹配請(qǐng)求,首先判斷方法名,以及參數(shù)類型是否匹配,首先獲得方法中聲明的參數(shù)名字, 放到數(shù)組里,循環(huán)遍歷27種解析器判斷是否有支持處理對(duì)應(yīng)參數(shù)名字類型的解析器,如果有的話,根據(jù)名字進(jìn)行解析參數(shù),根據(jù)名字獲得域數(shù)據(jù)中的參數(shù), 循環(huán)每個(gè)參數(shù)名字進(jìn)行判斷, 從而為每個(gè)參數(shù)進(jìn)行賦值.

對(duì)于自定義的POJO類參數(shù):
ServletRequestMethodArgumentResolver 這個(gè)解析器用來(lái)解析: 是通過(guò)主要是通過(guò)判斷是否是簡(jiǎn)單類型得到的

@Override
	public 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 instance
			try {
				attribute = createAttribute(name, parameter, binderFactory, webRequest);
			}
			catch (BindException ex) {
				if (isBindExceptionRequired(parameter)) {
					// No BindingResult parameter -> fail with BindException
					throw ex;
				}
				// Otherwise, expose null/empty value and associated BindingResult
				if (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.Optional
			if (!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 model
		Map<String, Object> bindingResultModel = bindingResult.getModel();
		mavContainer.removeAttributes(bindingResultModel);
		mavContainer.addAllAttributes(bindingResultModel);

		return attribute;
	}

WebDataBinder binder =binderFactory.createBinder(webRequest,attribute,name)
WebDataBinder:web數(shù)據(jù)綁定器,將請(qǐng)求參數(shù)的值綁定到指定的javaBean里面
WebDataBinder 利用它里面的Converters將請(qǐng)求數(shù)據(jù)轉(zhuǎn)成指定的數(shù)據(jù)類型,通過(guò)反射一系列操作,再次封裝到j(luò)avabean中

GenericConversionService:在設(shè)置每一個(gè)值的時(shí)候,找它里面所有的converter哪個(gè)可以將這個(gè)數(shù)據(jù)類型(request帶來(lái)參數(shù)的字符串)轉(zhuǎn)換到指定的類型(javabean—某一個(gè)類型)

在這里插入圖片描述
在這里插入圖片描述

未來(lái)我們可以給WebDataBinder里面放自己的Converter

private static final class StringToNumber implements Converter<String, T> {

converter總接口:
@FunctionalInterface
public interface Converter<S, T> {

//自定義轉(zhuǎn)換器:實(shí)現(xiàn)按照自己的規(guī)則給相應(yīng)對(duì)象賦值

@Override
    public void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new Converter<String, Pet>() {
                @Override
                public 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;
                }
            });
    }

二:復(fù)雜參數(shù)

Map/Model(map/model里面的數(shù)據(jù)會(huì)被放在request的請(qǐng)求域 相當(dāng)于request.setAttribute)/Errors/BindingResult/RedirectAttributes(重定向攜帶數(shù)據(jù))/ServletRespons().SessionStaus.UriComponentsBuilder

6.在上面第五步目標(biāo)方法執(zhí)行完成后:
將所有的數(shù)據(jù)都放在ModelAdnViewContainer;包含要去的頁(yè)面地址View,還包含Model數(shù)據(jù)

在這里插入圖片描述

7.處理派發(fā)結(jié)果

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

在頁(yè)面進(jìn)行響應(yīng)前, 進(jìn)行視圖渲染的時(shí)候:
exposeModelAsRequestAttributes(model, request); 該方法將model中所有參數(shù)都放在請(qǐng)求域數(shù)據(jù)中

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);
		}
	}

通過(guò)循環(huán)遍歷model中的所有數(shù)據(jù)放在請(qǐng)求域中

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);
			}
		});
	}

不管我們?cè)诜椒ㄐ螀⑽恢梅?Map集合或者M(jìn)olde 最終在底層源碼都是同一個(gè)對(duì)象在mvcContainer容器中進(jìn)行保存

到此這篇關(guān)于SpringBoot與SpringMVC中參數(shù)傳遞的原理的文章就介紹到這了,更多相關(guān)SpringBoot SpringMVC參數(shù)傳遞內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于spring屬性占位符用法

    關(guān)于spring屬性占位符用法

    這篇文章主要介紹了關(guān)于spring屬性占位符用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 詳解Spring配置及事務(wù)的使用

    詳解Spring配置及事務(wù)的使用

    這篇文章主要介紹了詳解Spring配置及事務(wù)的使用,文中附含詳細(xì)的示例代碼說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-09-09
  • java對(duì)ArrayList排序代碼示例

    java對(duì)ArrayList排序代碼示例

    本文通過(guò)代碼示例給大家介紹java對(duì)arraylist排序,代碼簡(jiǎn)潔易懂,感興趣的朋友一起學(xué)習(xí)吧
    2015-11-11
  • Java練習(xí)之潛艇小游戲的實(shí)現(xiàn)

    Java練習(xí)之潛艇小游戲的實(shí)現(xiàn)

    這篇文章主要和大家分享一個(gè)Java小練習(xí)——利用Java編寫一個(gè)潛艇小游戲,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-03-03
  • pagehelper插件顯示total為-1或1的問(wèn)題

    pagehelper插件顯示total為-1或1的問(wèn)題

    這篇文章主要介紹了pagehelper插件顯示total為-1或1,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot創(chuàng)建自定義starter詳解

    SpringBoot創(chuàng)建自定義starter詳解

    這篇文章主要介紹了SpringBoot創(chuàng)建自定義starter詳解,Starter是Spring Boot中的一個(gè)非常重要的概念,Starter相當(dāng)于模塊,它能將模塊所需的依賴整合起來(lái)并對(duì)模塊內(nèi)的Bean根據(jù)環(huán)境(條件)進(jìn)行自動(dòng)配置,需要的朋友可以參考下
    2024-01-01
  • java中httpclient封裝post請(qǐng)求和get的請(qǐng)求實(shí)例

    java中httpclient封裝post請(qǐng)求和get的請(qǐng)求實(shí)例

    這篇文章主要介紹了java中httpclient封裝post請(qǐng)求和get的請(qǐng)求實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • JDK8接口的默認(rèn)與靜態(tài)方法-接口與抽象類的區(qū)別詳解

    JDK8接口的默認(rèn)與靜態(tài)方法-接口與抽象類的區(qū)別詳解

    這篇文章主要介紹了JDK8接口的默認(rèn)與靜態(tài)方法-接口與抽象類的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下
    2019-06-06
  • Java數(shù)據(jù)結(jié)構(gòu)之紅黑樹的原理及實(shí)現(xiàn)

    Java數(shù)據(jù)結(jié)構(gòu)之紅黑樹的原理及實(shí)現(xiàn)

    紅黑樹是一種特殊的二叉查找樹,每個(gè)結(jié)點(diǎn)都要儲(chǔ)存位表示結(jié)點(diǎn)的顏色,或紅或黑。本文將通過(guò)示例為大家詳細(xì)講講紅黑樹的原理及Java實(shí)現(xiàn),感興趣的可以了解一下
    2022-09-09
  • springboot內(nèi)嵌Tomcat安全漏洞修復(fù)方式

    springboot內(nèi)嵌Tomcat安全漏洞修復(fù)方式

    針對(duì)CVE-2020-1938漏洞,建議升級(jí)Tomcat至安全版本以避免受影響,影響版本包括:Apache Tomcat 9.x小于9.0.31、Apache Tomcat 8.x小于8.5.51、Apache Tomcat 7.x小于7.0.100及Apache Tomcat 6.x,
    2024-10-10

最新評(píng)論

仙游县| 依兰县| 墨江| 嘉峪关市| 达尔| 新宁县| 通河县| 屯留县| 屯留县| 平乐县| 永城市| 汪清县| 广灵县| 芦山县| 英超| 金昌市| 独山县| 灵川县| 观塘区| 黎川县| 清远市| 黎川县| 唐海县| 汉源县| 通海县| 烟台市| 界首市| 渝北区| 遵化市| 城固县| 彩票| 建德市| 宁远县| 天气| 贵州省| 静乐县| 沽源县| 黄大仙区| 乌兰浩特市| 休宁县| 胶州市|