SpringMVC支持对Controller单元测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:mvc-dispatcher-servlet.xml",
})
@WebAppConfiguration
public class ControllerJUnitBase{
@Resource
private RequestMappingHandlerMapping handlerMapping;
@Resource
private RequestMappingHandlerAdapter handlerAdapter;
//执行request对象请求的action
public ModelAndView excuteAction(HttpServletRequest request,HttpServletResponse response)throws Exception{
HandlerExecutionChain chain = handlerMapping.getHandler(request);
final ModelAndView model = handlerAdapter.handle(request,response,chain.getHeader());
return model;
}
@Test
public void test throws Exception(){
//Mock构建request,response
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/api/user/login");
request.setParameter("mobile","190xxxx1234");
request.setMethod("POST");
MockHttpServletResponse response = new MockHttpServletResponse();
final ModelAndView mav = this.excuteAction(request,response);
Assert.assertEquals("user_login",mav.getViewName());
}
}
验证Web请求参数
一、通过Spring框架定义的Validator接口定义的校验
public class UserValidator implements Validator{
@Override
public boolean supports(Class<?> clazz){
return clazz.equals(User.class);
}
@Override
public void validate(Object target,Errors errors){
ValidationUtils.rejectIfEmpty(errors,"name","user.name.required","用户名不能为空");
User user = (User)target;
if(length > 10){
errors.rejectValue("name","user.name.too_long","用户不能超过20个字符");
}
}
}
在Controller里增加方法并以@InitBinder注解在对应的Controller方法中触发
@InitBinder
protected void initBinder(WebDataBinder binder){
binder.setValidator(new UserValidator());
}
@RequestMapping(method = RequestMethod.POST)
public String reg(@Validated User user,BindingResult result){
//如果校验没有通过
if(result.hasErrors()){
return "user";
}
if(user != null){
userService.saveUser(user);
}
return "user";
}
从页面提交的User对象,通过实现的UserValidator类校验,校验结果存入BindingResult对象中
二、支持JSR-303 Beam Validator定义的校验规范
不仅可以对Spring的MVC进行校验,也可以对Hibernate的存储对象进行校验
引入hibernate-validator,并开启MVC注解mvc:annotation-driven/
还需要对校验的meta类的属性做注解限制
- @Null 验证对象是否为空
- @NotNull 验证对象是否为非空
- @AssertTrue 验证Boolean对象是否为true
- @AssertFalse验证Boolean对象是否为false
- @Min 验证Number和String对象是否大于或等于指定的值
- @Max 验证Number和String对象是否小于或等于指定的值
- @DecimalMin 验证Number和String对象是否大于或等于指定的值,需要注意小数的精度问题
- @DecimalMax 验证Number和String对象是否小于或等于指定的值,需要注意小数点的精度问题
- @Size 验证对象(Array,Collection,Map,String)长度是否在给定的范围内
- @Digits 验证Number和String的构成是否合法
- @Past 验证Date和Calendar对象是否在当前时间之前
- @Future 验证Date和Calendar对象是否在当前时间之后
- @Pattern 验证String对象是否符合正则表达式的规则
此外hibernate-validator也提供了一些注解支持
- @NotEmpty 验证对象不为NULL也不为empty
- @NotBlank 验证对象NULL也不为empty,连续的空格也被认为是empty
- @Range 验证对象在指定的范围内
配置:只要队被校验的meta注解Constraint
public class User{
@NotNull
private String name;
}
然后Controller对应的方法中,给对应的参数@Valid注解
public String doRegister(@Valid User user,BindingResult result){
//校验没有通过
if(result.hasErrors()){
return "user";
}
if(user != null){
userService.saveUser(user);
}
return "user";
}
这样就完成了针对输入数据User对象的校验了,校验结果保存在BindingResult对象中
BindingResult参数如果放在验证参数的后面,那么错误信息是会绑定到此BindingResult上的,否则会抛出MethodArgumentNotValidException异常