接收表單數據有3種方式。
1、使用簡單類型接收表單數據(綁定簡單數據類型)
表單:
<form action="${pageContext.request.contextPath}/userController/handler" method="post"> 用戶名:<input name="username" type="text" /><br /> 密碼:<input name="password" type="password" /><br /> 年齡:<input name="age" type="number" /><br /> <button type="submit">提交</button> </form>
action會有提示,但必須要在前面加${pageContext.request.contextPath}來獲取項目名(/項目名的形式),否則會把后面的路徑直接拼接到域名后面。
如果是SpringBoot,則不用加${pageContext.request.contextPath}。
controller:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public ModelAndView handler(String username, String password, int age){ ModelAndView mav = new ModelAndView("user_info"); mav.addObject("username", username); mav.addObject("password", password); mav.addObject("age", age); return mav; } }
參數名要和表單字段的name一致。
SpringMVC會自動將請求參數轉換為需要的數據類型。
如果表單字段很多,業務方法要寫很多參數,太麻煩,不推薦。
2、使用pojo類接收表單數據(綁定pojo類型)
pojo:
public class User { private String username; private String password; private int age; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
屬性名要與表單字段的name一致。
controller:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public ModelAndView handler(User user){ ModelAndView mav = new ModelAndView("user_info"); mav.addObject("user", user); return mav; } }
推薦使用。
3、使用擴展類接收表單數據(綁定pojo的包裝類)
擴展類:
public class UserExt { private User user; //此處省略其它成員變量 public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
把bean寫為成員變量。
表單:
<form action="${pageContext.request.contextPath}/userController/handler" method="post"> 用戶名:<input name="user.username" type="text" /><br /> 密碼:<input name="user.password" type="password" /><br /> 年齡:<input name="user.age" type="number" /><br /> <button type="submit">提交</button> </form>
這里的user對應擴展類中的成員變量名。
controller:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public ModelAndView handler(UserExt userExt){ ModelAndView mav = new ModelAndView("user_info"); mav.addObject("userExt", userExt); return mav; } }
使用擴展類接收參數,主要是表單傳過來的數據有一些不屬於實體類,還需要用其它的成員變量來接收。
單選框、復選框的數據接收
單選框可用普通類型來接收。
復選框常用於同時勾選多個選項,比如選擇愛好、批量刪除等(同一個name、多個value)。
復選框使用數組來接收,復選框的name要與數組名一致。
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public ModelAndView handler(String[] hobby){ ModelAndView mav = new ModelAndView("user_info"); mav.addObject("hobby",hobby); return mav; } }
批量修改,使用List來接收
有時候我們需要批量插入、批量修改。
比如視圖以表格的形式列出了多個用戶的信息,管理員在頁面上修改了多個用戶的信息,現在要提交修改,需要使用List<User>來傳遞數據,批量添加也是一樣的。
不能直接使用List<User>來接收參數,需要使用包裝類包裝一下。
包裝類:
public class UserVO { private List<User> list; public List<User> getList() { return list; } public void setList(List<User> list) { this.list = list; } }
VO只有一個屬性,及其getter、setter方法。
表單:
<form action="${pageContext.request.contextPath}/userController/handler" method="post"> User1:<br /> username:<input name="list[0].username" type="text"><br /> password:<input name="list[0].password" type="password"><br /><br /> User2:<br /> id:<input name="list[1].username" type="text"><br /> name:<input name="list[1].password" type="password"><br /><br /> <button type="submit">提交</button> </form>
此處list對應包裝類的成員變量名。
controller:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public ModelAndView handler(UserVO userVO){ ModelAndView mav = new ModelAndView("user_info"); mav.addObject("list", userVO.getList()); return mav; } }
日期的接收
有時候需要接收表單傳遞的日期,比如生日。
后台有2種接收方式:
- 使用String接收日期
如果不進行相關計算,使用String表示日期即可;如果要進行相關計算,先用String接收日期,在業務方法中把String轉換為Date(可以封裝為工具類,在業務方法中調用)。
表單使用<input type="text" />、<input type="date" />都可以,type="text"要嚴格校驗日期格式。
- 使用Date接收日期
表單使用<input type="text" />、<input type="date" />都可以,如果使用type="text",日期格式只能是 年/月/日 (/分隔)。
DataBinder 數據綁定
數據綁定的概念:將請求參數的內容與controller中業務方法的參數綁定,比如表單數據的提交。
數據綁定的流程:
(1)Spring MVC將ServletRequest對象傳遞給DataBinder
(2)Spring MVC從controller的業務方法的簽名(聲明)中獲取參數表(形參名),把它傳遞給DataBinder
(3)DataBinder調用ConversionService對ServletRequest中的請求參數進行數據類型的轉換、格式化
( ConversionService會根據 原始類型 ——目標類型 調用對應的Converter來進行數據轉換。Spring MVC內置了常用的類型轉換器,我們也可以自定義類型轉換器。)
(4)DataBinder調用Validator校驗已經被轉換好的請求參數是否合法
(5)DataBinder調用BindingResult,把請求參數賦給業務方法中對應的參數,完成數據綁定。
解決前端傳過來的數據中文亂碼
使用spring mvc提供的編碼過濾器,過濾所有請求。
在web.xml中配置:
<filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <!--過濾所有請求--> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
@RequestParam 必需的請求參數
controller:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public String handler(int user_id,Model model){ model.addAttribute("user_id", user_id); return "user_info"; } }
就算請求參數中沒有user_id這個字段,也會調用這個業務方法來處理,就是說參數不是必需傳遞的。
如果參數是必需的,要求HTTP請求參數中必需要有這個字段,可以這樣:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public String handler(@RequestParamint user_id,Model model){ model.addAttribute("user_id", user_id); return "user_info"; } }
用@RequestParam修飾某個參數,表示這個參數是必需的,如果沒有傳遞此參數,不會調用業務方法,直接報錯。
如果請求參數的字段名和業務方法的形參名不一致,比如請求參數中的字段名是id,而業務方法中的形參名是user_id,則必須指定該形參與請求參數中的哪個字段綁定:
@RequestMapping("/handler") public String handler(@RequestParam("id") int user_id,Model model){ model.addAttribute("user_id", user_id); return "user_info"; }
如果請求參數的字段名和業務方法的形參名一致,直接寫@RequestParam就行,SpringMVC會自動把請求參數賦給業務方法中同名的形參。
注意:
必需和必填不是一個概念,必需是指請求參數中必須要有這個字段,只有要這個字段就行,值可以是空的。
如果一個表單字段(有name屬性),沒填就提交了,請求參數中是有這個字段的,只不過值是空的。
可以設置是否必需:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public String handler(@RequestParam(value = "user_id",required = false) int user_id,Model model){ model.addAttribute("user_id", user_id); return "user_info"; } }
默認為true——必需,沒傳遞該參數直接報錯。
false——不是必需的,傳不傳遞都行,都會調用業務方法。
可以設置默認值:
@org.springframework.stereotype.Controller @RequestMapping("/userController") public class UserController{ @RequestMapping("/handler") public String handler(@RequestParam(value = "user_id",defaultValue = "0") int user_id,Model model){ model.addAttribute("user_id", user_id); return "user_info"; } }
如果沒有傳遞此參數,會自動使用默認值。