SpringMVC第三篇【收集引數、字串轉日期、結果重定向、返回JSON】
業務方法收集引數
我們在Struts2中收集web端帶過來的引數是在控制器中定義成員變數,該成員變數的名字與web端帶過來的名稱是要一致的…並且,給出該成員變數的set方法,那麼Struts2的攔截器就會幫我們自動把web端帶過來的引數賦值給我們的成員變數….
那麼在SpringMVC中是怎麼收集引數的呢????我們SpringMVC是不可能跟Struts2一樣定義成員變數的,因為SpringMVC是單例的,而Struts2是多例的。因此SpringMVC是這樣乾的:
- 業務方法寫上引數
- 引數的名稱要和web端帶過來的資料名稱要一致
接收普通引數
如果是普通引數的話,我們直接在方法上寫上與web端帶過來名稱相同的引數就行了!
<form action="${pageContext.request.contextPath}/hello.action" method="post">
<table align="center">
<tr>
<td>使用者名稱:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td >編號</td>
<td><input type="text" name="id"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="提交">
</td>
</tr>
</table>
</form>
@RequestMapping(value = "/hello.action")
public String hello(Model model, String username, int id) throws Exception {
System.out.println("使用者名稱是:" + username);
System.out.println("編號是:" + id);
model.addAttribute("message", "你好");
return "/index.jsp";
}
效果:
接收JavaBean
我們處理表單的引數,如果表單帶過來的資料較多,我們都是用JavaBean對其進行封裝的。那麼我們在SpringMVC也是可以這麼做的。
- 建立Javabean
- javaBean屬性與表單帶過來的名稱相同
- 在業務方法上寫上Javabean的名稱
建立JavaBean,javaBean屬性與表單帶過來的名稱相同
public class User {
private String id;
private String username;
public User() {
}
public User(String id, String username) {
this.id = id;
this.username = username;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", username='" + username + '\'' +
'}';
}
}
在業務方法引數上寫入Javabean
@RequestMapping(value = "/hello.action")
public String hello(Model model,User user) throws Exception {
System.out.println(user);
model.addAttribute("message", "你好");
return "/index.jsp";
}
收集陣列
收集陣列和收集普通的引數是類似的,看了以下的程式碼就懂了。
<form action="${pageContext.request.contextPath}/hello.action" method="post">
<table align="center">
<tr>
<td>使用者名稱:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>愛好</td>
<td><input type="checkbox" name="hobby" value="1">籃球</td>
<td><input type="checkbox" name="hobby" value="2">足球</td>
<td><input type="checkbox" name="hobby" value="3">排球</td>
<td><input type="checkbox" name="hobby" value="4">羽毛球</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="提交">
</td>
</tr>
</table>
</form>
業務方法獲取引數
@RequestMapping(value = "/hello.action")
public String hello(Model model,int[] hobby) throws Exception {
for (int i : hobby) {
System.out.println("喜歡運動的編號是:" + i);
}
model.addAttribute("message", "你好");
return "/index.jsp";
}
效果:
收集List<JavaBean>
集合
我們在Spring的業務方法中是不可以用List這樣的引數來接收的,SpringMVC給了我們另一種方案!
我們使用一個JavaBean把集合封裝起來,給出對應的set和get方法。那麼我們在接收引數的時候,接收的是JavaBean
/**
* 封裝多個Emp的物件
* @author AdminTC
*/
public class Bean {
private List<Emp> empList = new ArrayList<Emp>();
public Bean(){}
public List<Emp> getEmpList() {
return empList;
}
public void setEmpList(List<Emp> empList) {
this.empList = empList;
}
}
業務方法接收JavaBean物件
/**
* 批量新增員工
*/
@RequestMapping(value="/addAll",method=RequestMethod.POST)
public String addAll(Model model,Bean bean) throws Exception{
for(Emp emp:bean.getEmpList()){
System.out.println(emp.getUsername()+":"+emp.getSalary());
}
model.addAttribute("message","批量增加員工成功");
return "/jsp/ok.jsp";
}
在JSP頁面直接寫上empList[下表].
<form action="${pageContext.request.contextPath}/emp/addAll.action" method="POST">
<table border="2" align="center">
<caption><h2>批量註冊員工</h2></caption>
<tr>
<td><input type="text" name="empList[0].username" value="哈哈"/></td>
<td><input type="text" name="empList[0].salary" value="7000"/></td>
</tr>
<tr>
<td><input type="text" name="empList[1].username" value="呵呵"/></td>
<td><input type="text" name="empList[1].salary" value="7500"/></td>
</tr>
<tr>
<td><input type="text" name="empList[2].username" value="班長"/></td>
<td><input type="text" name="empList[2].salary" value="8000"/></td>
</tr>
<tr>
<td><input type="text" name="empList[3].username" value="鍵狀哥"/></td>
<td><input type="text" name="empList[3].salary" value="8000"/></td>
</tr>
<tr>
<td><input type="text" name="empList[4].username" value="綠同學"/></td>
<td><input type="text" name="empList[4].salary" value="9000"/></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="批量註冊"/>
</td>
</tr>
</table>
</form>
其實這種方法看起來也沒有那麼難理解,我們就是向上封裝了一層【與接收普通的JavaBean類似的】。
收集多個模型
我們有可能在JSP頁面上即有User模型的資料要收集,又有Emp模型的資料要收集….並且User模型的屬性和Emp模型的屬性一模一樣….此時我們該怎麼辦呢???
我們也是可以在User模型和Emp模型上向上抽象出一個Bean,該Bean有Emp和User物件
/**
* 封裝User和Admin的物件
* @author AdminTC
*/
public class Bean {
private User user;
private Admin admin;
public Bean(){}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Admin getAdmin() {
return admin;
}
public void setAdmin(Admin admin) {
this.admin = admin;
}
}
在JSP頁面收集的時候,給出對應的型別就行了。
<form action="${pageContext.request.contextPath}/person/register.action" method="POST">
<table border="2" align="center">
<tr>
<th>姓名</th>
<td><input type="text" name="user.username" value="${user.username}"/></td>
</tr>
<tr>
<th>月薪</th>
<td><input type="text" name="user.salary" value="${user.salary}"></td>
</tr>
<tr>
<th>入職時間</th>
<td><input
type="text"
name="user.hiredate"
value='<fmt:formatDate value="${user.hiredate}" type="date" dateStyle="default"/>'/></td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="普通使用者註冊" style="width:111px"/>
</td>
</tr>
</table>
</form>
字串轉日期型別
我們在Struts2中,如果web端傳過來的字串型別是yyyy-mm-dd hh:MM:ss這種型別的話,那麼Struts2預設是可以自動解析成日期的,如果是別的字串型別的話,Struts2是不能自動解析的。要麼使用自定義轉換器來解析,要麼就自己使用Java程式來解析….
而在SpringMVC中,即使是yyyy-mm-dd hh:MM:ss這種型別SpringMVC也是不能自動幫我們解析的。我們看如下的例子:
JSP傳遞關於日期格式的字串給控制器…
<form action="${pageContext.request.contextPath}/hello.action" method="post">
<table align="center">
<tr>
<td>使用者名稱:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>出生日期</td>
<td><input type="text" name="date" value="1996-05-24"></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="提交">
</td>
</tr>
</table>
</form>
User物件定義Date成員變數接收
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
業務方法獲取Date值
@RequestMapping(value = "/hello.action")
public String hello(Model model, User user) throws Exception {
System.out.println(user.getUsername() + "的出生日期是:" + user.getDate());
model.addAttribute("message", "你好");
return "/index.jsp";
}
結果出問題了,SpringMVC不支援這種型別的引數:
現在問題就丟擲來了,那我們要怎麼解決呢????
SpringMVC給出類似於Struts2型別轉換器這麼一個方法給我們使用:如果我們使用的是繼承AbstractCommandController類來進行開發的話,我們就可以重寫initBinder()方法了….
具體的實現是這樣子的:
@Override
protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
}
那我們現在用的是註解的方式來進行開發,是沒有重寫方法的。因此我們需要用到的是一個註解,表明我要重寫該方法!
@InitBinder
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
binder.registerCustomEditor(
Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
再次訪問:
值得注意的是:如果我們使用的是Oracle插入時間的話,那麼我們在SQL語句就要寫TimeStrap時間戳插入進去,否則就行不通!
結果重定向和轉發
我們一般做開發的時候,經常編輯完資料就返回到顯示列表中。我們在Struts2是使用配置檔案進行重定向或轉發的:
而我們的SpringMVC就非常簡單了,只要在跳轉前寫上關鍵字就行了!
public String hello(Model model, User user) throws Exception {
System.out.println(user.getUsername() + "的出生日期是:" + user.getDate());
model.addAttribute("message", user.getDate());
return "redirect:/index.jsp";
}
以此類推,如果是想要再次請求的話,那麼我們只要寫上對應的請求路徑就行了!
@RequestMapping(value = "/hello.action")
public String hello(Model model, User user) throws Exception {
return "redirect:/bye.action";
}
@RequestMapping("/bye.action")
public String bye() throws Exception {
System.out.println("我進來了bye方法");
return "/index.jsp";
}
返回JSON文字
回顧一下Struts2返回JSON文字是怎麼操作的:
- 匯入jar包
- 要返回JSON文字的物件給出get方法
- 在配置檔案中繼承json-default包
- result標籤的返回值型別是json
那麼我們在SpringMVC又怎麼操作呢???
匯入兩個JSON開發包
- jackson-core-asl-1.9.11.jar
- jackson-mapper-asl-1.9.11.jar
在要返回JSON的業務方法上給上註解:
@RequestMapping(value = "/hello.action")
public
@ResponseBody
User hello() throws Exception {
User user = new User("1", "zhongfucheng");
return user;
}
配置JSON介面卡
<!--
1)匯入jackson-core-asl-1.9.11.jar和jackson-mapper-asl-1.9.11.jar
2)在業務方法的返回值和許可權之間使用@ResponseBody註解表示返回值物件需要轉成JSON文字
3)在spring.xml配置檔案中編寫如下程式碼:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
</list>
</property>
</bean>
-->
測試的JSP
<input type="button" value="Emp轉JSON"/><p>
<input type="button" value="List<Emp>轉JSON"/><p>
<input type="button" value="Map<String,Object>轉JSON"/><p>
<!-- Map<String,Object>轉JSON -->
<script type="text/javascript">
$(":button:first").click(function(){
var url = "${pageContext.request.contextPath}/hello.action";
var sendData = null;
$.post(url,sendData,function(backData,textStaut,ajax){
alert(ajax.responseText);
});
});
</script>
測試:
Map測試:
@RequestMapping(value = "/hello.action")
public
@ResponseBody
Map hello() throws Exception {
Map map = new HashMap();
User user = new User("1", "zhongfucheng");
User user2 = new User("12", "zhongfucheng2");
map.put("total", user);
map.put("rows", user2);
return map;
}
更新——————————————————————
如果傳遞進來的資料就是JSON格式的話,我們我們需要使用到另外一個註解@RequestBody
,將請求的json資料轉成java物件