In a web application, URL redirection or forwarding is the technique of moving visitors to a different web page than the one they requested. Most of the time, this technique is used after submitting a web form to avoid resubmission of the same form due to pressing the browser's back button or refresh. Spring MVC has a special View object that handles redirection and forwarding. To use a RedirectView
(org.springframework.web.servlet.view.RedirectView
) with our Controller, we simply need to return the target URL string with the redirection prefix from the Controller. There are two redirection prefixes available in Spring MVC:
Though both redirection and forwarding are used to present a different web page than the one requested, there is a small difference between them. Let's try to understand them by examining them:
HomeController
class and add one more request mapping method as follows: @RequestMapping("/welcome/greeting")
public String greeting() {
return "welcome";
}
welcome
request mapping method as follows and save it:return "forward:/welcome/greeting";
http://localhost:8080/webstore/
. You will able to see the welcome message on the web page.welcome
request mapping method as follows and save it:return "redirect:/welcome/greeting";
http://localhost:8080/webstore/
. You will see a blank page without any welcome message.welcome
method to the original value:return "welcome";
What we demonstrated here is how to invoke RedirectView
from the Controller's method. In step 1, we simply created a request mapping method called greeting
for the welcome
/greeting
request path. This method simply returns a logical View name as welcome
.
Since we returned the logical View name as welcome
, the welcome.jsp
file will be rendered by InternalResourceView
at runtime. The InternalResourceView
file expects two model attributes, greeting
and tagline
, while rendering welcome.jsp
. And in step 2, we altered the return statement of the existing request mapping method to return a redirect URL as follows:
@RequestMapping("/")
public String welcome(Model model) {
model.addAttribute("greeting", "Welcome to Web Store!");
model.addAttribute("tagline", "The one and only amazing web store");
return "forward:/welcome/greeting";
}
So what we did in step 2 was more important; instead of returning a logical View name, we simply returned the request path value of the greeting
handler method with the forward
keyword prefixed.
The moment Spring MVC sees this, it can understand that it is not a regular logical View name, so it won't search for any View file under the src/main/webapp/WEB-INF/views/
directory; rather it will consider this request for forwarding to another request mapping method based on the request path attached after the forward:
keyword.
One important thing to remember here is that the forwarded request is still the active original request, so whatever value we put in the model at the start of the request would still be available; that's why we did not add any value to the Model
inside the greeting
method. We simply returned the View name as welcome
and the welcome.jsp
file with the assumption that there will be model attributes, greeting
and tagline
, available in the model. So when we finally run our application as mentioned in step 3, even though we issued the request to the URL http://localhost:8080/webstore/
, RedirectView
will forward our request to http://localhost:8080/webstore/welcome/greeting
and we will be able to see the welcome message on the web page.
Again in step 4, we simply changed the return statement of the processAddNewProductFormwelcome
method to the redirect:
prefix. This time Spring will consider this request as a new request, so whatever value we put in the model (inside the welcome
method) at the start of the original request will be gone. This is why you saw an empty welcome page in step 6, since the welcome.jsp
page can't read the greeting
and tagline
model attributes from the model.
So, based on this exercise, we understand that RedirectView
will come into the picture if we return a redirection URL with the appropriate prefix from the Controller method. RedirectView
will keep the original request or spawn a new request based on redirection or forwarding.
Consider the following customer Controller:
@Controller("/customers") public class CustomerController { @RequestMapping("/list") public String list(Model model) { return "customers"; } @RequestMapping("/process") public String process(Model model) { // return } }
If I want to redirect the list
method from process
, how should I form the return statement with the process
method?
return "redirect:list"
return "redirect:/list"
return "redirect:customers/list"
return "redirect:/customers/list"