SPRING IN ACTION 第4版笔记-第七章Advanced Spring MVC-006- 如何保持重定向的request数据(用model、占位符、RedirectAttributes、model.addFlashAttribute("spitter", spitter);)

一、redirect为什么会丢数据?

when a handler method completes, any model data specified in the method is copied into the request as request attributes, and the request is forwarded to the view for rendering. Because it’s the same request that’s handled by both

the controller method and the view, the request attributes survive the forward.But as illustrated in figure 7.1, when a controller method results in a redirect, the original request ends and a new HTTP GET request begins. Any model data carried in the original request dies with the request. The new request is devoid of any model data in its attributes and has to figure it out on its own.Clearly, the model isn’t going to help you carry data across a redirect. But there are
a couple of options to get the data from the redirecting method to the redirect handling method:
 Passing data as path variables and/or query parameters using URL templates
 Sending data in flash attributes

二、拼url字符串

return "redirect:/spitter/" + spitter.getUsername();

   

三、用model和占位符

在方法中加上model参数,model中的数据能匹配占位符的就作为path参数,否则会作为query参数,如

1 @RequestMapping(value = "/register", method = POST)
2 public String processRegistration(
3     Spitter spitter, Model model) {
4     spitterRepository.save(spitter);
5     model.addAttribute("username", spitter.getUsername());
6     model.addAttribute("spitterId", spitter.getId());
7     return "redirect:/spitter/{username}";
8 }

占位符会编码,把直接拼接字符串安全些,Because it’s filled into the placeholder in the URL template instead of concatenated

into the redirect String , any unsafe characters in the username property are escaped.This is safer than allowing the user to type in whatever they want for the username and then appending it to the path.

因为id匹配不到占位符,假设 username attribute is habuma and the spitterId attribute is 42 , then the resulting redirect path will be /spitter/habuma?spitterId=42

三、用flash attributes->RedirectAttributes

1.需求:

Let’s say that instead of sending a username or ID in the redirect, you want to send the actual Spitter object. If you send just the ID , then the method that handles the redirect has to turn around and look up the Spitter from the database. But before the redirect, you already have the Spitter object in hand. Why not send it to the redirect-handling method to display?

2.

RedirectAttributes是model的子接口,工作原理是用session,Before the redirect takes place, all flash attributes are copied into the session. After the redirect, the flash attributes stored in the session are moved out of the session and into the model. The method that handles the redirect request can then access the Spitter from the model, just like any other model object. Figure 7.2 illustrates how this works.

3.代码实现

1 @RequestMapping(value = "/register", method = POST)
2 public String processRegistration(
3     Spitter spitter, RedirectAttributes model) {
4     spitterRepository.save(spitter);
5     model.addAttribute("username", spitter.getUsername());
6     model.addFlashAttribute("spitter", spitter);
7     return "redirect:/spitter/{username}";
8 }
1 @RequestMapping(value = "/{username}", method = GET)
2 public String showSpitterProfile(
3     @PathVariable String username, Model model) {
4     if (!model.containsAttribute("spitter")) {
5         model.addAttribute(
6             spitterRepository.findByUsername(username));
7     }
8     return "profile";
9 }
原文地址:https://www.cnblogs.com/shamgod/p/5247050.html