Spring MVC forwarding and redirection

Essential difference

 


In a word, forwarding is server behavior, and redirection is client behavior. Why do I say this, it depends on the workflow of the two actions:

Forwarding process: client browser sends http request----"web server accepts this request----"calls an internal method to complete request processing and forwarding action inside the container----"sends the target resource to the client; here , the forwarding path must be the url under the same web container , it cannot be redirected to other web paths, and the request in its own container is passed in the middle. The path displayed in the path bar of the client's browser is still the path of the first visit, that is to say, the client does not feel that the server has forwarded it. The forwarding behavior is that the browser only makes one access request.

Redirection process: The client browser sends an http request----"The web server sends a 302 status code response and the corresponding new location to the client browser after accepting it-"The client browser finds that it is a 302 response, and automatically sends a new one . http request, the request url is the new location address ----" the server finds the resource according to this request and sends it to the client. Here location can be redirected to any URL. Since the browser reissues the request, there is no concept of request transmission. The path bar of the client's browser displays the redirected path, and the client can observe the change of the address. The redirect behavior is that the browser makes at least two access requests.


Forward and redirect

 When starting Java EE, the concepts of forward and redirect may be unclear. This article firstly understands the difference between the two through the code example and the running result picture, and then gives the definition of the two.

1. Conventional usage, return a View

@RequestMapping(value="/testa", method=RequestMethod.GET)
public String inputData(){
    return "testa"; //Spring框架找到对应的View并渲染
}

@RequestMapping(value="/testa", method=RequestMethod.POST)
public String outputData(HttpServletRequest request){
    String userName = request.getParameter("name");
    String password = request.getParameter("pwd");
    request.setAttribute("name", userName);
    request.setAttribute("pwd", password);
    return "testb"; //Spring框架找到对应的View并渲染
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Open the testa webpage:

Enter username: spring, password: spring:

write picture description here

Click the login button, the page becomes as follows:

write picture description here

Refresh again, and Google Chrome prompts to resubmit the form.

write picture description here

对比图片,发现浏览器的输入框中URL不变,但是不同情况下显示不同的View。跳转时Model共享(表单会被重复提交)。

2、转发(forward)

@RequestMapping(value="/testa", method=RequestMethod.GET)
public String inputData(){
    return "testa"; //Spring框架找到对应的View并渲染
}

@RequestMapping(value="/testa", method=RequestMethod.POST)
public String outputData(HttpServletRequest request){
    String userName = request.getParameter("name");
    String password = request.getParameter("pwd");
    request.setAttribute("name", userName);
    request.setAttribute("pwd", password);
    //转发到 /testb 的Controller方法(即outputDataX)上
    return "forward:/testb"; 
}

@RequestMapping(value="/testb", method=RequestMethod.POST)
public String outputDataX(HttpServletRequest request){
    return "testb";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

打开testa网页:

输入用户名:spring,密码:spring:

write picture description here

点击登陆按钮,页面变为如下:

write picture description here

调试分析:forward后面跟一个资源。当程序运行到return “forward:/testb”时,会执行会执行该资源对应的方法outputDataX。 
另外转发时,浏览器的URL不变。

再次刷新,谷歌浏览器提示重新提交表单。

write picture description here

3、重定向(redirect)

@RequestMapping(value="/testa", method=RequestMethod.GET)
public String inputData(){
    return "testa"; //Spring框架找到对应的View并渲染
}

@RequestMapping(value="/testa", method=RequestMethod.POST)
public String outputData(HttpServletRequest request){
    String userName = request.getParameter("name");
    String password = request.getParameter("pwd");
    request.setAttribute("name", userName);
    request.setAttribute("pwd", password);
    //重定向到 /testb 的Controller方法(即outputDataY)上
    return "redirect:/testb"; 
}

@RequestMapping(value="/testb", method=RequestMethod.POST)
public String outputDataX(HttpServletRequest request){
    return "testb";
}

@RequestMapping(value="/testb", method=RequestMethod.GET)
public String outputDataY(HttpServletRequest request){
    return "testb";
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

打开testa网页:

输入用户名:spring,密码:spring:

write picture description here

点击登陆按钮,页面变为如下:

write picture description here

调试分析:redirect后面跟一个资源。当执行到return “redirect:/testb”时,会执行该资源对应个方法outputDataY。由于重定向Model不共享,所以页面无数据显示。 
另外重定向后浏览器的输入框中URL也发生变化。

刷新后,谷歌浏览器没有提示重新提交表单

write picture description here

总结: 
常说的可以通过redirect: URL防止重复提交表单,就是上面过程的意思。 
原理是对于redirect而言,Request的attribute不会被传递,放到session中,session在跳到页面后马上移除对象。所以你刷新一下后这个值就会丢掉。

如果你希望Request的attribute被传递,可以使用RedirectAttributes类。

@RequestMapping(value="/testa", method=RequestMethod.GET)
 public String inputData(){
  return "testa"; //Spring框架找到对应的View并渲染
 }

 @RequestMapping(value="/testa", method=RequestMethod.POST)
 public String outputData(HttpServletRequest request, RedirectAttributes redirectAttributes){
  String userName = request.getParameter("name");
  String password = request.getParameter("pwd");
  request.setAttribute("name", userName);
  request.setAttribute("pwd", password);
  //重定向到 /testb 的Controller方法(即outputDataY)上
  //重定向传递参数的两种方法
  redirectAttributes.addAttribute("name", userName);
  redirectAttributes.addFlashAttribute("pwd", password);

  return "redirect:/testb"; 
 }

 @RequestMapping(value="/testb", method=RequestMethod.POST)
 public String outputDataX(HttpServletRequest request){
  return "testb";
 }

 @RequestMapping(value="/testb", method=RequestMethod.GET)
 public String outputDataY(HttpServletRequest request){
  String userName = request.getParameter("name");
  request.setAttribute("name", userName);
  return "testb";
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

运行如下:

write picture description here

The above example shows two methods of passing parameters using RedirectAttributes: 
1. Passing parameters using the addAttribute method of the RedirectAttributes class will follow the URL, as shown in the Google browser above, the URL is http://localhost:8080/testb?name= spring 
2. Using the addFlashAttribute method of the RedirectAttributes class to pass parameters will not follow the URL. The parameter value will be temporarily saved in the session. After the redirection URL obtains the parameter, it will be removed from the session. The redirect here must be the method mapping path. , jsp is invalid. You will find that the pwd will only appear once in the redirected jsp page, and the pwd will never appear again after the refresh. The following figure shows the result after refresh, and the password pwd is displayed as empty. This verifies the above, the pwd will be removed from the session after being accessed. This method can be used to prevent duplicate submissions.

definition

As an experienced servlet/JSP programmer, you must know the difference between forwarding and redirecting. Forwarding is faster than redirecting because redirection goes through the client, while forwarding does not. However, it is better to use redirection. If you need to redirect to an external website, you cannot use forwarding.

Personal understanding: For example, the server window A orders food, and window B takes the food. Forwarding means that the browser goes to the server window A to order food. After ordering, the server takes the food from window B and sends the food directly to the browser. Redirection means that the browser goes to the server window A to order food. The server does not help the browser to fetch food from window B, but tells the browser to go to B to fetch food. After the browser obtains the information, it sends a meal request to window B.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325663435&siteId=291194637