(七)拦截器

        拦截器属于AOP的一种实现,在现在的开发之中如果不是提供拦截器,那么基本上这个框架的设计就属于失败的设计,而在SpringMVC里面也自然提供有拦截器的操作.

        在Spring里面提供有一个专门的拦截器实现接口:org.springframework.web.servlet.HandlerInterceptor.在这个接口里面一共定义有三个方法:

操作执行前拦截:

default boolean preHandle(HttpServletRequest request,
                          HttpServletResponse response,
                          java.lang.Object handler)
                   throws java.lang.Exception

执行时拦截

default void postHandle(HttpServletRequest request,
                        HttpServletResponse response,
                        java.lang.Object handler,
                        @Nullable
                        ModelAndView modelAndView)
                 throws java.lang.Exception

   操作执行完拦截

default void afterCompletion(HttpServletRequest request,
                             HttpServletResponse response,
                             java.lang.Object handler,
                             @Nullable
                             java.lang.Exception ex)
                      throws java.lang.Exception

大部分情况下都会在preHandle里面进行处理,因为拦截器主要处理的就是拦截前的操作,

范例:定义一个拦截器

package cn.zwb.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class MyHandler implements HandlerInterceptor{

	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse response, Object obj, Exception ex)
			throws Exception {
		System.out.println("##############33执行处理完毕");
		
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("##########执行中拦截");
		
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
		System.out.println("#############3执行前拦截");
		return true;
	}
		
}

        随后在applicationContext.xml文件里面去定义拦截器的使用

		<mvc:interceptors>
			<mvc:interceptor>
				<mvc:mapping path="/pages/**/*.action"/>
				<bean class="cn.zwb.interceptor.MyHandler"></bean>
			</mvc:interceptor>
		</mvc:interceptors>

        在整个SpringMVC里面采用了同样结构的资源定位符号,此处表示在pages目录下的所有的*.action都进行拦截

        在整个的拦截器的处理过程之中,将处理的步骤拆分的非常细,但是拦截器最为重要的做法是进行输入数据的拦截操作,可是这个操作要如何进行呢?要想进行输入数据的拦截,那么重点就要放在perHandler()方法上,


        如果说这个方法返回true表示正常向下执行,而返回false表示不执行后续的操作.

        要想进行数据验证拦截操作.那么关键的部分就在于preHandle()方法里面的Object参数.

org.springframework.web.method.HandlerMethod

在这个类里面定义有如下的一堆操作方法:

        触发此拦截器的程序类(Action):public Object getBean();

        取得处理的方法:public Method get,ethod();

        取得Bean的类型:public Class<?> getBeanType();

        取得方法的参数数据:

public MethodParameter[] getMethodParameters()

                取得方法:

public java.lang.reflect.Method getMethod()
                取得参数名称:
public java.lang.String getParameterName()

                取得参数类型:

public java.lang.Class<?> getParameterType()

范例:取得要操作的Action数据:

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
			HandlerMethod hanm=(HandlerMethod)obj;
			
		System.out.println("#############3执行前拦截");
		System.out.println("操作的Action对象"+hanm.getBean()+",类型:"+hanm.getBeanType()+",方法名称:"+hanm.getMethod());
		MethodParameter[] methodParameters = hanm.getMethodParameters();
		for (MethodParameter methodParameter : methodParameters) {
			System.out.println("方法:"+methodParameter.getMethod()+",参数名称"+methodParameter.getParameterName());
		}
		return true;
	}

        此时只要是用户执行的操作,现在都可以利用拦截器取得.

        既然可以取得了基础内容,那么下面就可以实现信息的验证功能.

范例:实现拦截处理

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
			HandlerMethod hanm=(HandlerMethod)obj;
			
		System.out.println("#############3执行前拦截");
		System.out.println("操作的Action对象"+hanm.getBean()+",类型:"+hanm.getBeanType()+",方法名称:"+hanm.getMethod());
		MethodParameter[] methodParameters = hanm.getMethodParameters();
		for (MethodParameter methodParameter : methodParameters) {
			System.out.println("方法:"+methodParameter.getMethod()+",参数名称"+methodParameter.getParameterName());
			
			
		}
		try{
			String fieldName=hanm.getMethod().getName()+"Rule";
			Field field=hanm.getBean().getClass().getDeclaredField(fieldName);
			field.setAccessible(true);
			String rules=(String) field.get(hanm.getBean());//取得规则信息
			System.out.println("**********取得规则信息**********"+rules);
			String result[]=rules.split("\\|");  //拆分验证规则
			for (String string : result) {
				String temp[]=string.split(":");
				String paramValue=request.getParameter(temp[0]);
				System.out.println("参数名称:"+temp[0]+",参数内容:"+paramValue+",验证规则:"+temp[1]);
			}
		}catch(Exception e){
			
		}
		return true;
	}

        但是对于拦截器的操作还需要考虑一种情况,那么就是表单的文件上传问题.对于上传文件一般都会要求有限制,例如,本次的上传操作只能够是图片,那么就需要在拦截器里面继续进行拦截的配置.

范例:定义表单

<body>
	<form action="pages/hello/insert.action" method="post" enctype="multipart/form-data">
		新闻编号:<input type="text" id="nid" name="nid" value="999"><br>
		消息名称:<input type="text" id="title" name="title" value="啦啦啦"><br>
		上传文件:<input type="file" id="pic" name="pic" ><br>
		<input type="submit" value="提交">
		<input type="reset" value="重置">
	</form>
</body>

        现在发现对于上传的文件并没有设置相应的验证规则,所以现在进一步完善拦截器

范例:拦截非法图片信息

package package cn.zwb.interceptor;


import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import org.springframework.core.MethodParameter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;


public class MyHandler implements HandlerInterceptor{


	@Override
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse response, Object obj, Exception ex)
			throws Exception {
		System.out.println("##############33执行处理完毕");
		
	}


	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("##########执行中拦截");
		
	}


	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception {
			HandlerMethod hanm=(HandlerMethod)obj;
			
		System.out.println("#############3执行前拦截");
		System.out.println("操作的Action对象"+hanm.getBean()+",类型:"+hanm.getBeanType()+",方法名称:"+hanm.getMethod());
		MethodParameter[] methodParameters = hanm.getMethodParameters();
		for (MethodParameter methodParameter : methodParameters) {
			System.out.println("方法:"+methodParameter.getMethod()+",参数名称"+methodParameter.getParameterName());
			
			
		}
		//定义一个专门用于保存错误信息的map集合
		Map<String, String> errors=new HashMap<String, String>();
		try{
			String fieldName=hanm.getMethod().getName()+"Rule";
			Field field=hanm.getBean().getClass().getDeclaredField(fieldName);
			field.setAccessible(true);
			String rules=(String) field.get(hanm.getBean());//取得规则信息
			System.out.println("**********取得规则信息**********"+rules);
			String result[]=rules.split("\\|");  //拆分验证规则
			for (String string : result) {
				String temp[]=string.split(":");
				String paramValue=request.getParameter(temp[0]);
				System.out.println("参数名称:"+temp[0]+",参数内容:"+paramValue+",验证规则:"+temp[1]);
				if(paramValue==null){
					errors.put(temp[0], "数据内容不允许为空");
					return false;
				}else{
					if("int".equalsIgnoreCase(temp[1])){
						if(!paramValue.matches("\\d+")){
							errors.put(temp[0], "数据类型必须是整数!!");
							return false;
						}
					}
				}
			}
		}catch(Exception e){}
		boolean flag=true;
		if(errors.size()>0){  //有错误信息再进行跳转
			flag=false;
		}else{  //表示现在的基础信息验证完成.下面需要判断是否有上传文件
			MultipartResolver mr=new CommonsMultipartResolver();
			if(mr.isMultipart(request)){  //如果有文件上传
				MultipartRequest mreq=(MultipartRequest)request;//取得上传文件的内容
				Map<String,MultipartFile > map= mreq.getFileMap();  //取得所有的上传文件
				if(map.size()>0){
					Field field=hanm.getBean().getClass().getDeclaredField("mimeRule");
					field.setAccessible(true);
					String mime=(String)field.get(hanm.getBean());
					System.out.println(mime);
					String resultMime[]=mime.split(",");
					Iterator<Map.Entry<String,MultipartFile>> it=map.entrySet().iterator();
					
					while(it.hasNext()){
						Map.Entry<String,MultipartFile> me=it.next();
						String fileName=me.getKey();
						MultipartFile file=me.getValue();  //取得文件内容
						System.out.println("文件名称:"+fileName+",文件内容:"+file+",\n"+file.getContentType());
							if(!this.isExists(resultMime, file.getContentType())){
								errors.put(fileName, "上传了非法文件");
								flag=false;
								break;
						}
					}
				}
			}
		}
		if(!flag){
			System.out.println(errors);
			request.getRequestDispatcher("/errors.jap").forward(request, response);
			return false;
		}
		return true;
	}
	public boolean isExists(String data[],String str){
		for (String string : data) {
			if(str.equals(string)){
				return true;
						
			}
		}
		return false;
	}
		
}
}
        


猜你喜欢

转载自blog.csdn.net/qq1019648709/article/details/80941503
今日推荐