標(biāo)簽(空格分隔): SpringMVC
@ModelAttribute使用大致有有兩種,一種是是直接標(biāo)記在方法上,一種是標(biāo)記在方法的參數(shù)中,兩種標(biāo)記方法產(chǎn)生的效果也各不相同,這里就列舉下兩種標(biāo)記所產(chǎn)生的效果
首先先做點簡單的準(zhǔn)備工作,寫一個只包含一個button的jsp頁面,這里可以看見,只是寫了個簡單按鈕事件,跳轉(zhuǎn)的modelTest.do這個路徑
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type="text/javascript" src="<%=basePath%>static/js/jquery.min.js"></script>
</head>
<script type="text/javascript">
$(function(){
$("#modelTest").on("click",function(){
window.location.href="<%=basePath%>model/modelTest.do";
})
});
</script>
<body>
<input type="button" id="modelTest" value="測試">
</body>
</html>
注解標(biāo)記在方法上
下面,再讓我們寫一個controller控制器,這里我們再控制器中寫兩個方法,其中一個使用@RequestMapping方法路徑標(biāo)記為modelTest.do,另外一個方法不標(biāo)記路徑,使用@ModelAttribute標(biāo)記
package com.lovo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {
@ModelAttribute
public void init()
{
System.out.println("最先執(zhí)行的方法");
}
@ModelAttribute
public void init02()
{
System.out.println("最先執(zhí)行的方法02");
}
@RequestMapping(value="modelTest.do")
public String modelTest()
{
System.out.println("然后執(zhí)行的方法");
return "modelTest";
}
@ModelAttribute
public void init03()
{
System.out.println("最先執(zhí)行的方法03");
}
}
部署后運(yùn)行,點擊頁面測試按鈕,查看控制臺輸出,這個時候你會發(fā)現(xiàn),后臺控制器并沒有直接進(jìn)入modelTest.do的路徑,而是先執(zhí)行了被@ModelAttribute標(biāo)記的init方法。應(yīng)該這么理解,當(dāng)同一個controller中有任意一個方法被@ModelAttribute注解標(biāo)記,頁面請求只要進(jìn)入這個控制器,不管請求那個方法,均會先執(zhí)行被@ModelAttribute標(biāo)記的方法,所以我們可以用@ModelAttribute注解的方法做一些初始化操作。當(dāng)同一個controller中有多個方法被@ModelAttribute注解標(biāo)記,所有被@ModelAttribute標(biāo)記的方法均會被執(zhí)行,按先后順序執(zhí)行,然后再進(jìn)入請求的方法。
下面方法做一些變形,變形為帶有參數(shù)的返回,這樣也是實際開發(fā)中經(jīng)常會操作的
首先像創(chuàng)建個pojo對象,對象包含userName,sex兩個屬性。并對JSP及控制器代碼做一些修改
頁面使用EL表達(dá)式接受返回參數(shù)
<script type="text/javascript">
$(function(){
$("#modelTest").on("click",function(){
window.location.href="<%=basePath%>model/modelTest.do";
})
});
</script>
<body>
<input type="button" id="modelTest" value="測試">
<input type="text" value="${pojo.userName }">
<input type="text" value="${pojo.sex }">
</body>
@ModelAtterbute方法無返回值情況
@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {
@ModelAttribute
public void init(Model mode)
{
PojoTest pojo=new PojoTest(null, "小明", "男");
mode.addAttribute("pojo", pojo);
}
@RequestMapping(value="modelTest.do")
public String modelTest()
{
return "modelTest";
}
}
訪問ModelTest.jsp頁面并點擊測試
出現(xiàn)如下結(jié)果
從執(zhí)行結(jié)果看出,當(dāng)訪問請求時,會首先訪問init方法,然后再對test方法進(jìn)行訪問,并且是同一個請求,因為model模型數(shù)據(jù)的作用域與request相同,所以可以用此標(biāo)記直接標(biāo)記在方法上對實際要訪問的方法進(jìn)行一些初始化操作
@ModelAttribute標(biāo)記方法有返回值
@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {
@ModelAttribute
public String init(Model mode)
{
System.out.println("進(jìn)入init方法");
PojoTest pojo=new PojoTest(null, "小明", "男");
mode.addAttribute("pojo", pojo);
return "model/befor.do";
}
@RequestMapping(value="befor.do")
public String befor(){
System.out.println("進(jìn)入befor方法");
return "index";
}
@RequestMapping(value="modelTest.do")
public String modelTest()
{
System.out.println("進(jìn)入modelTest方法");
return "modelTest";
}
}
這里稍微做了點變形,可以看到在被@ModelAttribute方法中設(shè)值了返回路徑為befor方法,但是在在代碼運(yùn)行的過程中并不會跳轉(zhuǎn)befor方法,而是在代碼執(zhí)行完成return之前直接跳轉(zhuǎn)了實際請求的方法。
@ModelAttribute標(biāo)記在參數(shù)前
從from表單或url地址中取值,這里就以url地址為例,為了避免url地址中文亂碼問題,這里調(diào)用了encodeURL函數(shù)
<script type="text/javascript">
$(function(){
$("#modelTest").on("click",function(){
window.location.href="<%=basePath%>model/modelTest.do?userName="+encodeURI('小明')+"&sex="+encodeURI('男');
})
});
</script>
<body>
<input type="button" id="modelTest" value="測試">
<input type="text" value="${pojo.userName }">
<input type="text" value="${pojo.sex }">
</body>
@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {
@RequestMapping(value="modelTest.do")
public String modelTest(@ModelAttribute("pojo") PojoTest pojo)
{
try {
pojo.setUserName(new String(pojo.getUserName().getBytes("iso-8859-1"),"utf-8"));
pojo.setSex(new String(pojo.getSex().getBytes("iso-8859-1"),"utf-8"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(pojo);
return "modelTest";
}
}
點擊頁面測試,頁面文本框會顯示URL地址傳遞過來的參數(shù),因為SpringMVC會自動匹匹配頁面?zhèn)鬟f過來的參數(shù)的name屬性和后臺控制器中的方法中的參數(shù)名,如果參數(shù)名相同,會自動匹配,如果控制器中方法是封裝的bean,會自動匹配bean中的屬性,其實這種取值方式不需要用@ModelAttribute注解,只要滿足匹配要求,也能拿得到值
從model對象中取值
@Controller
@RequestMapping(value="model")
public class ModelAttributeTest {
@ModelAttribute("pojo")
public PojoTest init( PojoTest pojo)
{
pojo.setSex("男");
return pojo;
}
@RequestMapping(value="modelTest.do")
public String modelTest(@ModelAttribute("pojo") PojoTest pojo)
{
pojo.setUserName("小明");
return "modelTest";
}
}
點擊測試發(fā)現(xiàn),modelTest拿到inint方法中的pojo對象,合并兩次set的參數(shù)后返回頁面