springmvc拦截器

拦截器源代码如下

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 {
		//最后执行
	}

}

猜你喜欢

转载自dan326714.iteye.com/blog/2396861