若是须要将请求中的参数绑定到该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"; }