springMVC(6)---處理模型數據
之前一篇博客,寫個怎么獲取前段數據:springMVC(2)---獲取前段數據,這篇文章寫怎么從后端往前端傳入數據。
模型數據類型
SpringMVC 提供了以下幾種途徑輸出模型數據:
– ModelAndView: 處理方法返回值類型為 ModelAndView時, 方法體即可通過該對象添加模型數據
– Map及Model:入參為org.springframework.ui.Model、org.springframework.ui.ModelMap 或 Java.uti.Map 時,處理方法返回時,Map中的數據會自動添加到模型中。
– @SessionAttributes: 將模型中的某個屬性暫存到HttpSession 中,以便多個請求之間可以共享這個屬性
– @ModelAttribute: 方法入參標注該注解后, 入參的對象就會放到數據模型中。
一.ModelAndView
目標方法的返回值可以是ModelAndView類型,其中可以包含視圖和模型信息
springmvc會把ModelAndView的model中數據放在request域對象中
@RequestMapping("/springmvc") @Controller public class SpringMVCTest { private static final String SUCCESS = "success"; /** * 目標方法的返回值可以是ModelAndView類型 * 其中可以包含視圖和模型信息 * springmvc會把ModelAndView的model中數據放在request域對象中 * @return*/ @RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ String viewName=SUCCESS; //添加模型視圖 ModelAndView modelAndView=new ModelAndView(viewName); //添加模型數據到ModelAndView中 modelAndView.addObject("time", new Date()); return modelAndView; }
index.jsp
<a href="springmvc/testModelAndView">Test ModelAndView<a>
success.jsp
<html> <h4>Success Page</h4> time:${requestScope.time} </html>
二.Map 及 Model
入參為org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 時,處理方法返回時,Map 中的數據會自動添加到模型中
Controller類
@RequestMapping("/testMap") public String testMap(Map<String, Object> map) { map.put("names", Arrays.asList("tom", "jerry", "mike")); return "success";
index.jsp
<a href="springmvc/testMap">Test Map</a>
success.jsp
map: ${requestScope.names }
界面
三.@SessionAttributes
如果希望在多個請求之間共用某個模型屬性數據,則可以在控制器類標注一個 @SessionAttributes,SpringMVC 會將模型中對應的屬性暫存到 HTTPSession 中。
@SessionAttributes 除了可以通過屬性名指定需要放到會話中的屬性外,還可以通過模型屬性的對象類型指定哪些模型屬性需要放到會話中。
1. @SessionAttributes(types=User.class)會將隱含模型中所有類型為 User 的屬性添加到會話中
2. @SessionAttributes(value={"user1", "user2"})將名為 user1 和 user2 的模型屬性添加到會話中
3. @SessionAttributes(types={"User.class", "Dept.class"})將模型中所有類型為 User 及 Dept 的屬性添加到會話中
4. @SessionAtributes(value={"user1", "user2"}, types={Dept.class})將名為 user1 和 user2 的模型屬性添加到會話中,同時將所有類型為 Dept 的模型屬性添加到會話中
controller類
//SessionAttributes只能放在類上,不能在方法上 @SessionAttributes(value={"user"}, types={String.class}) @RequestMapping("/springmvc") @Controller public class SessionController { private static final String SUCCESS = "success"; @RequestMapping("/testSessionAttributes") public String testSessionAttributes(Map<String, Object> map) { User user = new User("Jack", "123"); map.put("user", user); map.put("msg", "hello"); return SUCCESS; } }
index.jsp
<a href="springmvc/testSessionAttributes">Test SessionAttributes</a>
success.jsp
request user: ${requestScope.user }
request msg: ${requestScope.msg }
session user: ${sessionScope.user }
session msg: ${sessionScope.msg }
最終request和session都有相應值,由此我們可以得出:
被 @SessionAttributes 注解修飾后,模型屬性不僅存在於請求域還存在於會話域。除了可以通過value屬性值指定需要放到會話中的屬性外,還可以根據types屬性值指定哪些類型的模型屬性需要放到會話中。
四.@ModelAttribute
@ModelAttribute注解只支持一個屬性value,類型是為String,代表綁定的屬性名稱。
@ModelAttribute會優先於@RequestMapping執行,也會在Controller中每個方法執行前被執行,所以當一個Controller中有映射到多個Url時,需要謹慎使用
(1)先講下基本理解,網上講的無非就那么幾種:
@ModelAttribute public void myModel3(Model model) { model.addAttribute("name", "SHANHY"); model.addAttribute("age", "28"); } /** * 這個相當於 model.addAttribute("name", name); */ @ModelAttribute("name") public String userModelfirst(@RequestParam("name") String name){ return name; } /** * 這個相當於 model.addAttribute("string", name); * 因為你自己沒有設置model的key值,所以它會默認value的類型第一個字母小寫作為key值 * 如果你是User對象,那它會默認key值為"user",這個在實際開發中並不適用 * 因為太局限了,我們很難接受 key 為 string、int、user 等等這樣的。 */ @ModelAttribute public String myModel1(@RequestParam(required = false) String name) { return name; }
(2)RequestMapping方法中取ModelAttribute方法中的值
modelattr.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <body> <!-- 這里我輸入用戶名:李四 密碼:5678 --> <form action="modelattr/test1"> <label>用戶名:</label> <input type="text" id="name" name="name"></input><br><br> <label>密碼:</label> <input type="text" id="pwd" name="pwd"></input><br><br> <input type="submit" value="登錄"/> </form> </body> </html>
ModelAttrController類
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller @RequestMapping(value="/modelattr") public class ModelAttrController { @ModelAttribute public void Model1(Model model) { model.addAttribute("name", "張三"); model.addAttribute("pwd", "1234"); } /** * test1方法中,有兩個值是通過Model1方法中放入的 * 有兩個值是通過前端獲取的我們看后台打印結果 */ @RequestMapping(value="/test1") public String test1( @ModelAttribute("name") String str2, @ModelAttribute("pwd") String str3, @RequestParam("name") String name, @RequestParam("pwd") String pwd) { System.out.println("name="+str2+",pwd="+str3); System.out.println("name="+name+",pwd="+pwd); return null; } }
后台打印結果:
(3)有關更新,具體看案例
modelPerson.jsp
<html> <body> <!-- 模擬修改操作 1. 原始數據為: 1, zhangsan, 123456,12 2. 密碼不能被修改. 3. 表單回顯, 模擬操作直接在表單填寫對應的屬性值 --> <form action="modelattr/person" method="Post"> <input type="hidden" name="id" value="1"/> name: <input type="text" name="name" value="zhangsan"/> <br> age: <input type="text" name="age" value="12"/> <br> <input type="submit" value="Submit"/> </form> </body> </html>
ModelAttrController類
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import com.ssm.model.Person; @Controller @RequestMapping(value="/modelattr") public class ModelAttrController { /** *1: 因為password我在界面上是沒有輸入的,所以我通過id去數據庫找到這條數據,就能獲得它的password *2:Person領域對象就id name password age 四個屬性都是String形 */ @ModelAttribute public void getUser(@RequestParam(value="id",required=false) String id, Map<String, Object> map){ if(id != null){ //模擬從數據庫中獲取對象 Person person = new Person("1", "lisi", "123456", "24"); System.out.println("從數據庫中獲取一個對象: " + person); map.put("person", person); } } @RequestMapping(value="/person", method=RequestMethod.POST) public String testModelAttribute(Person person){ System.out.println("修改: " + person); return null; } /* * 總結幾點: * 1:map.put("person", person);中的key值,一定要和Person person中的形參一致,否則報錯 * 2:如果去掉@ModelAttribute注解和getUser方法,直接testModelAttribute(Person person)會報錯 * java.lang.NoSuchMethodException: com.ssm.model.Person.<init>() * 3:最后修改的那個person其實就是從數據庫中和前端界面傳來的集合體,就是說如果前端有值那就覆蓋數據庫中對於 * 屬性的值,如果前段沒有值那就還是用數據庫中屬性的值 */ }
后台打印結果
(4)@ModelAttribute和@RequestMapping同時注釋的有返回值的方法
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller @RequestMapping(value="/modelattr") public class ModelAttrController { @ModelAttribute(value="username") @RequestMapping("/person") public String login(@RequestParam("name") String name){ return name; } /** * 這種情況比較有意思:以前return name;都是作為返回路徑 * 現在它變成了value值 * model.addAttribute("username", name); * 那它的映射還是@RequestMapping中的value值這里指:modelattr/person * 我之前路徑為:http://localhost:8080/ssm/modelattr/person * 那么返回路徑為:http://localhost:8080/ssm/WEB-INF/jsp/modelattr/person.jsp */ }
先看WEB-INF/jsp/modelattr/person.jsp
內容
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> </head> <body> <h1>Person返回成功</h1> </body> </html>
最后我們看界面
有關處理模型數據就講到這了,如果哪里講的不周全也歡迎多多指教。
想的太多,做的太少,中間的落差就是煩惱,要么去做,要么別想 少尉【13】