拦截器源代码如下
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;
void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception;
void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception;
}
先来看看这个方法boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler),里面有一个handler,其实它属于HandlerMethod。
public Object getBean() {
//获得要操作控制层
return this.bean;
}
public Method getMethod() {
//获得要操作的方法
return this.method;
}
public MethodParameter[] getMethodParameters() {
//获得要操作的参数
return this.parameters;
}
所以此方法是在前置控制器后,真实控制器之前进行操作的。
而postHandle里面含有ModleAndView,这个是在真实控制器操作之后进行的。
先编写正则验证类,此类把构造器私有化,所有的验证方法都是类方法。
import org.springframework.util.StringUtils;
/**
* 类说明 专门对数据格式进行认证
* @author rfk
*/
public class ValueRuleValidator {
private ValueRuleValidator() {}
/**
* 使用正则验证数据是否为整数
* @param str 需要验证的数据
* @return 如果数据全部为数字,返回为真,否则返回为假
*/
public static boolean isInt(String str) {
if(!StringUtils.isEmpty(str)) {
return str.matches("\\d+");
}
return false;
}
/**
* 使用正则验证数据是否为long类型
* @param str 需要验证的数据
* @return 需要验证的数据如果全部是数字返回为true,否则返回为false
*/
public static boolean isLong(String str) {
return isInt(str);
}
/**
* 使用正则验证数据是否为double类型
* @param str 需要验证的数据
* @return 需要验证的数据如果为Double类型返回为true,否则返回为false
*/
public static boolean isDouble(String str) {
if(!StringUtils.isEmpty(str)) {
return str.matches("\\d+(\\.\\d+)?");
}
return false;
}
/**
* 使用正则验证数据是否为date类型
* @param str 需要验证的数据
* @return 如果验证的数据为xxxx-xx-xx类型返回为true,否则返回为false,传输过来的数据需要在前面处理成xxxx-xx-xx类型
*/
public static boolean isDate(String str) {
if(!StringUtils.isEmpty(str)) {
return str.matches("\\d{4}-\\d{2}-\\d{2}");
}
return false;
}
/**
* 使用正则验证数据是否为xxxx-xx-xx xx:xx:xx类型
* @param str 需要验证的数据
* @return 验证的数据符合标准格式返回为true,否则返回为false
*/
public static boolean isDateTime(String str) {
if(!StringUtils.isEmpty(str)) {
str.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}");
}
return false;
}
/**
* 验证用户输入的验证码和后台验证码是否一致
* @param str 用户输入的验证码
* @param rand 后台获得的验证码
* @return 如果验证码一致,返回为true,否则返回为false;
*/
public static boolean isRand(String str,String rand) {
if(!StringUtils.isEmpty(str) && !StringUtils.isEmpty(rand)) {
return str.equalsIgnoreCase(rand);
}
return false;
}
/**
* 判断数据是否为boolean类型
* @param str 需要验证的数据
* @return 如果数据为boolen类型,返回为true,否则为false;
*/
public static boolean isBoolean(String str) {
if(!StringUtils.isEmpty(str)) {
return "true".equalsIgnoreCase(str)||"false".equalsIgnoreCase(str);
}
return false;
}
/**
*
* @param rule 编写的规则
* @param contentType 传输数据类型
* @return
*/
public static boolean isPhoto(String rule,String contentType) {
if(!StringUtils.isEmpty(rule)&&!StringUtils.isEmpty(contentType)) {
String result [] =rule.split("\\|");
for(int x=0;x<result.length;x++) {
if(contentType.equalsIgnoreCase(result[x]))
return true;
}
}
return false;
}
}
然后编写一个数据验证类,此类主要是针对常用数据判断;
/**
* 类说明
*
* @author rfk
*/
public class ValidationUtil {
private HttpServletRequest request;
private String rule;
private MessageSource message;
private Map<String, String> map = new HashMap<>();
public ValidationUtil(HttpServletRequest request, String rule, MessageSource message) {
this.request = request;
this.rule = rule;
this.message = message;
this.handleValidateion();
}
/**
*
* @return 返回验证的错误信息
*/
public Map<String, String> getErrors() {
return this.map;
}
/**
* 进行数据验证
*/
private void handleValidateion() {
String[] result = rule.split("//|");
for (int x = 0; x < result.length; x++) {
String[] temp = result[x].split(":");
String parameterValue = this.request.getParameter(temp[0]);
switch (temp[1]) {
case "int":
//int.msg=验证的数据不是int类型
if (!ValueRuleValidator.isInt(parameterValue)) {
this.map.put(temp[0], this.message.getMessage("int.msg", null, null));
}
break;
case "long":
if (!ValueRuleValidator.isLong(parameterValue)) {
this.map.put(temp[0], this.message.getMessage("long.msg", null, null));
}
break;
case "double":
if (!ValueRuleValidator.isDouble(parameterValue)) {
this.map.put(temp[0], this.message.getMessage("int.msg", null, null));
}
break;
case "string":
if (!StringUtils.isEmpty(parameterValue)) {
this.map.put(temp[0], this.message.getMessage("string.msg", null, null));
}
break;
case "date":
if (!ValueRuleValidator.isDate(parameterValue)) {
this.map.put(temp[0], this.message.getMessage("date.msg", null, null));
}
break;
case "datatime":
if (!ValueRuleValidator.isDateTime(parameterValue)) {
this.map.put(temp[0], this.message.getMessage("datetime.msg", null, null));
}
break;
case "rand":
if (!ValueRuleValidator.isRand(parameterValue,
(String) this.request.getSession().getAttribute("rand"))) {
this.map.put(temp[0], this.message.getMessage("rand.msg", null, null));
}
break;
case "boolean":
if (!ValueRuleValidator.isBoolean(parameterValue)) {
this.map.put(temp[0], this.message.getMessage("boolean.msg", null, null));
}
break;
}
}
}
}
编写一个文件上传的类,主要是针对上传文件进行判断
public class FileValidationUtil {
private HttpServletRequest request;
private MultipartResolver multipartResolver;
private String key;
private MessageSource messageSource;
private Map<String, String> errors = new HashMap<>();
/**
*
* @param request
* @param multipartResolver 封装后的表单
* @param key 验证的规则
* @param messageSource 国际化资源读取类
*/
public FileValidationUtil(HttpServletRequest request, MultipartResolver multipartResolver, String key,
MessageSource messageSource) {
super();
this.request = request;
this.multipartResolver=new CommonsMultipartResolver();
this.key = key;
this.messageSource = messageSource;
}
public void validateMime() {
if (this.multipartResolver.isMultipart(request)) {
String rule = this.messageSource.getMessage(this.key, null, null);
if (request instanceof DefaultMultipartHttpServletRequest) {
DefaultMultipartHttpServletRequest newRequest = (DefaultMultipartHttpServletRequest) request;
Map<String, MultipartFile> filemap = newRequest.getFileMap();
if (filemap.size() > 0) {
Iterator<Map.Entry<String, MultipartFile>> iterator = filemap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, MultipartFile> mEntry = iterator.next();
if (mEntry.getValue().getSize() > 0) {
if (!ValueRuleValidator.isPhoto(rule, mEntry.getValue().getContentType())) {
this.errors.put(mEntry.getKey(),
messageSource.getMessage(this.key + "error", null, null));
}
}
}
}
}
}
}
public Map<String, String> getErrors() {
return this.errors;
}
}
编写拦截器
public class VaildationInterceptor implements HandlerInterceptor {
private static final Log log = LogFactory.getLog(VaildationInterceptor.class);
@Resource
private MessageSource message;
/**
* 此方法主要是在org.springframework.web.servlet.DispatcherServlet之后,Controller进行数据验证
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod newHandler = (HandlerMethod) handler;
// 拼接出资源文件读取的key,例如 emp.add
String key = newHandler.getBean().getClass().getSimpleName() + "." + newHandler.getMethod();
// 根据key获得规则,比如emp.add=id:int|name:string|biredate:date
String rule = this.message.getMessage(key, null, null);
if (rule != null) {
// 进行数据的认证,此处主要是标准数据的认证
ValidationUtil validat = new ValidationUtil(request, rule, message);
//基本数据验证,如果有错误返回为false
/* ValidationUtil validat = new ValidationUtil(request, rule, message);
* FileValidationUtil fileValidationUtil =new FileValidationUtil(request, key, message);
* if (validat.getErrors().size() > 0 ||fileValidationUtil.getErrors().size() > 0 ) {
* if(validat.getErrors().size() > 0){
* //怎么做
* }
* if(fileValidationUtil.getErrors().size() > 0){
* //怎么做
* }
* if(validat.getErrors().size() > 0 &&fileValidationUtil.getErrors().size() > 0 ){
* //怎么做。
* }
// 有数据没有通过认证,讲数据放到errors里面
request.setAttribute("errors", validat.getErrors());
String errorsUrl = null;
try {
// 例如emp.add.err.page页面就是数据增加的页面
errorsUrl = this.message.getMessage(key + ".error.page", null, null);
} catch (Exception e) {
errorsUrl = this.message.getMessage("error.page", null, null);
log.error(e);
}
request.getRequestDispatcher(errorsUrl).forward(request, response);
return false;
}
*/
if (validat.getErrors().size() > 0) {
// 有数据没有通过认证,讲数据放到errors里面
request.setAttribute("errors", validat.getErrors());
String errorsUrl = null;
try {
// 例如emp.add.err.page页面就是数据增加的页面
errorsUrl = this.message.getMessage(key + ".error.page", null, null);
} catch (Exception e) {
errorsUrl = this.message.getMessage("error.page", null, null);
log.error(e);
}
request.getRequestDispatcher(errorsUrl).forward(request, response);
return false;
}else {
//基本数据判断无错误,肯定进入此处,所以此处需要判断是否有错误,有错误返回false,无错误返回true
/*本来想讲此处验证放到ValidationUtil validat = new ValidationUtil(request, rule, message);后面
* 后来发现如果放在他后面,判断错误使用||判断后,在放入错误时候仍然需要判断
*/
FileValidationUtil fileValidationUtil =new FileValidationUtil(request, key, message);
if(fileValidationUtil.getErrors().size()>0) {
request.setAttribute("errors", validat.getErrors());
String errorsUrl = null;
try {
// 例如emp.add.err.page页面就是数据增加的页面
errorsUrl = this.message.getMessage(key + ".error.page", null, null);
} catch (Exception e) {
errorsUrl = this.message.getMessage("error.page", null, null);
log.error(e);
}
request.getRequestDispatcher(errorsUrl).forward(request, response);
return false;
}
return true;
}
}
}
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
//此方法主要是在controller之后进行,所以此处可以获得modlerAndview
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
//最后执行
}
}