若是須要將請求中的參數綁定到該pojo對象形參中,只須要保證請求中攜帶的key/value格式的參數中的key值與pojo類中的屬性名相同便可,SpringMVC會自動將請求中的參數綁定或者說注入到pojo對象的屬性中,好比html
<form action="user/regist.do"> <div>請輸入名稱:<input type="text" name="userName"></div> <div>請輸入密碼:<input type="password" name="userPassword"></div> <div>請輸入年齡:<input type="text" name="userAge"></div> <div>請輸入地址:<input type="text" name="userAddress"></div> <div>請輸入手機:<input type="text" name="userTelephone"></div> <div><input type="submit" value="註冊"></div> </form>
public class User { private Integer userAccount; private String userName; private String userPassword; private Integer userAge; private String userAddress; private String userTelephone; //省略每一個屬性的get/set方法 }
@Controller @RequestMapping("/user") public class UserController { @RequestMapping("/regist") public String userRegist(User user){ return "login"; } }
一樣以上面的註冊爲例前端
public class UserVo { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } } @Controller @RequestMapping("/user") public class UserController { @RequestMapping("/regist") public String userRegist(UserVo user){ return "login"; } }
<form action="user/regist.do"> <div>請輸入名稱:<input type="text" name="user.userName"></div> <div>請輸入密碼:<input type="password" name="user.userPassword"></div> <div>請輸入年齡:<input type="text" name="user.userAge"></div> <div>請輸入地址:<input type="text" name="user.userAddress"></div> <div>請輸入手機:<input type="text" name="user.userTelephone"></div> <div><input type="submit" value="註冊"></div> </form>
能夠看出,只須要保證請求參數的key值爲綁定的目標pojo對象中的 屬性名.屬性名.屬性名···便可java
<form action=""> <input type="checkbox" name="arr" value="1"> <input type="checkbox" name="arr" value="2"> <input type="checkbox" name="arr" value="3"> <!-- 多個checkbox,name屬性的值相同 --> </form>
在controller方法中的形參正則表達式
@RequestMapping("uri") public String toPage(int[] arr){ return ""; }
和簡單類型參數綁定相似,保證請求中的key/value數據的key值與形參名相同便可spring
//綁定的pojo類型 public class User { private Integer userAccount; private String userName; private String userPassword; private Integer userAge; private String userAddress; private String userTelephone; //省略get/set方法 } public class UserVo { //將請求中參數對應的pojo集合放在另外一個包裝類中做爲屬性 private List<User> users; public List<User> getUsers() { return users; } public void setUsers(List<User> users) { this.users = users; } } //controller方法的形參 @RequestMapping("uri") public String test(UserVo uservo){ return page; }
使用List接收頁面提交的批量數據會被綁定爲list<pojo>類型的數據,但不能直接經過list<pojo>形參進行接收,而是經過另外一個包裝pojo接收,在包裝pojo中定義list<pojo>屬性數組
<form action=""> <div> <input type="text" name="users[0].userAccount" value=""> <input type="text" name="users[0].userName" value=""> <input type="text" name="users[0].userPassword" value=""> <input type="text" name="users[0].userAge" value=""> <input type="text" name="users[0].userAddress" value=""> <input type="text" name="users[0].userTelephone" value=""> </div> <div> <input type="text" name="users[1].userAccount" value=""> <input type="text" name="users[1].userName" value=""> <input type="text" name="users[1].userPassword" value=""> <input type="text" name="users[1].userAge" value=""> <input type="text" name="users[1].userAddress" value=""> <input type="text" name="users[1].userTelephone" value=""> </div> <div> <input type="text" name="users[2].userAccount" value=""> <input type="text" name="users[2].userName" value=""> <input type="text" name="users[2].userPassword" value=""> <input type="text" name="users[2].userAge" value=""> <input type="text" name="users[2].userAddress" value=""> <input type="text" name="users[2].userTelephone" value=""> </div> </form>
1. 項目中,一般使用較可能是前端的校驗,好比頁面中js校驗。對於安全要求較高點建議在服務端進行校驗。瀏覽器
2. 服務端校驗:緩存
3. 簡單開發應用:SpringMVC主要使用Hibernate的校驗框架(和hibernate沒有任何關係)。校驗思路就是頁面提交請求的參數,請求到controller方法中,使用validation進行校驗。若是校驗出錯,將錯誤信息展現到頁面。安全
<mvc:annotation-driven validator="validator"></mvc:annotation-driven> <!-- 配置校驗器 --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <!-- 配置第三方提供的校驗器類 :Hibernate校驗器類--> <property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property> <!-- 指定校驗使用的資源文件,在文件中配置校驗錯誤信息文件源 --> <property name="validationMessageSource" ref="messageSource"></property> </bean> <!-- 配置校驗信息錯誤文件源,能夠配置多個 --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <!-- 會自動解析爲當前類路徑下,名爲validationMessage1.properties的文件 --> <value>classpath:validationMessage1</value> </list> </property> <!-- 指定解析文件的編碼格式 --> <property name="fileEncodings" value="utf-8"></property> <!-- 指定對資源文件內容的緩存時間,單位爲秒 --> <property name="cacheSeconds" value="120"></property> </bean>
package user_manage.pojo; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; public class User { //驗證正則表達式,regexp寫正則表達式 @Pattern(regexp="[0-9]{10}",message="{User.userAccount.pattern.error}") private Integer userAccount; //校驗非空 @NotNull(message="{User.userName.null.error}") private String userName; //校驗密碼長度必須大於6且小於16個字符長度 //min指定最小長度,max指定最大長度,message指定校驗出錯時顯示的信息 @Size(min=6,max=16,message="{User.userPassword.length.error}") private String userPassword; private Integer userAge; private String userAddress; private String userTelephone; private String userImage; //省略get/set方法 }
在須要校驗的pojo形參前邊添加@Validated,在須要校驗的pojo後邊添加BindingResult Result接收校驗出錯信息mvc
注意:@Validated和BindingResult bindingResult是配對出現(一個@Validated對應一個BindingResult ),而且形參順序是固定的(一前一後)。@RequestMapping("/") public String userLogin(@Validated User user,BindingResult result){ //能夠經過BindingResult對象獲取到全部的錯誤信息,而且能夠經過該對象將錯誤信息發送到客戶端頁面 List<ObjectError> errors=result.getAllErrors(); for(ObjectError error:errors){ System.out.println(error.getDefaultMessage()); } model.addAttribute("errors", result); return "login"; }
4. 分組校驗:在pojo中定義校驗規則,而pojo是被多個 controller所共用,當不一樣的controller方法對同一個pojo進行校驗,每一個controller方法可能會須要須要不一樣的校驗規則。能夠定義多個校驗分組(實際上是一個java接口),分組中定義有哪些規則,每一個controller方法使用不一樣的校驗分組
public interface validatorGroup1 { //不須要定義任何方法,只用定義一個接口便可,該接口就表示一個校驗器分組 } public interface validatorGroup2 { //不須要定義任何方法,只用定義一個接口便可,該接口就表示一個校驗器分組 } //將User類中的校驗規則分到到validatorGroup1分組中,經過groups指定,能夠寫多個分組 public class User { //驗證正則表達式,regexp寫正則表達式,groups表示將該校驗規則添加到validatorGroup1和validatorGroup2兩個分組中 @Pattern(regexp="[0-9]{10}",message="{User.userAccount.pattern.error}",groups={validatorGroup1.class,validatorGroup2.class}) private Integer userAccount; //校驗非空 @NotNull(message="{User.userName.null.error}",groups={validatorGroup1.class}) private String userName; //校驗密碼長度必須大於6且小於16個字符長度 //min指定最小長度,max指定最大長度,message指定校驗出錯時顯示的信息 @Size(min=6,max=16,message="{User.userPassword.length.error}",groups={validatorGroup1.class}) private String userPassword; private Integer userAge; private String userAddress; private String userTelephone; //省略get/set方法 }
@RequestMapping("/") public String userLogin1(@Validated(value={validatorGroup1.class}) User user,BindingResult result){ //能夠經過BindingResult對象獲取到全部的錯誤信息,而且能夠經過該對象將錯誤信息發送到客戶端頁面 List<ObjectError> errors=result.getAllErrors(); for(ObjectError error:errors){ System.out.println(error.getDefaultMessage()); } model.addAttribute("errors", result); return "login"; } @RequestMapping("/") public String userLogin2(@Validated(value={validatorGroup2.class}) User user,BindingResult result){ //能夠經過BindingResult對象獲取到全部的錯誤信息,而且能夠經過該對象將錯誤信息發送到客戶端頁面 List<ObjectError> errors=result.getAllErrors(); for(ObjectError error:errors){ System.out.println(error.getDefaultMessage()); } model.addAttribute("errors", result); return "login"; }
1. 處理思路:系統中異常包括兩類,預期異常和運行時異常RuntimeException,前者經過捕獲異常從而獲取異常信息,後者主要經過規範代碼開發、測試經過手段減小運行時異常的發生。系統的dao、service、controller出現都經過throws Exception向上拋出,最後由springmvc前端控制器交由異常處理器進行異常處理,springmvc提供全局異常處理器(一個系統只有一個異常處理器)進行統一異常處理。以下圖
2. 自定義異常類,該類會針對程序中預期可能會出現的異常,會拋出此類異常
public class MyException extends Exception { private String message; public MyException(String message) { super(message); this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
3. 定義全局異常處理器,系統遇到異常,在程序中手動拋出,dao拋給service、service給controller、controller拋給前端控制器,前端控制器調用全局異常處理器。全局異常處理器處理思路:解析出異常類型;若是該 異常類型是系統 自定義的異常,直接取出異常信息,在錯誤頁面展現;若是該 異常類型不是系統 自定義的異常,構造一個自定義的異常類型(信息爲「未知錯誤」)。springmvc提供一個HandlerExceptionResolver接口,定義全局異常處理器必須實現該接口
public class MyHandlerExceptionResolver implements HandlerExceptionResolver { @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // handler就是處理器適配器要執行的Handler對象(也就是Controller中的方法) // 解析出異常類型 // 若是該 異常類型是系統 自定義的異常,直接取出異常信息,在錯誤頁面展現 MyException myException = null; if(ex instanceof MyException){ myException = (MyException)ex; }else{ myException = new MyException("未知錯誤"); } //錯誤信息 String message = myException.getMessage(); ModelAndView modelAndView = new ModelAndView(); //將錯誤信息傳到頁面 modelAndView.addObject("message", message); //指向錯誤頁面 modelAndView.setViewName("error"); return modelAndView; } }
4. 顯示錯誤信息的頁面:
5. 在SpringMVC的配置文件springmvc.xml配置全局異常處理器:
<!--只要實現了HandlerExceptionResolver接口並掃描到SpringMVC應用容器中,就是全局異常處理器--> <bean class="user_manage.exception.MyHandlerExceptionResolver"></bean>
6. 測試:只須要在service層或controller層中任意一處須要手動拋出自定義的MyException異常。若是是程序中手動拋出的異常,在錯誤頁面中顯示自定義的異常信息;若是不是手動拋出異常說明是一個運行時異常,在錯誤頁面只顯示「未知錯誤」。若是與業務功能相關的異常,建議在service中拋出異常。與業務功能沒有關係的異常,建議在controller中拋出。
1. 數據回顯指從頁面提交請求數據後,若是請求不符合要求或者出現錯誤,將剛纔提交的數據回顯到剛纔的提交頁面。
2. 實現方法:請求中攜帶的數據一般經過Controller中的方法形參接收
springmvc默認對pojo數據進行回顯。pojo數據傳入controller方法後,springmvc自動將pojo數據放到request域,而後向指定的jsp頁面中發送該請求,在jsp頁面中顯示數據,使用@ModelAttribute指定pojo回顯到頁面在request中的key,不必定是用來回顯到原頁面
@RequestMapping("/update") //ModelAttribute經過該註解就能夠將綁定到pojo形參的數據回顯到指定的頁面中,括號內指定回顯到jsp中的key值 public String userUpdate(@ModelAttribute("user") User user){ //指定返回的jsp頁面名 return "user"; }
//經過Model實現 @RequestMapping("/update") public String userUpdate(User user,Model model){ model.addAttribute("userdata", user); return "user"; } //經過ModelAndView實現 @RequestMapping("/update") public ModelAndView userUpdate(User user,Model model){ ModelAndView mv=new ModelAndView(); mv.addObject("userdata", user); mv.setViewName("user"); return "user"; }