SpringMVC 拦截器

  拦截器属于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.jcn.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.jcn.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;

}

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

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

范例:在需要验证的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());

    }

    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>

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

范例:拦截非法图片信息

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;

        }

    }

}

以后的工作中如果使用的是SpringMVC,那么就使用如上的拦截器操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值