日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

springboot-springmvc请求参数获取与原理【长文预警,收藏慢啃】

發布時間:2025/3/19 c/c++ 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springboot-springmvc请求参数获取与原理【长文预警,收藏慢啃】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

一、參數注解

1.@PathVariable

2.@RequestHeader

3.@RequestParam

4.@CookieValue

5.@RequestBody

6.@RequestAttribute

7.@MatrixVariable

二、參數解析原理

1.DispatcherServlet類的doDispatch方法

2.HandlerAdapter

3.執行目標方法

4.參數解析器-HandlerMethodArgumentResolver

5.返回值處理器

三、使用Servlet API作為參數

1.使用

四、使用Servlet API作為參數原理

1.InvocableHandlerMethod的getMethodArgumentValues方法

2.HttpServletRequest作為參數的參數處理器

五、復雜參數的解析

1.使用

六、復雜參數解析原理

1.還是同樣會進入到以上的參數解析方法。

2.參數類型是Map

2.參數類型是Model

七、自定義對象參數

1.使用

八、自定義對象類型參數封裝原理

1.還是同樣會進入到以上的參數解析方法。

2.ServletModelAttributeMethodProcessor 參數處理器

3.Converters-數據類型轉換器

4.自定義Converter類型轉換器


一、參數注解

@PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@MatrixVariable、@CookieValue、@RequestBody、@RequestAttribute

import org.springframework.web.bind.annotation.*; import javax.servlet.http.Cookie; import java.util.HashMap; import java.util.List; import java.util.Map;@RestController public class ParameterTestController {/*** 數據綁定:頁面提交的請求數據(GET、POST)都可以和對象屬性進行綁定* @param person* @return*/@PostMapping("/saveuser")public Person saveuser(Person person){return person;}// car/2/owner/zhangsan@GetMapping("/car/{id}/owner/{username}")public Map<String,Object> getCar(@PathVariable("id") Integer id,@PathVariable("username") String name,@PathVariable Map<String,String> pv,@RequestHeader("User-Agent") String userAgent,@RequestHeader Map<String,String> header,@RequestParam("age") Integer age,@RequestParam("inters") List<String> inters,@RequestParam Map<String,String> params,@CookieValue("_ga") String _ga,@CookieValue("_ga") Cookie cookie){Map<String,Object> map = new HashMap<>();// map.put("id",id); // map.put("name",name); // map.put("pv",pv); // map.put("userAgent",userAgent); // map.put("headers",header);map.put("age",age);map.put("inters",inters);map.put("params",params);map.put("_ga",_ga);System.out.println(cookie.getName()+"===>"+cookie.getValue());return map;}@PostMapping("/save")public Map postMethod(@RequestBody String content){Map<String,Object> map = new HashMap<>();map.put("content",content);return map;}}

1.@PathVariable

(1) 獲取路徑變量的值。

@PathVariable("id") Integer id

@PathVariable("username") String name

(2)?獲取所有的路徑變量,必須使用Map<String,String>

@PathVariable Map<String,String> pv

2.@RequestHeader

(1)?獲取請求頭

@RequestHeader("User-Agent") String userAgent

(2)?獲取所有請求頭

@RequestHeader Map<String,String> header

3.@RequestParam

(1)?獲取請求參數xxxx?age=18&inters=games&inters=ball

@RequestParam("age") Integer age,

@RequestParam("inters") List<String> inters,

(2)?獲取所有請求參數

@RequestParam Map<String,String> params

4.@CookieValue

(1)?獲取某個cookie的值

@CookieValue("_ga") String _ga

(2)?獲取Cookie類型的cookie

@CookieValue("_ga") Cookie cookie

5.@RequestBody

只能用于post方式。

(1) @RequestBody String content

獲取請求體的內容

6.@RequestAttribute

獲取請求域中屬性的值。

(1)?第一種獲取轉發參數:

@RequestAttribute(value = "msg",required = false) String msg

@RequestAttribute(value = "code",required = false)Integer code

(2)?第二種獲取轉發參數

request.getAttribute("msg");

(3)?注意:

@RequestAttribute不可以用Map獲取所有的請求域的值。

Attribute更多用于設置值之后跳轉頁面,用el表達式獲取值。

@GetMapping("/goto") public String goToPage(HttpServletRequest request){request.setAttribute("msg","成功了...");request.setAttribute("code",200);return "forward:/success"; //轉發到 /success請求 }@ResponseBody @GetMapping("/success") public Map success(@RequestAttribute(value = "msg",required = false) String msg,@RequestAttribute(value = "code",required = false)Integer code,HttpServletRequest request){Object msg1 = request.getAttribute("msg");Map<String,Object> map = new HashMap<>();Object hello = request.getAttribute("hello");Object world = request.getAttribute("world");Object message = request.getAttribute("message");map.put("reqMethod_msg",msg1);map.put("annotation_msg",msg);map.put("hello",hello);map.put("world",world);map.put("message",message);return map; }

7.@MatrixVariable

矩陣變量

(1)?語法:?

請求路徑:/cars/sell;low=34;brand=byd,audi,yd

請求路徑:/cars/sell;low=34;brand=byd;brand=audi;brand=yd

請求路徑:/boss/1;age=20/2;age=10

(2)?使用

* SpringBoot默認是禁用了矩陣變量的功能

* 手動開啟:原理。對于路徑的處理。UrlPathHelper進行解析。removeSemicolonContent(移除分號內容)支持矩陣變量的。

*?矩陣變量必須有url路徑變量才能被解析。

(3)?開啟方式

①?第一種,重寫匹配規則

@Configuration(proxyBeanMethods = false) public class WebConfig implements WebMvcConfigurer {@Overridepublic void configurePathMatch(PathMatchConfigurer configurer) {UrlPathHelper urlPathHelper = new UrlPathHelper();// 設置為不移除分號“;”后面的內容。矩陣變量功能就可以生效urlPathHelper.setRemoveSemicolonContent(false);configurer.setUrlPathHelper(urlPathHelper);} }

②?第二種,直接在容器中添加組件

@Bean public WebMvcConfigurer webMvcConfigurer(){return new WebMvcConfigurer() {@Overridepublic void configurePathMatch(PathMatchConfigurer configurer) {UrlPathHelper urlPathHelper = new UrlPathHelper();// 設置為不移除分號“;”后面的內容。矩陣變量功能就可以生效urlPathHelper.setRemoveSemicolonContent(false);configurer.setUrlPathHelper(urlPathHelper);}}; }

(4)?使用代碼

// /cars/sell;low=34;brand=byd,audi,yd @GetMapping("/cars/{path}") public Map carsSell(@MatrixVariable("low") Integer low,@MatrixVariable("brand") List<String> brand,@PathVariable("path") String path){Map<String,Object> map = new HashMap<>();map.put("low",low); // 34map.put("brand",brand); // byd,audi,ydmap.put("path",path); // sellreturn map; }// /boss/1;age=20/2;age=10 @GetMapping("/boss/{bossId}/{empId}") public Map boss(@MatrixVariable(value = "age",pathVar = "bossId") Integer bossAge,@MatrixVariable(value = "age",pathVar = "empId") Integer empAge){Map<String,Object> map = new HashMap<>();map.put("bossAge",bossAge); // 20map.put("empAge",empAge); // 10return map; }

(5) 問題:做頁面開發,如果cookie被禁用了,如何獲取session?

解析:session是由每次請求攜帶的cookie中的jsessionid定位的,cookie被禁用了,就無法通過cookie查找到對應的session。

解決:使用矩陣變量,發起請求/xxx;jsessionid=xxxxx,把cookie的值使用矩陣變量的方式進行傳遞。

二、參數解析原理

springmvc處理邏輯參考博文:

springBoot-springMVC請求處理原理_A_art_xiang的博客-CSDN博客

參數解析也是從DispatcherServlet類的doDispatch方法開始研究。

1.DispatcherServlet類的doDispatch方法

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request;HandlerExecutionChain mappedHandler = null;boolean multipartRequestParsed = false;WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);try {ModelAndView mv = null;Exception dispatchException = null;try {processedRequest = checkMultipart(request);multipartRequestParsed = (processedRequest != request);// 找@RequestMapping注解注釋的方法,HandlerMapping中找到能處理請求的Handler(Controller.method())// Determine handler for the current request.mappedHandler = getHandler(processedRequest);if (mappedHandler == null) {noHandlerFound(processedRequest, response);return;}// 為當前Handler 找一個適配器 HandlerAdapter; RequestMappingHandlerAdapter// Determine handler adapter for the current request.HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());// Process last-modified header, if supported by the handler.String method = request.getMethod();boolean isGet = "GET".equals(method);if (isGet || "HEAD".equals(method)) {long lastModified = ha.getLastModified(request, mappedHandler.getHandler());if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}}if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}// 真正的執行目標方法// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());if (asyncManager.isConcurrentHandlingStarted()) {return;}applyDefaultViewName(processedRequest, mv);mappedHandler.applyPostHandle(processedRequest, response, mv);}catch (Exception ex) {dispatchException = ex;}catch (Throwable err) {// As of 4.3, we're processing Errors thrown from handler methods as well,// making them available for @ExceptionHandler methods and other scenarios.dispatchException = new NestedServletException("Handler dispatch failed", err);}processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);}catch (Exception ex) {triggerAfterCompletion(processedRequest, response, mappedHandler, ex);}catch (Throwable err) {triggerAfterCompletion(processedRequest, response, mappedHandler,new NestedServletException("Handler processing failed", err));}finally {if (asyncManager.isConcurrentHandlingStarted()) {// Instead of postHandle and afterCompletionif (mappedHandler != null) {mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);}}else {// Clean up any resources used by a multipart request.if (multipartRequestParsed) {cleanupMultipart(processedRequest);}}} }

2.HandlerAdapter

有四種處理器的適配器

?

RequestMappingHandlerAdapter支持方法上標注@RequestMapping。

HandlerFunctionAdapter支持函數式編程的。

等等 。

// org.springframework.web.servlet.DispatcherServlet#getHandlerAdapter protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {if (this.handlerAdapters != null) {for (HandlerAdapter adapter : this.handlerAdapters) {if (adapter.supports(handler)) {return adapter;}}}throw new ServletException("No adapter for handler [" + handler +"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }

3.執行目標方法

// Actually invoke the handler. //DispatcherServlet -- doDispatch中的 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 以上進去之后實際是執行的RequestMappingHandlerAdapter的handleInternal方法 // RequestMappingHandlerAdapter的handleInternal方法 @Override protected ModelAndView handleInternal(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ModelAndView mav;checkRequest(request);// Execute invokeHandlerMethod in synchronized block if required.if (this.synchronizeOnSession) {HttpSession session = request.getSession(false);if (session != null) {Object mutex = WebUtils.getSessionMutex(session);synchronized (mutex) { mav = invokeHandlerMethod(request, response, handlerMethod);}}else {// No HttpSession available -> no mutex necessarymav = invokeHandlerMethod(request, response, handlerMethod);}}else {// 真正的執行目標方法// No synchronization on session demanded at all...mav = invokeHandlerMethod(request, response, handlerMethod);}if (!response.containsHeader(HEADER_CACHE_CONTROL)) {if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);}else {prepareResponse(response);}}return mav; } // RequestMappingHandlerAdapter的invokeHandlerMethod方法 @Nullable protected ModelAndView invokeHandlerMethod(HttpServletRequest request,HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ServletWebRequest webRequest = new ServletWebRequest(request, response);try {WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);// 注冊參數解析器-argumentResolvers,有26個。if (this.argumentResolvers != null) {invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);}// 注冊返回值處理器if (this.returnValueHandlers != null) {invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);}invocableMethod.setDataBinderFactory(binderFactory);invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);ModelAndViewContainer mavContainer = new ModelAndViewContainer();mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));modelFactory.initModel(webRequest, mavContainer, invocableMethod);mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);asyncWebRequest.setTimeout(this.asyncRequestTimeout);WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);asyncManager.setTaskExecutor(this.taskExecutor);asyncManager.setAsyncWebRequest(asyncWebRequest);asyncManager.registerCallableInterceptors(this.callableInterceptors);asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);if (asyncManager.hasConcurrentResult()) {Object result = asyncManager.getConcurrentResult();mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];asyncManager.clearConcurrentResult();LogFormatUtils.traceDebug(logger, traceOn -> {String formatted = LogFormatUtils.formatValue(result, !traceOn);return "Resume with async result [" + formatted + "]";});invocableMethod = invocableMethod.wrapConcurrentResult(result);}// 真正執行目標方法invocableMethod.invokeAndHandle(webRequest, mavContainer);if (asyncManager.isConcurrentHandlingStarted()) {return null;}return getModelAndView(mavContainer, modelFactory, webRequest);}finally {webRequest.requestCompleted();} } // ServletInvocableHandlerMethod的invokeAndHandle方法 public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception {// 執行請求,真正的執行controller的目標方法Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);setResponseStatus(webRequest);if (returnValue == null) {if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {disableContentCachingIfNecessary(webRequest);mavContainer.setRequestHandled(true);return;}}else if (StringUtils.hasText(getResponseStatusReason())) {mavContainer.setRequestHandled(true);return;}mavContainer.setRequestHandled(false);Assert.state(this.returnValueHandlers != null, "No return value handlers");try {this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);}catch (Exception ex) {if (logger.isTraceEnabled()) {logger.trace(formatErrorForReturnValue(returnValue), ex);}throw ex;} } // InvocableHandlerMethod的invokeForRequest方法 @Nullable public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception {// 獲取方法所有參數的值Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);if (logger.isTraceEnabled()) {logger.trace("Arguments: " + Arrays.toString(args));}// 調用目標方法return doInvoke(args); } // InvocableHandlerMethod的getMethodArgumentValues方法,這才是如何確定目標方法每一個參數的值 protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception {// 獲取所有參數MethodParameter[] parameters = getMethodParameters();if (ObjectUtils.isEmpty(parameters)) {return EMPTY_ARGS;}Object[] args = new Object[parameters.length];// 遍歷所有參數for (int i = 0; i < parameters.length; i++) {MethodParameter parameter = parameters[i];parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);args[i] = findProvidedArgument(parameter, providedArgs); // 參數名字發現器if (args[i] != null) {continue;}if (!this.resolvers.supportsParameter(parameter)) { // 判斷所有26個參數解析器是否支持該參數類型throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));}try {// args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);}catch (Exception ex) {// Leave stack trace for later, exception may actually be resolved and handled...if (logger.isDebugEnabled()) {String exMsg = ex.getMessage();if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {logger.debug(formatArgumentError(parameter, exMsg));}}throw ex;}}return args; } // HandlerMethodArgumentResolverComposite的getArgumentResolver方法,挨個判斷所有參數解析器那個支持解析這個參數 @Nullable private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);if (result == null) {for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) {if (resolver.supportsParameter(parameter)) { // 判斷是否支持解析result = resolver;this.argumentResolverCache.put(parameter, result); // 緩存,第一次執行可能會慢,以后就會很快。break;}}}return result; }

4.參數解析器-HandlerMethodArgumentResolver

確定將要執行的目標方法的每一個參數的值是什么;

SpringMVC目標方法能寫多少種參數類型。取決于參數解析器。

(1)26個參數解析器

?(2)參數解析器實際是個接口

?

*?判斷當前解析器是否支持解析這種參數

* 支持就調用 resolveArgument

最終參數解析時,調用各自 HandlerMethodArgumentResolver 的 resolveArgument 方法即可

5.返回值處理器

有以下返回值可寫:

?

三、使用Servlet API作為參數

WebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId

1.使用

@GetMapping("/test") public String test(HttpServletRequest request){return "success"; }

四、使用Servlet API作為參數原理

1.InvocableHandlerMethod的getMethodArgumentValues方法

同上,也會來到InvocableHandlerMethod的getMethodArgumentValues方法,這才是如何確定目標方法每一個參數的值

// InvocableHandlerMethod的getMethodArgumentValues方法,這才是如何確定目標方法每一個參數的值 protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception {// 獲取所有參數MethodParameter[] parameters = getMethodParameters();if (ObjectUtils.isEmpty(parameters)) {return EMPTY_ARGS;}Object[] args = new Object[parameters.length];// 遍歷所有參數for (int i = 0; i < parameters.length; i++) {MethodParameter parameter = parameters[i];parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);args[i] = findProvidedArgument(parameter, providedArgs); // 參數名字發現器if (args[i] != null) {continue;}if (!this.resolvers.supportsParameter(parameter)) { // 判斷所有26個參數解析器是否支持該參數類型throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));}try {//args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);}catch (Exception ex) {// Leave stack trace for later, exception may actually be resolved and handled...if (logger.isDebugEnabled()) {String exMsg = ex.getMessage();if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {logger.debug(formatArgumentError(parameter, exMsg));}}throw ex;}}return args; } // HandlerMethodArgumentResolverComposite的getArgumentResolver方法,挨個判斷所有參數解析器那個支持解析這個參數 @Nullable private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);if (result == null) {for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) { // 循環判斷所有26個參數解析器是否支持該參數類型if (resolver.supportsParameter(parameter)) { // 判斷是否支持解析result = resolver;this.argumentResolverCache.put(parameter, result); // 緩存,第一次執行可能會慢,以后就會很快。break;}}}return result; }

2.HttpServletRequest作為參數的參數處理器

ServletRequestMethodArgumentResolver?解析以上的部分參數(WebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId)

@Override public boolean supportsParameter(MethodParameter parameter) {Class<?> paramType = parameter.getParameterType();return (WebRequest.class.isAssignableFrom(paramType) ||ServletRequest.class.isAssignableFrom(paramType) ||MultipartRequest.class.isAssignableFrom(paramType) ||HttpSession.class.isAssignableFrom(paramType) ||(pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) ||Principal.class.isAssignableFrom(paramType) ||InputStream.class.isAssignableFrom(paramType) ||Reader.class.isAssignableFrom(paramType) ||HttpMethod.class == paramType ||Locale.class == paramType ||TimeZone.class == paramType ||ZoneId.class == paramType); }@Override public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {Class<?> paramType = parameter.getParameterType();// WebRequest / NativeWebRequest / ServletWebRequestif (WebRequest.class.isAssignableFrom(paramType)) {if (!paramType.isInstance(webRequest)) {throw new IllegalStateException("Current request is not of type [" + paramType.getName() + "]: " + webRequest);}return webRequest;}// ServletRequest / HttpServletRequest / MultipartRequest / MultipartHttpServletRequestif (ServletRequest.class.isAssignableFrom(paramType) || MultipartRequest.class.isAssignableFrom(paramType)) {return resolveNativeRequest(webRequest, paramType);}// HttpServletRequest required for all further argument typesreturn resolveArgument(paramType, resolveNativeRequest(webRequest, HttpServletRequest.class)); }

五、復雜參數的解析

Map、Model(map、model里面的數據會被放在request的請求域 request.setAttribute)、Errors/BindingResult、RedirectAttributes( 重定向攜帶數據)、ServletResponse(response)、SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder

1.使用

@GetMapping("/params") public String testParam(Map<String,Object> map,Model model,HttpServletRequest request,HttpServletResponse response){map.put("hello","world666");model.addAttribute("world","hello666");request.setAttribute("message","HelloWorld");Cookie cookie = new Cookie("c1","v1");response.addCookie(cookie);return "forward:/success"; }@ResponseBody @GetMapping("/success") public Map success(HttpServletRequest request){Map<String,Object> map = new HashMap<>();Object hello = request.getAttribute("hello");Object world = request.getAttribute("world");Object message = request.getAttribute("message");map.put("hello",hello);map.put("world",world);map.put("message",message);return map; }

Map<String,Object> map,??Model model, HttpServletRequest request 都是可以給request域中放數據,可以使用request.getAttribute();獲取數據,也可以在頁面使用el表達式獲取。

六、復雜參數解析原理

1.還是同樣會進入到以上的參數解析方法。

2.參數類型是Map

會使用MapMethodProcessor參數解析器。

public class MapMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {// 判斷是否用該參數解析器解析@Overridepublic boolean supportsParameter(MethodParameter parameter) {return Map.class.isAssignableFrom(parameter.getParameterType()) &&parameter.getParameterAnnotations().length == 0;}// 解析@Override@Nullablepublic Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure");return mavContainer.getModel(); // 返回一個BindingAwareModelMap,既是Model 也是Map。} } // ModelAndViewContainer的getModel方法 public ModelMap getModel() {if (useDefaultModel()) {return this.defaultModel;}else {if (this.redirectModel == null) {this.redirectModel = new ModelMap();}return this.redirectModel;} }

?目標方法執行完成,將所有的數據都放在 ModelAndViewContainer;包含要去的頁面地址View。還包含Model數據。

@Nullable private ModelAndView getModelAndView(ModelAndViewContainer mavContainer,ModelFactory modelFactory, NativeWebRequest webRequest) throws Exception {modelFactory.updateModel(webRequest, mavContainer);if (mavContainer.isRequestHandled()) {return null;}ModelMap model = mavContainer.getModel();ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());if (!mavContainer.isViewReference()) {mav.setView((View) mavContainer.getView());}if (model instanceof RedirectAttributes) {Map<String, ?> flashAttributes = ((RedirectAttributes) model).getFlashAttributes();HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);if (request != null) {RequestContextUtils.getOutputFlashMap(request).putAll(flashAttributes);}}return mav; }

處理派發結果:

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); -> renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);InternalResourceView:視圖解析流程 @Override 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);} } protected void exposeModelAsRequestAttributes(Map<String, Object> model,HttpServletRequest request) throws Exception {//model中的所有數據遍歷挨個放在請求域中(在頁面跳轉之前)model.forEach((name, value) -> {if (value != null) {request.setAttribute(name, value);}else {request.removeAttribute(name);}}); }

2.參數類型是Model

會使用ModelMethodProcessor參數解析器。

public class ModelMethodProcessor implements HandlerMethodArgumentResolver, HandlerMethodReturnValueHandler {@Overridepublic boolean supportsParameter(MethodParameter parameter) {return Model.class.isAssignableFrom(parameter.getParameterType());}@Override@Nullablepublic Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure");return mavContainer.getModel(); // 跟Map參數一樣,也返回一個BindingAwareModelMap,既是Model 也是Map。} }

七、自定義對象參數

可以自動類型轉換與格式化,可以級聯封裝

1.使用

/** * 姓名: <input name="userName"/> <br/> * 年齡: <input name="age"/> <br/> * 生日: <input name="birth"/> <br/> * 寵物姓名:<input name="pet.name"/><br/> * 寵物年齡:<input name="pet.age"/> */ @Data public class Person {private String userName;private Integer age;private Date birth;private Pet pet; }@Data public class Pet {private String name;private String age; } /** * 數據綁定:頁面提交的請求數據(GET、POST)都可以和對象屬性進行綁定 */ @PostMapping("/saveuser") public Person saveuser(Person person){return person; }

八、自定義對象類型參數封裝原理

1.還是同樣會進入到以上的參數解析方法。

2.ServletModelAttributeMethodProcessor 參數處理器

自定義類型的參數,是用ServletModelAttributeMethodProcessor 參數處理器解析的。

// ModelAttributeMethodProcessor的supportsParameter方法(ServletModelAttributeMethodProcessor繼承ModelAttributeMethodProcessor) @Override public boolean supportsParameter(MethodParameter parameter) {return (parameter.hasParameterAnnotation(ModelAttribute.class) ||(this.annotationNotRequired && !BeanUtils.isSimpleProperty(parameter.getParameterType())));// 參數是不是簡單類型,自定義對象不是簡單類型 }// org.springframework.beans.BeanUtils#isSimpleProperty public static boolean isSimpleProperty(Class<?> type) {Assert.notNull(type, "'type' must not be null");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)); } // org.springframework.web.method.annotation.ModelAttributeMethodProcessor#resolveArgument @Override @Nullable 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();}bindingResult = ex.getBindingResult();}}if (bindingResult == null) {// Bean property binding and validation;// skipped in case of binding failure on construction.// attribute就是創建的空實體類對象(Person),webRequest就是原生的request請求。// WebDataBinder :web數據綁定器,將請求參數的值綁定到指定的JavaBean里面// WebDataBinder 利用它里面的 Converters 將請求數據轉成指定的數據類型。再次封裝到JavaBean中WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);if (binder.getTarget() != null) {if (!mavContainer.isBindingDisabled(name)) {// 關鍵一步,幫我們把請求里的數據綁定到Person對象,執行的是ServletModelAttributeMethodProcessor類的方法。// 綁定過程中,有使用到Converter類型轉換器,因為http都是string,如果對象有Integer等類型需要進行轉換。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; }

GenericConversionService類:在設置每一個值的時候,找它里面的所有converter那個可以將這個數據類型(request帶來參數的字符串)轉換到指定的類型(JavaBean -- Integer)(文件上傳:byte -- > file)

3.Converters-數據類型轉換器

WebDataBinder 利用它里面的 Converters 將請求數據轉成指定的數據類型。再次通過反射封裝到JavaBean中。

?

?

4.自定義Converter類型轉換器

未來我們可以給WebDataBinder里面放自己的Converter(T就是要轉換的類型);

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

(1)新需求:假設寵物輸入“貓,3”,就以“,”分割,前后參數分別綁定到Pet的name和age。

/** * 姓名: <input name="userName"/> <br/> * 年齡: <input name="age"/> <br/> * 生日: <input name="birth"/> <br/> * 寵物:<input name="pet"/> */ @Data public class Person {private String userName;private Integer age;private Date birth;private Pet pet; }@Data public class Pet {private String name;private String age; }

(2)定義config類

import com.cxf.model.Pet; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import org.springframework.format.FormatterRegistry; import org.springframework.util.StringUtils; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration(proxyBeanMethods = false) public class WebConfig{//WebMvcConfigurer定制化SpringMVC的功能@Beanpublic WebMvcConfigurer webMvcConfigurer(){return new WebMvcConfigurer() {@Overridepublic void addFormatters(FormatterRegistry registry) {// 添加一個String->Pet的類型轉換器registry.addConverter(new Converter<String, Pet>() {@Overridepublic Pet convert(String source) {// 貓,3if(!StringUtils.isEmpty(source)){Pet pet = new Pet();String[] split = source.split(",");pet.setName(split[0]);pet.setAge(Integer.parseInt(split[1]));return pet;}return null;}});}};} }

(3)測試一下

http://localhost:8080/person?userName=zhangsan&age=18&birth=1992/12/12&pet=mao,3

{"userName":"zhangsan","age":18,"birth":"1992-12-11T16:00:00.000+00:00","pet":{"name":"mao","age":3}}

總結

以上是生活随笔為你收集整理的springboot-springmvc请求参数获取与原理【长文预警,收藏慢啃】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

色综合久久久久综合体 | 尤物九九久久国产精品的分类 | 免费在线观看一级片 | 亚洲精品视频 | 日韩三级免费观看 | 国产成人三级一区二区在线观看一 | 日韩一三区 | 欧美日韩免费在线视频 | 日韩精品一卡 | 中文字幕在线第一页 | 狠狠狠狠狠色综合 | 精品国产乱码久久久久久1区二区 | 草久视频在线 | 极品久久久 | 色香天天 | 国产美女免费观看 | 久久久综合九色合综国产精品 | 性色大片在线观看 | 日韩一区二区三免费高清在线观看 | 亚洲第一区在线播放 | 国产精品国产毛片 | 国产一区二区三区网站 | 久久爱综合 | 欧美大片在线观看一区 | 久久国产精品99久久久久久老狼 | 亚洲精品一区二区精华 | 特级aaa毛片| 欧美最新另类人妖 | 欧美极品少妇xbxb性爽爽视频 | 99九九视频| 97视频一区| 久草久热| 国产日韩精品一区二区在线观看播放 | 久久黄网站 | 超碰97人人爱 | 97在线看| 91精品国产一区二区在线观看 | 日韩黄色在线 | 91精品国产乱码久久 | 在线三级播放 | 久久在线影院 | 亚洲区精品视频 | 波多野结衣综合网 | 欧美日韩国产成人 | 成人精品一区二区三区电影免费 | 一区二区三区视频 | 国产网站在线免费观看 | 伊人婷婷久久 | www.夜夜爽 | www.狠狠操.com | 69久久夜色精品国产69 | 黄色电影网站在线观看 | 久久久久国产精品免费 | 手机看片中文字幕 | 国产精品婷婷 | 91亚色视频 | 去干成人网 | 日韩av电影免费观看 | 婷婷中文字幕综合 | 国产又粗又硬又长又爽的视频 | 成人国产精品免费观看 | 国产精品成人一区二区 | 婷婷久久综合九色综合 | 久久99欧美 | 日韩欧美一区二区在线 | 色欧美综合 | 久久久色 | 亚洲一区久久 | 日韩伦理一区二区三区av在线 | 不卡国产视频 | 精品综合久久久 | 中文字幕一区二区三区在线观看 | 最近字幕在线观看第一季 | 色婷婷av国产精品 | 91麻豆精品国产午夜天堂 | 亚洲精品午夜久久久久久久久久久 | 开心综合网 | 99久久久久 | 美女久久久久久久久久久 | 99在线精品视频在线观看 | 色欧美综合 | 日韩免费在线观看视频 | adc在线观看| 亚洲最新在线 | 国产黄色片久久久 | 国产精品一区二区在线播放 | 欧美成人精品欧美一级乱黄 | 九九99| 毛片网在线 | 麻豆视传媒官网免费观看 | 国产一区私人高清影院 | 亚洲国产欧美在线人成大黄瓜 | 精品国产自 | 亚洲综合一区二区精品导航 | 日韩精品久久久免费观看夜色 | 国产精品久久久999 国产91九色视频 | 久久精品国产免费看久久精品 | 成人在线视频在线观看 | 成人在线视频在线观看 | 国产精品99久久久精品免费观看 | 欧美a级成人淫片免费看 | 色婷婷成人网 | 亚洲97在线| 高清一区二区三区av | 国产伦理久久精品久久久久_ | 99视频精品 | 欧美国产高清 | 亚洲mv大片欧洲mv大片免费 | 97视频在线看 | 欧美va天堂va视频va在线 | 日韩视频免费 | 午夜精品一区二区三区在线观看 | 久久久久久国产精品美女 | 国产成人1区 | 色偷偷av男人天堂 | 激情五月婷婷 | 天堂在线视频中文网 | 亚洲色图av | www.色com| 国产精品入口久久 | 日日干激情五月 | 免费日韩三级 | 亚洲精品毛片一级91精品 | 日韩天堂在线观看 | 国产69精品久久久久久 | 亚洲涩涩涩 | 欧美一二三视频 | 中文字幕视频网站 | 久久成人一区二区 | 久99久精品 | 韩国一区二区在线观看 | 日韩在线观看视频中文字幕 | 日韩啪啪小视频 | av国产在线观看 | 精品国产乱码 | 亚洲欧美少妇 | 亚洲春色综合另类校园电影 | 91精品久久久久久久久久入口 | 久久精品日产第一区二区三区乱码 | 亚洲精品福利视频 | 在线成人av| av观看在线观看 | 中文字幕在线乱 | 香蕉在线视频播放网站 | 欧美一二区在线 | 五月婷婷导航 | 成人国产精品一区 | 久久免费精品一区二区三区 | 97免费视频在线播放 | 亚洲天天在线日亚洲洲精 | www.久热| 免费色网站 | 五月天久久综合 | 中文字幕乱码日本亚洲一区二区 | 久久久久亚洲国产精品 | 日韩影片在线观看 | 国产精品视频资源 | 久草在线在线精品观看 | 亚洲3级| 成人动图 | 午夜丰满寂寞少妇精品 | 日韩欧美视频免费在线观看 | 亚洲成av片人久久久 | 91精品啪在线观看国产 | 美女国产精品 | 国产一二三在线视频 | 久久久久久久久久久久久久电影 | www亚洲国产 | 国产精品影音先锋 | 成人免费视频播放 | 亚洲精品在线观看中文字幕 | 国产精品国产三级国产专区53 | 国内小视频在线观看 | 中文字幕乱码亚洲精品一区 | 久久精品99国产 | 91看片淫黄大片91 | 免费看一级 | 手机在线看永久av片免费 | 亚洲电影影音先锋 | 国产老太婆免费交性大片 | 久久久国产精品一区二区中文 | 国产日韩精品在线 | 亚洲视频 中文字幕 | 国产精品一区二区三区观看 | 91av视频观看| 伊人久久在线观看 | 国产一二三精品 | 狠狠色2019综合网 | 国产伦理精品一区二区 | 久久久久久毛片精品免费不卡 | 人人爽人人爽人人爽学生一级 | 天天综合入口 | 午夜精品福利一区二区 | 91精品啪 | 日韩黄色av网站 | 国产91免费在线 | 97精品国产一二三产区 | 中文字幕在线观看资源 | 天天色天天干天天 | 亚洲在线免费视频 | 久久深爱网| 久久亚洲精品国产亚洲老地址 | av久久在线 | 成人免费网站在线观看 | 在线免费观看视频你懂的 | 国产精品网红福利 | 亚洲综合色激情五月 | 欧美日韩不卡在线视频 | 超碰99人人 | 久久黄色免费观看 | 91精品国产成人观看 | 最新日韩中文字幕 | 四虎成人精品在永久免费 | 毛片网站在线观看 | 久久国产精品精品国产色婷婷 | www日日夜夜 | 国产又黄又爽又猛视频日本 | se视频网址| 中文字幕资源站 | 热久久99这里有精品 | 黄色的网站免费看 | 日韩中文字幕视频在线观看 | 成人欧美一区二区三区黑人麻豆 | 日本久久精 | 西西大胆免费视频 | 日韩久久午夜一级啪啪 | 特级西西人体444是什么意思 | 国产一区电影在线观看 | 三级av在线免费观看 | 亚洲国产美女精品久久久久∴ | 96久久精品 | 狠狠干五月天 | 国产破处在线视频 | 国产精品人成电影在线观看 | 久久精品视频中文字幕 | 精品国产视频在线 | 国产精品一区免费看8c0m | 国产精品一区二区美女视频免费看 | 最近中文字幕免费 | 国产成人一区二区三区影院在线 | 久久久免费少妇 | 九九久久视频 | 久久国产99| 国产在线不卡 | 婷婷中文字幕在线观看 | 国产日韩欧美综合在线 | 99色亚洲| 国产精品av免费 | 91免费版在线观看 | 97人人射| 日韩色一区二区三区 | 探花视频在线版播放免费观看 | 天堂av在线中文在线 | 成人av一二三区 | 激情视频综合网 | 亚洲五月婷 | 日韩一区正在播放 | 国产96在线视频 | 超碰97网站 | 久久精品网站免费观看 | 人人天天夜夜 | 精品欧美一区二区三区久久久 | 亚洲午夜在线视频 | 久久久精品国产一区二区 | 亚洲h视频在线 | 日韩视频二区 | 欧美精品在线观看 | 五月婷婷在线视频观看 | 激情五月网站 | 看片网站黄色 | 久久亚洲专区 | 国产精品午夜av | 久久精品人人做人人综合老师 | 在线精品国产 | 日韩精品免费在线观看 | 激情视频一区二区三区 | 青青河边草免费观看完整版高清 | 伊香蕉大综综综合久久啪 | 在线v片免费观看视频 | 婷婷深爱网 | 99热在线观看 | 91成人在线观看高潮 | 99久久久久国产精品免费 | 午夜久久 | 狠狠色丁香婷婷综合久小说久 | 色无五月| 久久久久久久久毛片 | 久久久受www免费人成 | 国产视频一二三 | 日日夜夜精品免费 | 成人一级片免费看 | 亚洲精品9 | 日韩精品电影在线播放 | 二区三区精品 | 一区视频在线 | 久久精品欧美日韩精品 | 国产亚洲视频在线 | 日韩av中文在线 | 精品国产乱码久久久久久浪潮 | 天堂成人在线 | 精品视频在线免费观看 | 精品在线视频一区 | 91精品国产九九九久久久亚洲 | 国产精品1区2区3区在线观看 | 视频福利在线 | 免费日韩一区二区三区 | 欧美国产日韩一区 | 久久图| 韩国中文三级 | av在线短片 | 最近中文字幕视频完整版 | 午夜视频日本 | 国产在线无 | 亚a在线 | 久久婷婷国产色一区二区三区 | 丝袜少妇在线 | 亚洲国产av精品毛片鲁大师 | 狠狠的干狠狠的操 | 激情视频在线观看网址 | 中文av影院 | 日韩在线观看电影 | www欧美色 | 热99在线| 激情综合色图 | 久久久2o19精品| 在线亚洲高清视频 | 久久成人精品 | 在线看片中文字幕 | 五月天电影免费在线观看一区 | 免费观看黄色12片一级视频 | 国产精品va在线播放 | 国产看片免费 | 性色av一区二区 | a v在线观看 | 久久任你操 | 国产精品岛国久久久久久久久红粉 | 一区二区欧美在线观看 | 亚洲国产免费 | 91精品秘密在线观看 | 8x8x在线观看视频 | 永久免费的啪啪网站免费观看浪潮 | 日韩高清一区 | 亚洲国产小视频在线观看 | 午夜视频不卡 | 国产欧美综合视频 | 2019免费中文字幕 | 日本三级国产 | 国产又粗又猛又黄又爽 | 最新色站 | 九九热在线视频 | 亚洲精品视频观看 | 久精品一区| 精品毛片一区二区免费看 | 91麻豆精品国产 | 久草成人在线 | 成人久久18免费网站图片 | 99精品久久久久久久 | 麻豆国产露脸在线观看 | 成人午夜精品久久久久久久3d | 97超碰资源站| 亚洲天堂va | 日韩欧美一区二区三区在线 | 免费的国产精品 | 国产精品永久久久久久久久久 | 97国产一区| 玖草在线观看 | 大型av综合网站 | 日本久久久久久科技有限公司 | 欧美日韩免费一区二区 | 夜夜夜夜爽 | 欧美男男激情videos | 久久久精品成人 | 349k.cc看片app | 久久国产精品久久w女人spa | 婷婷视频导航 | 成人免费在线视频 | 在线看的av网站 | 伊人天堂久久 | 天堂中文在线播放 | 一本色道久久综合亚洲二区三区 | 中文字幕一区二区三区四区视频 | 久久中文字幕在线视频 | 亚洲伦理一区 | se视频网址 | 亚洲精品www久久久久久 | 国产精品国产三级在线专区 | 国产高清精 | 色网站视频 | 久久久久久国产精品亚洲78 | 91麻豆精品国产午夜天堂 | 国产精品久久久久久久久久白浆 | 六月婷操 | 在线韩国电影免费观影完整版 | 色综合久久久久久久久五月 | av在线小说 | 久久精品视频国产 | 成在人线av | 999久久久精品视频 日韩高清www | 色就是色综合 | 久久久久久麻豆 | 久久综合九色综合97婷婷女人 | 午夜在线免费观看 | 不卡视频一区二区三区 | 综合激情婷婷 | 黄色大片免费播放 | 欧美一区三区四区 | 日韩成人精品在线观看 | 午夜婷婷在线观看 | 欧美在线视频精品 | 日韩中出在线 | 极品嫩模被强到高潮呻吟91 | 国产艹b视频 | 成人aⅴ视频 | 一区二区三区韩国免费中文网站 | 97国产精品亚洲精品 | 久久久久久久久国产 | 亚洲综合欧美日韩狠狠色 | 国产 在线 高清 精品 | 天堂中文在线播放 | 天天操·夜夜操 | 欧美日本啪啪无遮挡网站 | 国产精品久久久久一区 | 综合亚洲视频 | 亚洲精品午夜国产va久久成人 | 亚洲精品一区二区在线观看 | 亚洲精品免费在线视频 | 欧美一级裸体视频 | 国产无限资源在线观看 | 中文字幕在线观看完整版电影 | 日韩综合第一页 | 在线观看国产91 | 日韩精品一区二区三区外面 | 精品在线你懂的 | 黄色片免费电影 | 免费在线观看一区二区三区 | 激情久久久久 | 亚洲精品电影在线 | 亚洲日本成人网 | 人人射人人爽 | 911精品美国片911久久久 | 成人久久久精品国产乱码一区二区 | 久久久久久毛片精品免费不卡 | 中文日韩在线视频 | 91片网 | 日韩欧美视频免费看 | 在线影院 国内精品 | 国产麻豆剧传媒免费观看 | 91精品专区| 98福利在线 | 午夜久久精品 | 国产一区免费在线 | 特片网久久 | 91久久在线观看 | 日韩在线电影观看 | 国产在线观看地址 | 日本久久影视 | 天天插天天爱 | av三级av| 欧美日韩精品久久久 | 久久久亚洲精品 | 91在线看视频免费 | 天天插天天爱 | 国产精品普通话 | 久久精品看片 | 超碰在线个人 | 三上悠亚在线免费 | 日本不卡一区二区三区在线观看 | 亚洲黄网址| 国产中文字幕在线观看 | 人人爽人人乐 | 午夜美女福利 | 久产久精国产品 | 国产成人在线免费观看 | 蜜桃视频日韩 | 亚洲一级片免费观看 | 97精品国产97久久久久久免费 | 成人午夜在线观看 | 91日本在线播放 | 日日干天天爽 | 欧美日韩在线观看不卡 | 久久久免费精品视频 | 欧美久久久 | 99久久精品免费 | 91精品国产一区二区在线观看 | 亚洲色视频 | 在线观看国产日韩 | 国产人成看黄久久久久久久久 | 最新精品视频在线 | 精品乱码一区二区三四区 | 五月天综合激情 | 天堂素人在线 | 国产亚洲精品美女 | 久久久久久草 | 奇米网444| 久久99久久99精品中文字幕 | 久久伊人精品一区二区三区 | 国产精品一区免费在线观看 | 久久国产精品久久久 | 国产免费视频一区二区裸体 | 国产伦精品一区二区三区照片91 | 91看片在线 | 亚洲欧美一区二区三区孕妇写真 | 激情在线网站 | 综合亚洲视频 | 黄色美女免费网站 | 亚洲 综合 国产 精品 | 伊人久久av | 欧美另类视频 | mm1313亚洲精品国产 | 亚洲黄色区 | 国产精品久久99综合免费观看尤物 | 亚洲成人在线免费 | 国内免费久久久久久久久久久 | 亚洲区另类春色综合小说校园片 | 中国一级片在线观看 | 精品久久久久免费极品大片 | 91麻豆精品国产91久久久更新时间 | 九色福利视频 | 色激情在线| 欧美激情精品一区 | 一区二区三区免费看 | 成人一区二区在线 | 人人盈棋牌 | 色婷婷影视 | 久久国产精品免费一区二区三区 | 91视频 - x99av | 国产美女视频免费观看的网站 | 免费观看不卡av | 精品99免费视频 | 日日夜夜天天干 | 久久夜夜操 | 国产一区二区播放 | 国产精品99久久久久的智能播放 | 国产在线观看不卡 | 四虎在线视频 | 91av电影在线 | 久久久久99精品国产片 | 中文字幕精品一区二区精品 | 精品国模一区二区 | 五月天国产精品 | 日韩系列在线 | 亚洲欧洲国产日韩精品 | 91精品人成在线观看 | 欧美黄在线 | 色综合色综合久久综合频道88 | 亚洲第一区在线播放 | 久久综合久久久久88 | 欧美俄罗斯性视频 | 久久av在线播放 | 久久精品99国产精品日本 | 免费在线观看黄网站 | 在线播放国产一区二区三区 | 日韩色综合 | 久久在线| 深夜国产福利 | 丁香婷婷网 | 又色又爽的网站 | 九九热精品在线 | 色婷婷狠 | 在线v片| 97夜夜澡人人爽人人免费 | 一级黄色大片 | 国产在线 一区二区三区 | 一区在线免费观看 | 夜夜夜草| 激情av五月婷婷 | 精品久久久久久亚洲综合网站 | 超碰国产在线播放 | 国产免费视频一区二区裸体 | 蜜桃视频成人在线观看 | 夜色资源站国产www在线视频 | 黄网站色欧美视频 | 免费观看特级毛片 | 日本公妇色中文字幕 | 久久综合爱 | 欧美大香线蕉线伊人久久 | 黄色免费观看 | 毛片随便看 | 爱爱av在线 | 国产精品久久9 | 1024手机基地在线观看 | 999一区二区三区 | 午夜精品电影 | 亚州av一区| 97人人人人| 色婷婷av国产精品 | 四虎影视精品永久在线观看 | 精品黄色片 | 夜夜操狠狠干 | 九色最新网址 | 日韩av高清 | 精品久久久99 | 国产精品久久久久久久久久久免费 | 国产欧美综合在线观看 | 在线免费黄色av | 久久综合九色欧美综合狠狠 | 不卡的av片 | 一区二区三区精品在线视频 | 丁香婷婷激情网 | 中文字幕在线观看免费 | 在线看国产一区 | 黄色三级久久 | avav99| 欧美久久久久久久久久久 | 免费在线播放黄色 | 黄色在线观看污 | 国产亚洲精品电影 | 国产淫片 | 美国三级黄色大片 | 久久这里只有精品视频首页 | 人人澡人人爽欧一区 | 久久不见久久见免费影院 | 男女全黄一级一级高潮免费看 | 丁香婷婷激情 | 日韩av成人 | 国产一级在线观看视频 | 精品国产精品久久一区免费式 | 中文在线www | 亚洲 欧美 精品 | 免费看片网址 | 免费在线一区二区 | av一区二区三区在线观看 | 成人精品在线 | 丁香在线视频 | 99久久婷婷国产综合精品 | 视频在线观看国产 | 国产免费视频在线 | 二区精品视频 | 偷拍精偷拍精品欧洲亚洲网站 | 麻豆精品视频在线 | 久久久午夜精品理论片中文字幕 | 国产精品99久久久久久久久久久久 | 免费黄色在线网站 | 五月婷丁香网 | 欧美91视频| 久草9视频 | 嫩小bbbb摸bbb摸bbb | 亚洲精品玖玖玖av在线看 | 最近日韩免费视频 | 亚洲一区二区天堂 | 天天天插 | 一区二区三区在线视频观看58 | 日韩免费观看视频 | 国产资源免费 | 中文字幕专区高清在线观看 | 天天综合网久久 | 亚洲黄色在线免费观看 | 午夜久久成人 | 夜夜躁天天躁很躁波 | 天天色天天艹 | 精品国产一区二区三区不卡 | 国产视频久 | 九九热在线播放 | 成人网在线免费视频 | 探花视频在线观看免费版 | 国产精品2019 | 免费观看成人 | 四虎在线免费观看 | 日本久久片 | 免费久久99精品国产婷婷六月 | 不卡的av在线播放 | 91热在线 | 在线观看91精品视频 | 久久精品系列 | 久久国产精品偷 | 日韩精品免费在线观看 | 91视频在线播放视频 | 成人午夜影视 | 日韩高清在线观看 | 日本精品一二区 | 亚洲激情视频在线观看 | 亚洲国产成人精品久久 | 黄色毛片一级 | 丝袜美腿av | 国产欧美综合视频 | 国产精品99视频 | 成人香蕉视频 | 色就色,综合激情 | 国产精品久久婷婷六月丁香 | 日韩欧美精品在线视频 | 久久久久久久久久久福利 | 久久伊人五月天 | 91日韩在线专区 | 久久久久在线观看 | 在线国产欧美 | 在线观看av免费观看 | 日韩中文幕 | 日操操 | 久久免费视频7 | 欧美成人在线网站 | 日韩av一卡二卡三卡 | 97夜夜澡人人爽人人免费 | 欧美精品一区二区三区一线天视频 | 夜夜操狠狠操 | 日韩精品综合在线 | 亚洲精品九九 | 国产精品白虎 | 97视频在线观看成人 | 国产a精品| 色的网站在线观看 | 欧美日韩视频观看 | 国产一级电影网 | 国产精品久久久久久久久久免费看 | 国产日韩三级 | 国产麻豆精品传媒av国产下载 | 日韩在线色 | 久久精品久久精品久久精品 | 国产男女免费完整视频 | 欧美日韩成人 | 日韩电影黄色 | 永久免费看av| 狠狠操狠狠操 | 亚洲国产av精品毛片鲁大师 | www.狠狠色 | 五月天色中色 | 欧美一区二区三区特黄 | 国产午夜亚洲精品 | 国产黄色片在线免费观看 | 精品一区二区三区在线播放 | 日韩免费视频线观看 | 性色av免费看| 69久久99精品久久久久婷婷 | 国产成人综合图片 | 成人午夜电影在线 | av.com在线 | 免费亚洲视频在线观看 | 亚洲综合视频在线 | 激情欧美丁香 | 国产99久久久国产精品免费二区 | 五月婷婷综合激情网 | 欧美一级在线 | 色七七亚洲影院 | 黄色成人小视频 | 黄色日批网站 | 日韩免费一级电影 | 国产在线视频资源 | 中文永久免费观看 | 久久久久在线观看 | 天天爽天天爽天天爽 | 中文字幕免费在线看 | 三级动态视频在线观看 | 日本精品一区二区三区在线观看 | 久久免费国产电影 | 射射射综合网 | 久久精品欧美一区二区三区麻豆 | 丁香伊人网 | 国产高清无av久久 | 国产一级二级在线观看 | 国产成人一区二区三区免费看 | 色婷婷啪啪免费在线电影观看 | 丁香高清视频在线看看 | www成人精品 | 在线观看不卡的av | 96视频在线 | 精品美女在线视频 | 精品99久久久久久 | 国内精品久久久久久中文字幕 | 久久综合国产伦精品免费 | 成人久久毛片 | 521色香蕉网站在线观看 | 成年人在线观看 | 亚洲精品一区二区久 | av韩国在线| 精品主播网红福利资源观看 | 日韩欧美综合 | 欧美视频日韩 | 久久精品视频在线看 | 99九九热只有国产精品 | 青草视频在线播放 | 天天射天天干 | 狠狠色丁香久久综合网 | 久久久久电影网站 | 伊人婷婷激情 | 日韩激情精品 | 久久久穴 | 美女免费电影 | 久久看片网站 | 97国产精品 | 国产91av视频在线观看 | 亚洲精品乱码久久久久久蜜桃不爽 | 国产伦精品一区二区三区免费 | 亚洲1级片 | 99精品黄色片免费大全 | 日韩成人不卡 | 久久中文字幕导航 | 久久综合狠狠 | 2020天天干夜夜爽 | 国产美女免费 | 豆豆色资源网xfplay | 91亚洲精品国偷拍 | 九九久久影视 | 久久老司机精品视频 | 亚洲视频一区二区三区在线观看 | 色之综合网 | 九九在线高清精品视频 | 奇米网8888 | 五月激情姐姐 | 一区二区三区四区五区六区 | 婷婷久久综合网 | 中文字幕av日韩 | 精品久久久久久综合日本 | 69国产精品视频 | 日韩精品免费在线观看 | 91成人国产| 在线观看中文字幕一区二区 | 最新不卡av | 日韩av中文在线观看 | 日韩精品在线播放 | 天天爽天天爽天天爽 | 免费观看国产视频 | 国产香蕉97碰碰久久人人 | 天天操夜夜拍 | 狠狠伊人 | 成年人免费看 | 欧美日本在线视频 | 亚洲电影久久久 | 国产99一区视频免费 | 欧美一级性生活 | 国产精品成人在线观看 | 深夜国产福利 | 黄色小说视频在线 | 国产视频每日更新 | 久久免费成人精品视频 | 射九九 | 中文字幕在线免费播放 | 久久新视频 | 五月天婷婷免费视频 | 中文字幕一区二区三区乱码不卡 | 狠狠躁日日躁夜夜躁av | 天天操天天射天天添 | 午夜精品一区二区三区可下载 | 午夜99| 黄色成人毛片 | 精品人人人 | 久久艹在线 | 久久手机看片 | 日日夜夜操av | 亚洲h在线播放在线观看h | 日韩欧美视频一区二区三区 | 国产 色 | a√资源在线 | 国产伦理久久精品久久久久_ | 国产伦理久久 | 国产99久久精品 | 日韩欧美大片免费观看 | 五月婷婷伊人网 | 91精品推荐 | 国产精品资源网 | 999成人| 黄色大全视频 | 国内精品国产三级国产aⅴ久 | 久草视频在线播放 | 久久爱综合 | 亚洲精品国产精品乱码不99热 | 久久精品欧美视频 | 综合网欧美 | 免费合欢视频成人app | 国产精品手机在线 | 97精品超碰一区二区三区 | 97香蕉超级碰碰久久免费软件 | 日产乱码一二三区别免费 | 日韩欧美高清一区二区 | 国产裸体永久免费视频网站 | av天天干| 91正在播放 | 国产在线第三页 | 国产精彩视频一区二区 | 国产精品久久久久久久免费 | 久久免费国产精品1 | 美女一二三区 | 精品久久一区二区 | 国内外成人在线视频 | 高清在线一区 | 黄色app网站在线观看 | 亚洲在线| 一区二区三区手机在线观看 | 玖玖玖影院| 欧美日韩在线观看一区二区 | 国产精品亚洲人在线观看 | 天天操夜夜爱 | 欧美一级日韩免费不卡 | 午夜av片| 2024av| 久久99久久精品 | 国产中出在线观看 | 国产专区视频 | 欧美日本一二三 | 日韩av成人在线观看 | 麻豆视频在线观看 | 欧美激情视频在线免费观看 | 精品在线观看视频 | 婷婷去俺也去六月色 | 精品网站999www | 精品国产精品国产偷麻豆 | 婷婷色中文字幕 | 日本高清中文字幕有码在线 | 精品国产乱码久久久久久1区2匹 | 日日添夜夜添 | 在线观看国产一区 | 精品中文字幕在线观看 | 免费裸体视频网 | 欧美一区日韩精品 | 国产区在线看 | 天天综合天天做 | 日韩欧美久久 | 99这里只有久久精品视频 | 91丨九色丨国产在线 | 国产999久久久 | 丁香婷婷综合激情五月色 | 国产成人精品亚洲精品 | zzijzzij日本成熟少妇 | 91日韩精品视频 | 韩国一区二区三区视频 | 国产精品99久久久久久久久久久久 | 国产精品18久久久久久首页狼 | 97超级碰碰| 在线观看国产91 | 国产一区二区三区免费观看视频 | 日韩高清av | 亚洲午夜久久久久久久久久久 | 免费无遮挡动漫网站 | 人交video另类hd| 亚洲va男人天堂 | 国产精品精品国产婷婷这里av | 人人澡视频 | 不卡av电影在线观看 | 热久久免费视频 | 成人av免费播放 | 免费看的视频 | 天天综合色 | 美女网站视频免费黄 | 97视频免费 | 三上悠亚一区二区在线观看 | 日日夜夜91 | 国产在线欧美日韩 | www.超碰97.com | 日日日操操 | 在线国产视频观看 | 久久在视频| 一区二区三区在线观看 | av高清网站在线观看 | 欧美日韩3p | 免费亚洲视频在线观看 | 婷婷色狠狠 | 九九交易行官网 | 人人爽人人爱 | 97国产大学生情侣酒店的特点 | 麻豆视频一区二区 | 国产人成在线视频 | 奇米影视777影音先锋 | 婷婷久草| 一级免费观看 | 中文字幕在线观看第二页 | 操操操操网 | 永久免费精品视频 | 日韩在线欧美在线 | 最近2019年日本中文免费字幕 | www免费黄色 | 国产精品久久久网站 | 久久久精品国产一区二区电影四季 | 久色网| 日韩av不卡在线播放 | 亚洲欧美一区二区三区孕妇写真 | 91资源在线播放 | 久久久久久国产精品 | 91日韩在线视频 | 久久永久免费视频 | 伊人久久影视 | 99久久网站| 日韩黄色大片在线观看 | 亚洲精品激情 | 国产日本亚洲高清 | 欧美大片www | 久久国产精品免费一区二区三区 | 友田真希x88av | 国产精品久久久久久一二三四五 | 婷婷在线视频 | 中文字幕精品三区 | 日本中文字幕久久 | 国产精品久久久久久影院 | 99久久99久久免费精品蜜臀 | 中文字幕在线观看国产 | 久久色中文字幕 | 欧美日韩国产色综合一二三四 | 天天看天天操 | 天天操天天射天天舔 | 黄色资源在线观看 | 狠狠干激情 | 欧美国产日韩中文 | 亚洲女人天堂成人av在线 | 中文字幕第一页在线vr | 亚洲最新av在线网址 | 日本在线观看一区二区三区 | 人人超碰在线 | 天天色天天爱天天射综合 | 亚洲乱码国产乱码精品天美传媒 | 国产中的精品av小宝探花 | .国产精品成人自产拍在线观看6 |