前台jsp頁面和后台傳值的幾種方式:
不用SpringMVC自帶的標簽
前台---->后台,通過表單傳遞數據():
1.jsp頁面代碼如下, modelattribute 有沒有都行
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <form method="post" enctype="multipart/form-data"> Username:<input type="text" name="username"/> <sf:errors path="username"> Password:<input type="password" name="password"/> <sf:errors path="password"> Nickname:<input type="text" name="nickname"/></br> Email<input type="text" name="email"/> </form> </body> </html>
2.寫Action,如下兩種方式都可以:
第一種,表單的name屬性值必須和接受的參數同名。否則,接收到的參數為null,但不報錯
第二種,表單的name屬性值必須和接收對象的屬性同名。否則,接收到的參數為null,但不報錯
@RequestMapping(value="/add",method=RequestMethod.POST) public String userAdd(String username,String password,String nickname,String email){ User user = new User(username,password,nickname,email); System.out.println(user.toString()); users.put(user.getNickname(), user); //客戶端跳轉 return "redirect:/user/users"; }
@RequestMapping(value="/add",method=RequestMethod.POST) public String userAdd(User user) { System.out.println(user.toString()); users.put(user.getNickname(), user); //客戶端跳轉 return "redirect:/user/users"; }
注意1:即使我們的Action使用第二種方式(選用User類對象作為參數),前台界面也不能寫成user.username ,后台這樣會接收失敗,得到的值是null。這一點如果沒記錯的話,應該和Struts2是不一樣的
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <form method="post" enctype="multipart/form-data"> Username:<input type="text" name="user.username"/> Password:<input type="password" name="user.password"/> Nickname:<input type="text" name="user.nickname"/> Email<input type="text" name="user.email"/> <input type="submit" value="添加用戶" /> </form> </body> </html>
注意2:我們的Action使用第二種方式(選用User類對象作為參數),我們可以在服務端使用@Validated注解來進行服務端驗證。但是由於我們前台jsp頁面沒有使用SpringMVC自帶的標簽庫,前台jsp頁面無法顯示錯誤信息,也就是<sf:errors path="username"></sf:errors> 不起作用(不報錯)。
----如果只把<form></form>標簽緩存<sf:form></sf:form>,並且添加modelAttribute="user"屬性,不該其他內容,<sf:error>會起作用。但是我們不會這樣做,沒有任何意義,要用就統一用SpringMVC自帶的標簽庫,要么就全部用,混着用容易出錯。
后台---->前台 model.addAttribute("users",users):
后台Action代碼
@RequestMapping(value={"/users","/",""},method=RequestMethod.GET)
public String userList(Model model){
//model.addAllAttributes(user);//key是map(類型名首字母小寫)
model.addAttribute("users",users);
return "user/list";
}
@RequestMapping(value="/add",method=RequestMethod.GET)
public String userAdd(){
model.addAttribute("user", new User("newUser","newUserPwd","newUserNickname","newUser@126.com"));
return "user/add";
}
前台jap頁面取值:使用jstl:<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>用戶列表</title> </head> <body> <a href="add" >添加</a> <br/> <c:forEach items="${users }" var="userMap"> ${userMap.key } <!-- 這里使用jstl取值,如果我們把User對象的字段,所對應的getter和setter方法去掉,頁面會報錯 --> -----><a href="${userMap.value.username }">${userMap.value.username } </a> ----->${userMap.value.password } ----->${userMap.value.nickname } ----->${userMap.value.email } -----><a href="${userMap.value.nickname }/update">修改用戶</a> -----><a href="${userMap.value.nickname }/delete">刪除用戶</a> </br> </c:forEach> </body> </html>
使用SpringMVC自帶的標簽
前台---->后台,通過表單傳遞數據():
前台jsp頁面代碼如下。
1.需要添加一個taglib <%@taglib prefix="sf" uri="http://www.springframework.org/tags/form"%>
2.由於使用了SpringMVC自帶的標簽<sf:input path="username"/>,<sf:password path="password"/>,帶有必須的path屬性,所以必須要加上
modelAttribute="user",否則會報錯
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <sf:form method="post" modelAttribute="user" enctype="multipart/form-data"> Username:<sf:input path="username"/> <sf:errors path="username"></sf:errors></br> Password:<sf:password path="password"/> <sf:errors path="password"></sf:errors></br> Nickname:<sf:input path="nickname"/></br> Email:<sf:input path="email"/> <input type="submit" value="添加用戶" /> </sf:form> </body> </html>
2.寫Action,如下兩種方式都可以:
第一種,表單的path屬性值必須和接受的參數同名。
第二種,表單的path屬性值必須和接收對象的屬性同名,並且modelAttribute="user"的屬性值,必須為Action參數的類型名小寫,即User變user。
public String userAdd(String username,String password,String nickname,String email) { User user = new User(username,password,nickname,email); System.out.println(user.toString()); users.put(usera.getNickname(), user); //客戶端跳轉 return "redirect:/user/users"; }
public String userAdd(User user) { System.out.println(user.toString()); users.put(user.getNickname(), user); //客戶端跳轉 return "redirect:/user/users"; }
如果我們的Action使用第二種方式(選用User類對象作為參數),我們可以在服務端使用@Validated注解來進行服務端驗證。那么前台jsp頁面是能夠通過<sf:error>來獲取錯誤信息的。想下面的代碼,如果我們填寫的User信息有錯誤,那么我們就會返回到剛才填寫信息的add頁面,並且還會顯示錯誤信息。
@RequestMapping(value="/add",method=RequestMethod.POST) public String userAdd(@Validated User user,BindingResult br,MultipartFile attach,HttpServletRequest re) throws IOException{//一定要緊跟validate寫,驗證結果類,中間如果有其他參數,就會報錯 System.out.println(user.toString());
//如果有錯誤,返回添加用戶信息的頁面。這里不用Model model和model.addAttribute()為什么不報錯呢 if(br.hasErrors()){ return "user/add"; } users.put(user.getNickname(), user); //客戶端跳轉 return "redirect:/user/users"; }
后台---->前台,傳遞數據:
后台Action,使用model.addAttribute():
注意:這里有一點需要強調一下,如果我們不適用SpringMVC自帶的標簽,那么如果我們不想往前台jsp頁面傳數據,那么我們可以不用添加Action的參數Model model 和 model.addAttribute()。但是如果使用SpringMVC自帶的標簽,我們必須要向前台頁面傳送數據,即使傳一個空值,也要傳,否則報錯。
@RequestMapping(value="/add",method=RequestMethod.GET) public String userAdd(Model model){ //public String userAdd(@ModelAttribute("user")User user){ //model.addAttribute(new User()); model.addAttribute("user", new User("newUser","newUserPwd","newUserNickname","newUser@126.com")); return "user/add"; }
前台jsp頁面取值方式
1.這里我們也可以使用jstl表達式,來獲取傳到前台jsp頁面的值,和不適用SpringMVC自帶標簽是一樣的,就不詳述了。
2.但是,我們也可以不使用jstl這種方式來獲取值。由於前台jsp頁面中,是有SpringMVC自帶標簽的,<sf:input path="username"/>,<sf:password path="password"/>,這里就會直接把值賦給這個標簽。
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <!-- 使用jstl取值 --> ${user.username } <sf:form method="post" modelAttribute="user" enctype="multipart/form-data"> <!-- 也可以直接把值,自動放到標簽里面顯示,不需要人工操作 --> Username:<sf:input path="username"/> <sf:errors path="username"></sf:errors></br> Password:<sf:password path="password"/> <sf:errors path="password"></sf:errors></br> Nickname:<sf:input path="nickname"/></br> Email<sf:input path="email"/> <input type="submit" value="添加用戶" /> </sf:form> </body> </html>
注意:很重要的一點,如果前台使用了SpringMVC自帶的標簽,我們用GET請求“添加頁面”的時候,即使我們后端沒有要傳給前台jsp頁面數據,我們的Action也必須要有Model model參數,並且函數體中,也必須要添加一個空,model.addAttribute(new User());,否則會報錯。也就是說,如果選擇了SpringMVC自帶的標簽:
1.負責GET請求的Action必須 要有Model model參數,並且函數體中,也必須要添加一個空,model.addAttribute(new User());
2.前台jsp頁面 <sf:form>表單 一定要有modelAttribute="user"
3.如果在POST請求中,用了@validated,如果頁面出錯,我們還是會返回“添加頁面”,但是奇怪的是為什么此時我不加Model model參數,和model.addAttribute(new User());是不會報錯的呢?個人認為,系統為自動給你加的。當然如果報錯了之后,你想自己傳一些特殊的值給前台jsp頁面,那么就需要用到。
。java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'command' available as request attribute ,
如果我們要使用@Validate進行驗證,並且需要在前台通過<sf:error></sf:error>來顯示錯誤信息,那么我們一定要用<sf:form></sf:form>,並且設置modelAttribute="user",它的屬性值,必須為小寫的類型名 ,表單中的其他標簽是否使用<sf:>都可以。
此時前台接收的方式
1.可以使用el表達式,${userMap.value.username }
2.如果我們想讓傳過來的值直接放到某個控件上(不使用js),我們可以使用SpringMVC自己帶的標簽(需要設置taglib)
比如下面的<sf:input path="username"/>,path屬性是必須要設置的。modelAttribute="user"也是必須要設置的。而且如果使用了這種方式,那么后台
代碼必須要有Model model,並且model需要add一個東西
我們這樣理解這個東西,由於<sf:input path="">的path屬性是必須的,所以這個屬性對應着對象的某一個字段,而對象是什么呢,就需要modelAttribute="user",來確定。這也就說明,只要使用<sf:>,就必須要有modelAttribute=""的原因了。而且后台一定要傳東西過來,如果沒有
model.addAttribute(),那么<sf:>標簽就獲取不到對應的值,就會報錯
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <sf:form method="post" modelAttribute="user" enctype="multipart/form-data"> Username:<sf:input path="username"/> <sf:errors path="username"></sf:errors></br> Password:<sf:password path="password"/> <sf:errors path="password"></sf:errors></br> Nickname:<sf:input path="nickname"/></br> Email<input type="text" name="email"/> <input type="submit" value="添加用戶" /> </sf:form> </body> </html>
