要點:
- model是一個Map結構的數據模型,能重定向時傳遞數據(拼接URL),但不安全,主要用於渲染前端頁面,配合Thymeleaf填充html里面里設置好的參數。
- @RequestParam用來獲取查詢字符串的參數值。
- HttpServletRequest也可以獲取查詢字符串的參數值。
- redirect: 用於重定向到新的url。
- @ModelAttribute:運用在參數上,會將客戶端傳遞過來的參數按名稱注入到指定對象中,並且會將這個對象自動加入ModelMap中,便於View層使用。
- @ModelAttribute:運用在方法上,會在每一個@RequestMapping標注的方法前執行,如果有返回值,則自動將該返回值加入到ModelMap中。
- redirectAttribute.addAttribute實現URL字符串拼接,類似於model.addAttribute,但是它並不把數據添加到model里。
- redirectAttribute.addFlashAttribute是安全的傳參方法。
下面是以上幾點的實例:
1 package com.example.demo.controller; 2 3 4 5 import javax.servlet.http.HttpServletRequest; 6 7 import org.springframework.stereotype.Controller; 8 import org.springframework.ui.Model; 9 import org.springframework.web.bind.annotation.ModelAttribute; 10 import org.springframework.web.bind.annotation.RequestMapping; 11 import org.springframework.web.bind.annotation.RequestParam; 12 import org.springframework.web.bind.annotation.ResponseBody; 13 14 15 @Controller 16 public class ModelConclusion { 17 18 /* 19 *從查詢字符串里獲取參數username的值 20 * 把name添加到model模型里 21 * 重定向到新的頁面 22 */ 23 @RequestMapping("user") 24 public String setAttribute(@RequestParam(value="username",defaultValue="Leo") String name,Model model) { 25 model.addAttribute("name",name); 26 return "redirect:user/1"; 27 } 28 29 /* 30 * 再次綁定name到model32 * 查看req請求參數,發現添加到model里的屬性也可以在請求參數中獲得 33 */ 34 @RequestMapping("user/1") 35 @ResponseBody() 36 public String getAttribute(@ModelAttribute("name") String name,Model model,HttpServletRequest req) { 37 38 String modelName="model->name:"+name; 39 String modelString = "model:"+model.toString(); 40 String reqName = "req->name:"+req.getParameter("name"); 41 42 return modelName+"<br>"+modelString+"<br>"+reqName; 43 } 44 45 }
頁面輸出結果:
發現,model里的數據添加到了URL里,從這一特點可以知道model傳遞數據是不安全的。所以我們使用model主要是因為java request沒有與視圖技術綁定,而非作為重定向時暫存一些重要數據,如密碼。
另外,在兩個方法參數里,系統都自動創建了新的model,所以重定向后的model不在被保留,但是通過@ModelAttribute再次將數據綁定在model里。
重新寫一下setAttribute方法,以體現modelattibute綁定功能:
1 @RequestMapping("user") 2 public String setAttribute(@ModelAttribute("name") String name,Model model) { 3 return "redirect:user/1"; 4 }
@ModelAttribute用於方法前面時,先於所在Controller下的RequestMapping標注的所有方法執行,實例如下:
User:
1 package com.example.demo.service; 2 3 public class User { 4 5 private String name; 6 private Integer age; 7 public String getName() { 8 return name; 9 } 10 public void setName(String name) { 11 this.name = name; 12 } 13 public Integer getAge() { 14 return age; 15 } 16 public void setAge(Integer age) { 17 this.age = age; 18 } 19 20 }
Controller:
1 package com.example.demo.controller; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.web.bind.annotation.ModelAttribute; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.ResponseBody; 7 8 import com.example.demo.service.User; 9 10 @Controller 11 public class ModelConclusion3 { 12 13 /* 14 * @ModelAttribute注解在方法前,在所有mapping前執行 15 * 可以實現統一配置 16 */ 17 //綁定參數到對象屬性 18 @ModelAttribute 19 public User create(User newUser) { 20 return newUser; 21 } 22 23 //獲取名字 24 @RequestMapping("user/getname") 25 @ResponseBody() 26 public String getName(User newUser) { 27 return newUser.getName(); 28 } 29 30 //獲取年齡 31 @RequestMapping("user/getage") 32 @ResponseBody() 33 public Integer getAge(User newUser) { 34 return newUser.getAge(); 35 } 36 37 38 }
在來看另一種重定向傳參技術:
1 package com.example.demo.controller; 2 3 import org.springframework.stereotype.Controller; 4 import org.springframework.ui.Model; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.ResponseBody; 7 import org.springframework.web.servlet.mvc.support.RedirectAttributes; 8 9 @Controller 10 public class ModelConclusion2 { 11 12 /* 13 * redirectAttribute.addAttribute功能時字符串拼接,類似於model.addAttribute,但是它並不把數據添加到model里 14 * redirectAttribute.addFlashAttribute時安全的傳遞參數方法,原理是將數據添加到session里,等頁面渲染好后從session里移除,最后加入到model模型里 15 */ 16 17 @RequestMapping("user2") 18 public String setAttribute(Model model,RedirectAttributes redirectAttribute) { 19 20 redirectAttribute.addAttribute("name","Jack"); 21 redirectAttribute.addFlashAttribute("age",15); 22 System.out.println(model); 23 24 return "redirect:user2/1"; 25 } 26 27 @RequestMapping("user2/1") 28 @ResponseBody() 29 public String getAttribute(String name,Integer age,Model model) { 30 31 System.out.println(age); 32 System.out.println(name); 33 System.out.println(model); 34 35 return "hello"; 36 } 37 38 39 }
控制台結果:
可以發現,addflash后model里是沒數據的,而且由於它不是URL拼接,所以age也沒有捕獲到,但最后我們還是在model里找到它,所以addflash非常適合密碼等信息的傳遞。
上述如有錯誤,望請指正!