Spring MVC Source Analysis--Page Jump RedirectView (3)

Keywords: Spring

Two previous blogs Spring MVC Source Code Analysis--View (1) and Spring MVC Source Code Analysis -- Views AbstractView and Internal Resource View (II) In this article, we have briefly introduced the related knowledge of View. Next, we introduce a Redirect View, which is used for page jumping as its name implies.

Examples of jumps:

@RequestMapping("/index")
	public String index(Model model,RedirectAttributes attr){
		attr.addAttribute("attributeName", "attributeValue");
		model.addAttribute("book", "Diamond Sutras");
		model.addAttribute("description","No wiping, no wiping, no wiping, no wiping, no wiping, no wiping, no wiping, no wiping, no wiping, no wiping, no wiping, no wiping, no wiping, no wiping, no wiping,"+new Random().nextInt(100));
		model.addAttribute("price", new Double("1000.00"));
		model.addAttribute("attributeName1", "attributeValue1");
		//Save the data to book, description, and price before jumping, because there are these parameters in the annotation @SessionAttribute
		return "redirect:get.action";
	}
The return value is "redirect:get.action". After processing, we will see that the browser will jump to get.action. First, we need to understand that the jump of the request will modify the request link in the browser, so that the jump request and the original request are two unrelated requests. The jump request will lose all the data in the original request. The general solution is to change the request link in the browser. The data in the original request is placed in the link of the jump request to get the data. Next, let's look at the processing done by RediectView of spring MVC, so that we don't have to worry about the value in the original request.

First, when the return value is "redirect:get.action", the handleReturnValue method of ViewNameMethodReturnValueHandler is called to determine whether it is a jump page and set the jump marker.

The implementation in ViewName Method Return Value Handler is as follows:

@Override
	public void handleReturnValue(Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {

		if (returnValue instanceof CharSequence) {
			String viewName = returnValue.toString();
			mavContainer.setViewName(viewName);
			//Used to determine whether it is a redirect jump page?
			if (isRedirectViewName(viewName)) {
				mavContainer.setRedirectModelScenario(true);
			}
		}
		else if (returnValue != null){
			// should not happen
			throw new UnsupportedOperationException("Unexpected return type: " +
					returnType.getParameterType().getName() + " in method: " + returnType.getMethod());
		}
	}
When the judgment page is a jump page and the View object generated by ViewResolver is RedirectView, the jump work can be realized.



Next, let's look at what we did in RedirectView. The final implementation is done in renderMerged Output Model. The mechanism that needs to be implemented here is that the data will be lost when the connection is redirected, so FlashMap is used to save the data as redirected data.

@Override
	protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		//Create jump links
		String targetUrl = createTargetUrl(model, request);
		targetUrl = updateTargetUrl(targetUrl, model, request, response);
		//Get the data carried by the original request
		FlashMap flashMap = RequestContextUtils.getOutputFlashMap(request);
		if (!CollectionUtils.isEmpty(flashMap)) {
			UriComponents uriComponents = UriComponentsBuilder.fromUriString(targetUrl).build();
			flashMap.setTargetRequestPath(uriComponents.getPath());
			flashMap.addTargetRequestParams(uriComponents.getQueryParams());
			FlashMapManager flashMapManager = RequestContextUtils.getFlashMapManager(request);
			if (flashMapManager == null) {
				throw new IllegalStateException("FlashMapManager not found despite output FlashMap having been set");
			}
			//Save data for use as data requested after a jump
			flashMapManager.saveOutputFlashMap(flashMap, request, response);
		}
		//Redirection operation
		sendRedirect(request, response, targetUrl, this.http10Compatible);
	}

Simply put, RedirectView realizes redirection of links and stores data in FlashMap, so that some data can be obtained in the jumped links.

Posted by OpSiS on Wed, 03 Apr 2019 11:24:31 -0700