拦截器,过滤器,全局异常处理器的使用

本文介绍了JavaWeb中的拦截器如何在请求前后添加逻辑,SpringMVC配置拦截器的方法,全局异常处理器的自定义和使用,以及过滤器的原理和实际应用,包括如何通过Order设置优先级和预处理请求内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一,拦截器: 

  主要两个文件,一个是创建拦截器:ProjectInterceptor.java,

 另一个是注册该拦截器:SpringMvcSupport

 

创建拦截器:

@Controller
public class ProjectInterceptor implements   HandlerInterceptor{    
                 //继承该HandlerInterceptor接口,按alt+Ins重写方法
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截之前");
        return false;                //true表示放行,false表示拦截并终止
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
               System.out.println("拦截之后");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
               System.out.println("拦截完成");
    }
}

   

注册拦截器:

@Controller
public class SpringMvcSuppor implements WebMvcConfigurer {
    @Resource
    private ProjectInterceptor  pp;        //导入拦截器


    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(pp).addPathPatterns("/**").excludePathPatterns("/user/**")     //这个表示拦截所有请求路径,但/user开头的路径不进行拦截

 registry.addInterceptor(pp).addPathPatterns("/**","/aa/**").excludePathPatterns("/cc", "/book/**")       //这个就表示拦截两个路径,排除两个路径
                                                                                                   //通过这个只是想说明可以同时传递多个参数用来拦截或排除路径 


;
                                                     
    }
}

 

总结:拦截器是对指定路径进行拦截处理,处理成功后就直接放行

 

 

 

 

 

 

 

二,全局异常处理器 

主要分为:自定义异常,抛出异常,捕获异常

 

自定义异常:

public class RunTimeE extends RuntimeException{           //这个类名是随便起的,继承RuntimeException的作用是能够保证编译过程可以正常通过,而不会因为异常导致编译失败
    String msg;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public RunTimeE(String msg) {
        this.msg = msg;
    }
}

 

抛出异常:

@RequestMapping("/aa")
@RestController
public class AAController {   

 @RequestMapping("/bb")
    public String ee(){
        try {
            int i=1/0;
        } catch (Exception e) {
            throw new RunTimeE("我失败了");
        }
       return "成功";
    }

}

 

捕获异常:

@RestControllerAdvice
public class ProjectExceptionHandler {
    @ExceptionHandler(RunTimeE.class)
    public String aa(RunTimeE e){

         return  e.getMsg();
    }
}

当访问“/aa/bb" , 打印的结果是”我失败了"

 

 

 

 

三,过滤器

过滤器主要用于处理请求之前或响应之后修改它们,我们可以使用Filter接口实现一个过滤器

过滤器的注册有两种方法

第一种(这是常用的一种方法,它能指定优先级)

直接创建一个过滤器到IOC容器中,在IOC容器中能够自动识别对应的过滤器并让它发挥作用

import javax.servlet.Filter;           //该接口来自这个包

@Component
@Order(-1)             //当有多个Filter时,数值越小,优先级就越高
public class MyFilter implements Filter {    //继承了Filter接口就表示该Bean对象是一个过滤器对象
 @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        System.out.println("请求之前");

        chain.doFilter(request,response);        //将请求进行放行,你也可以将这个看成是将目标函数复制到这里来了,
                                              //其实这个就相当于代指所要运行的目标函数

        
        request.getParameter("name")       //获取请求体中的get请求参数


        System.out.println("响应之后");
    }
 
 
}




//一个接口
 @RequestMapping("/aa")
    public String aa(){
        System.out.println("运行中");
        return "成功";
    }




当发送接口:localhost:8080/aa?name=zhan
打印结果为:
   请求之前
   运行中
   zhan
   响应之后

 

 

第二种:通过 @WebFilter 注解来标记一个 Filter过滤器,但是要在启动类中注册该过滤器

(这是比较老的一种方式,一般不常用)

首先标注过滤器:

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("-----doFilter-----");
        chain.doFilter(request, response);
    }
}

-

-

-

-

然后在启动类中注册该过滤器

@SpringBootApplication
@ServletComponentScan
public class FilterdemoApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(FilterdemoApplication.class, args);
    }
 
}//@ServletComponentScan 注解虽然名字带了 Servlet,
 //但是实际上它不仅仅可以扫描项目中的 Servlet 容器,也可以扫描 Filter 和 Listener
 //只要被扫描到,它就能自动发挥作用

 

 

总结:过滤器可以对任何请求进行预处理,是无法终止请求的

 

 

过滤器的实际应用方法:

import javax.servlet.Filter;           //该接口来自这个包

@Component
@Order(-1)             //当有多个Filter时,数值越小,优先级就越高
public class MyFilter implements Filter {    //继承了Filter接口就表示该Bean对象是一个过滤器对象
 @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        System.out.println("请求之前");

                                              
        
      String  name=request.getParameter("name")       //获取请求体中的get请求参数
            if(name.equals("zhan"){
                 chain.doFilter(request,response);        //将请求进行放行,你也可以将这个看成是将目标函数复制到这里来了,

            }else{
               
                response.setContentType("text/html;charset=utf-8");
                PrintWriter writer = response.getWriter();
                writer.write("你好");        //这个就是直接使用响应体的数据流打印结果
               }


      System.out.println("响应之后");
    }
 
 
}




//一个接口
 @RequestMapping("/aa")
    public String aa(){
        System.out.println("运行中");
        return "成功";
    }




当发送接口:localhost:8080/aa?name=zhan
打印结果为:
   请求之前
   运行中
   响应之后
响应结果是: 成功




当发送接口: localhost:8080/sldk/sel
打印结果是:
   请求之前
   响应之后
响应结果是: 你好

从这两个接口运行可以看出,如果没有传递get参数: name

那么目标函数就不会被调用,可以直接通过响应体响应出你指定的数据

在响应数据给别人之后,过滤器中的函数还是接着往下运行,直到运行完毕

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值