如何实现过滤器、拦截器和全局异常捕获?
目录
一、实现过滤器
1、创建过滤器
2、注册过滤器
3. 使用注解配置过滤器
4. 在Web.xml中配置过滤器
5. 过滤器的执行顺序
6. 过滤器的链式调用
二、实现拦截器
1、创建拦截器
2. 注册拦截器
3. 使用注解方式注册拦截器
4. 拦截器的执行顺序
5. 拦截器的匹配规则
6. 拦截器的高级使用
三、实现全局异常捕获
1、创建全局异常处理器
2. 使用@ExceptionHandler注解
3. 返回适当的响应
4. 记录异常信息
5. 配置多个全局异常处理器
一、实现过滤器
过滤器是Servlet规范的一部分,用于在请求到达Servlet之前或响应发送给客户端之后进行预处理和后处理。
1、创建过滤器
首先,需要创建一个实现javax.servlet.Filter接口的类,这个接口包含三个方法:init、doFilter和destroy:
import javax.servlet.*;
import java.io.IOException;public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化代码,过滤器启动时执行}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 在请求继续之前执行的代码System.out.println("Before processing request");// 继续执行过滤链中的下一个过滤器或目标资源(如Servlet)chain.doFilter(request, response);// 在请求处理之后执行的代码System.out.println("After processing request");}@Overridepublic void destroy() {// 清理代码,过滤器销毁时执行}}
2、注册过滤器
在Spring Boot中,使用FilterRegistrationBean来注册过滤器:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class FilterConfig {@Beanpublic FilterRegistrationBean<MyFilter> myFilterRegistration() {FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new MyFilter());registration.addUrlPatterns("/api/*"); // 指定过滤器应用的URL模式return registration;}}
3. 使用注解配置过滤器
如果使用的是Spring MVC或Spring Boot,可以通过在过滤器类上使用@Component注解来自动注册过滤器:
import javax.servlet.annotation.WebFilter;
import org.springframework.stereotype.Component;@Component@WebFilter(urlPatterns = "/api/*")
public class MyFilter implements Filter {// 实现init、doFilter和destroy方法
}
4. 在Web.xml中配置过滤器
在传统的Java EE应用中,可以在web.xml文件中配置过滤器:
<filter><filter-name>myFilter</filter-name><filter-class>com.example.MyFilter</filter-class></filter><filter-mapping><filter-name>myFilter</filter-name><url-pattern>/api/*</url-pattern></filter-mapping></filter>
5. 过滤器的执行顺序
过滤器的执行顺序取决于它们在web.xml中的声明顺序,或者在Spring配置中的注册顺序。如果想控制多个过滤器的执行顺序,可以使用setOrder方法:
registration.setOrder(1); // 数字越小,优先级越高
6. 过滤器的链式调用
过滤器可以形成一个链,一个请求会按顺序通过多个过滤器。在doFilter方法中,通过调用chain.doFilter(request, response)来传递请求到下一个过滤器或目标资源。
二、实现拦截器
在Spring框架中,拦截器(Interceptor)用于在处理HTTP请求之前、之后或请求处理过程中进行拦截,以实现如身份验证、日志记录、权限检查等功能。
1、创建拦截器
创建一个实现HandlerInterceptor接口的类。这个接口包含三个方法:preHandle、postHandle和afterCompletion:
import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndViewimport javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在控制器执行之前调用System.out.println("Pre Handle");// 如果返回true,继续流程;如果返回false,停止流程return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 在控制器执行之后调用System.out.println("Post Handle");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 请求完成后调用System.out.println("Request and Response is completed");}}
2. 注册拦截器
在Spring MVC配置中注册拦截器。如果你使用的是Spring Boot,可以通过添加一个配置类来实现:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate MyInterceptor myInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 指定拦截器应用的URL模式registry.addInterceptor(myInterceptor).addPathPatterns("/api/*"); }
}
3. 使用注解方式注册拦截器
如果你的拦截器不需要依赖注入,你也可以使用@Component注解和WebMvcConfigurer接口来自动注册拦截器:
import org.springframework.stereotype.Component;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Componentpublic class MyWebMvcConfigurer implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new MyInterceptor()).addPathPatterns("/api/*");}}
4. 拦截器的执行顺序
拦截器的执行顺序可以通过实现Ordered接口或使用@Order注解来控制:
public class MyInterceptor implements HandlerInterceptor, Ordered {@Overridepublic int getOrder() {return 1; // 数字越小,优先级越高}// 实现其他方法}
5. 拦截器的匹配规则
拦截器可以通过addPathPatterns方法指定匹配的URL模式,也可以通过excludePathPatterns方法指定排除的URL模式。
6. 拦截器的高级使用
拦截器不仅可以用于简单的日志记录和权限检查,还可以用于复杂的业务逻辑,如请求预处理、响应后处理等。
三、实现全局异常捕获
在Spring框架中,实现全局异常处理的一种常见方法是使用@ControllerAdvice注解。这个注解允许定义一个类来全局处理异常,而不需要在每个控制器中单独处理。
1、创建全局异常处理器
使用@ControllerAdvice注解创建一个全局异常处理器类。可以在这个类中定义一个或多个方法来处理不同类型的异常。
使用@ControllerAdvice和@ExceptionHandler:
import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.ResponseBody;@ControllerAdvicepublic class GlobalExceptionHandler {@ExceptionHandler(Exception.class)@ResponseBodypublic ResponseEntity<String> handleException(Exception e) {// 可以根据不同的异常类型返回不同的HTTP状态码return new ResponseEntity<>("An error occurred: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);}// 可以添加更多的异常处理方法@ExceptionHandler(NullPointerException.class)@ResponseBodypublic ResponseEntity<String> handleNullPointerException(NullPointerException e) {return new ResponseEntity<>("Null pointer error: " + e.getMessage(), HttpStatus.BAD_REQUEST);}// 处理特定业务异常@ExceptionHandler(CustomBusinessException.class)@ResponseBodypublic ResponseEntity<String> handleCustomBusinessException(CustomBusinessException e) {return new ResponseEntity<>(e.getMessage(), HttpStatus.FORBIDDEN);}}
2. 使用@ExceptionHandler注解
在全局异常处理器类中,使用@ExceptionHandler注解来指定哪些异常应该由哪个方法处理。可以为通用异常和特定异常类型定义不同的处理方法。
3. 返回适当的响应
在异常处理方法中可以构造一个适当的响应来通知客户端发生了错误。通常,这包括一个错误消息和一个HTTP状态码。使用ResponseEntity来构建这样的响应。
4. 记录异常信息
在异常处理方法中,可以将异常信息记录到日志中,这对于调试和监控应用程序非常有用。
import org.slf4j.Logger;import org.slf4j.LoggerFactory;@ControllerAdvicepublic class GlobalExceptionHandler {private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);@ExceptionHandler(Exception.class)@ResponseBodypublic ResponseEntity<String> handleException(Exception e) {logger.error("An error occurred", e);return new ResponseEntity<>("An error occurred:" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);}}
5. 配置多个全局异常处理器
如果有多个@ControllerAdvice类,Spring会根据它们的@Order或@Priority注解来决定处理异常的顺序。如果没有这些注解,Spring会按照类名的字母顺序来处理。