点滴记载,点滴进步,愿自己更上一层楼。加油!!!
所有代码都是基于上一篇,springmvc----json参数绑定
springmvc的参数校验,并不是传统的if else等等之类的代码,这里说的是框架校验。
springmvc的参数校验用的是hibernate的vaildation校验框架.
要求安全行较高的项目,都会做前台js校验+后台参数校验,这里仅仅代码仅仅作为引子,没有做那么全面。
示例开始。
既然要用到hibernate的vaildation校验框架,自然需要另外的jar包。将对应的jar依赖添加到pom中去。
org.hibernate
hibernate-validator
4.3.0.Final
javax.validation
validation-api
1.0.0.GA
添加一个校验框架专门用的xml springmvc-vaildation.xml
classpath:vaildation/Vaildations
文件中的classpath:vaildation/Vaildations对应着一个properties文件(Vaildations.properties)。
#user.account.notnull=用户名不能为空
#user.password.length=密码最大长度为12位
user.account.notnull=\u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a
user.password.length=\u5bc6\u7801\u6700\u5927\u957f\u5ea6\u4e3a12\u4f4d
由于中文有可能有问题,反正我这里一直乱码,网上搜索别人也有这种问题,有说什么将fileEncodings改成defaultEncoding,我这里不行,
还有的说在代码中做一层转换(这种方法可行,但是多了一层代码逻辑),建议直接将中文转成unicode编码。
controller代码
package com.soft.controller;
import com.soft.po.ValidationVo;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
* Created by xuweiwei on 2017/8/20.
*/
@Controller
public class TestVaildationController {
/**
* @Validated 用于激活ValidationVo中的校验,
* @param validationVo 传参数vo, 校验也在其中
* @param bindingResult 校验的结果都放在这里面。
* 注意:如果有多个vo,bindingResult需要和校验的vo成对出现,也就是像这种
* public ModelAndView vaildater01(@Validated ValidationVo validationVo, BindingResult bindingResult,
* @Validated XXXXVo validationVo, BindingResult xxxxResult)
* @return
*/
@RequestMapping("/testVaildater01")
public ModelAndView vaildater01(@Validated ValidationVo validationVo, BindingResult bindingResult) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("status", "success");
// 是否有错误信息
if (bindingResult.hasErrors()) {
// 获取全部的错误结果
List allerror = bindingResult.getAllErrors();
for (ObjectError objectError : allerror) {
// 打印错误消息
System.out.println(objectError.getDefaultMessage());
}
// 将错误消息显示到页面。
modelAndView.addObject("errors", allerror);
modelAndView.addObject("status", "error");
}
modelAndView.setViewName("test/testVaildate");
return modelAndView;
}
}
接收参数,校验参数的vo ValidationVo.java
package com.soft.po;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* Created by xuweiwei on 2017/8/20.
*/
public class ValidationVo {
@NotNull(message = "{user.account.notnull}")
private String account;
@Size(min=1, max=12,message = "{user.password.length}")
private String password;
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="false"%>
Title
是否有错误信息,无显示success,有显示error:${status}
${err.defaultMessage}
准备工作已经完毕,接下来进行测试。浏览器输入
http://localhost:8080/testVaildater01?password=123456789456123
上面可以看到打印出来的校验结果信息。结果前台jsp也进行了显示。
框架校验结束,但是上面的有局限性,如果有的需求不需要做这些的校验,但是又不想另行做一个vo,这是就需要用到校验分组了。
2 分组校验。
分组校验仅仅需要定义对应的接口。
package com.soft.vaildate;
/**
* Created by xuweiwei on 2017/8/20.
*/
public interface VaildateGroup {
// 里面不需要定义任何的方法,仅作为分组依据。
}
然后将这个分组接口加入到校验中,vo还是那个vo,只不过在校验password的时候加入了分组,此时仅仅在有该分组的时候才进行校验,如果再次输入上面的测试地址,密码长度的提示不在显示。
@Size(min=1, max=12,message = "{user.password.length}",groups = {VaildateGroup.class})
private String password;
测试结果。
另写一个action用于校验分组,
/**
* @Validated 用于激活ValidationVo中的校验,
* @param validationVo 传参数vo, 校验也在其中
* @param bindingResult 校验的结果都放在这里面。
* 注意:如果有多个vo,bindingResult需要和校验的vo成对出现,也就是像这种
* public ModelAndView vaildater01(@Validated ValidationVo validationVo, BindingResult bindingResult,
* @Validated XXXXVo validationVo, BindingResult xxxxResult)
* @return
*/
@RequestMapping("/testVaildater02")
public ModelAndView vaildater02(@Validated(value={VaildateGroup.class}) ValidationVo validationVo, BindingResult bindingResult) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("status", "success");
// 是否有错误信息
if (bindingResult.hasErrors()) {
// 获取全部的错误结果
List allerror = bindingResult.getAllErrors();
for (ObjectError objectError : allerror) {
// 打印错误消息
System.out.println(objectError.getDefaultMessage());
}
// 将错误消息显示到页面。
modelAndView.addObject("errors", allerror);
modelAndView.addObject("status", "error");
}
modelAndView.setViewName("test/testVaildate");
return modelAndView;
}
仔细看这个action跟01也就差了一句@Validated(value={VaildateGroup.class}),这个方法添加了分组校验,vo中加了VaildateGroup.class分组的都会校验,没加的不会校验。
如图所示,vo中仅仅password有分组,所以这里仅仅校验password 但是account的@NotNull并没有起作用。
如果多个controller公用一个vo ,有的需要校验,有的不需要校验,灵活运用分组即可。
这里仅仅做了两个简单的校验,没有太深入,请自行深入,这里只做引子。
点滴记载,点滴进步,愿自己更上一层楼。加油!!!