拦截器源代码如下
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 { //最后执行 } }