三种拦截方式分别为:
1 javax.servlet.Filter 2 org.springframework.web.servlet.HandlerInterceptor 3 org.aspectj.lang.annotation.Aspect
拦截先后顺序
客户端请求 --》 Filter --》 HandlerInterceptor --》 Aspect --》 目标方法 --》 Aspect --》 HandlerInterceptor --》 Filter --》 客户端
示例如下:
1. 新建Maven项目 interceptor
2. pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.java</groupId> <artifactId>interceptor</artifactId> <version>1.0.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> </parent> <dependencies> <!-- Spring Boot --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- 热部署 --> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> <version>1.2.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
3. InterceptorStarter.java
package com.java; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class InterceptorStarter { public static void main(String[] args) { SpringApplication.run(InterceptorStarter.class, args); } }
4. DemoController.java
package com.java.controller; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/demo") public class DemoController { @GetMapping("/getHostMessage") public Map<String, Object> getHostMessage(String type, String age) { Map<String, Object> map = new HashMap<>(); System.out.println(); System.out.println("type: " + type); System.out.println(); // 测试异常情况 if ("exception".equals(type)) { throw new RuntimeException("异常演习!"); } try { InetAddress serverHost = InetAddress.getLocalHost(); map.put("hostName", serverHost.getHostName()); map.put("hostAddress", serverHost.getHostAddress()); map.put("type", type); map.put("age", age); } catch (UnknownHostException e) { e.printStackTrace(); } return map; } }
5. DemoFilter.java
package com.java.interceptor; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Component; /** * <blockquote> * * <pre> * 请求拦截过滤器 * * 1. 开启 @Component 注解便可启用拦截功能 * 2. 不开启 @Component 可通过FilterRegistrationBean 设置注册到 @Configuration 注解的配置类中 * * </pre> * * </blockquote> * */ //@Component // 不开启注解时可以通过配置启动 public class DemoFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("初始化DemoFilter"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; System.out.println(String.format("[ DemoFilter ] [ Into %s ]", req.getRequestURI())); chain.doFilter(request, response); System.out.println(String.format("[ DemoFilter ] [ Exit %s ]", req.getRequestURI())); } @Override public void destroy() { System.out.println("销毁DemoFilter"); } }
6. DemoInterceptor.java
package com.java.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; @Component public class DemoInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println(String.format(" [ DemoInterceptor ] [ Into %s ]", request.getRequestURI())); System.out.println("[ preHandle ]"); System.out.println(((HandlerMethod) handler).getBeanType().getName()); System.out.println(((HandlerMethod) handler).getMethod().getName()); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("[ postHandle ] 抛出异常时不执行"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) throws Exception { System.out.println("[ afterCompletion ]"); System.out.println("Exception is " + e); // 抛出异常时Content-Type为 text/html;charset=ISO-8859-1 if (null != e) { response.setContentType("text/html;charset=UTF-8"); } System.out.println(String.format("[ DemoInterceptor ] [ Exit %s ] ", request.getRequestURI())); } }
7. DemoAspect.java
package com.java.interceptor; import java.util.Arrays; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component public class DemoAspect { @Around("execution(* com.java.controller..*.*(..))") public Object around(ProceedingJoinPoint point) throws Throwable { System.out.println(String.format(" [ DemoAspect ] [ Into %s ]", point.getSignature())); System.out.println(Arrays.toString(point.getArgs())); Object object = point.proceed(); System.out.println(String.format("[ DemoAspect ] [ Exit %s ] ", point.getSignature())); return object; } @AfterThrowing(pointcut = "execution(* com.java.controller..*.*(..))", throwing = "e") public void afterThrowing(Throwable e) { System.out.println(String.format("[ DemoAspect ] %s ", e)); } }
8. WebConfig.java
package com.java.config; import javax.servlet.Filter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.java.interceptor.DemoFilter; import com.java.interceptor.DemoInterceptor; @Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private DemoInterceptor demoInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(demoInterceptor); } @Bean public FilterRegistrationBean<Filter> demoFilter() { FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>(); DemoFilter demoFilter = new DemoFilter(); registrationBean.setFilter(demoFilter); registrationBean.addUrlPatterns("/*"); return registrationBean; } }
9. 运行InterceptorStarter.java, 启动测试
浏览器输入 http://localhost:8080/demo/getHostMessage?age=16&type=normal
返回结果如下:
{"hostName":"Logan","hostAddress":"192.168.1.101","type":"normal","age":"16"}
查看控制台打印信息如下:
[ DemoFilter ] [ Into /demo/getHostMessage ] [ DemoInterceptor ] [ Into /demo/getHostMessage ] [ preHandle ] com.java.controller.DemoController getHostMessage [ DemoAspect ] [ Into Map com.java.controller.DemoController.getHostMessage(String,String) ] [normal, 16] type: normal [ DemoAspect ] [ Exit Map com.java.controller.DemoController.getHostMessage(String,String) ] [ postHandle ] 抛出异常时不执行 [ afterCompletion ] Exception is null [ DemoInterceptor ] [ Exit /demo/getHostMessage ] [ DemoFilter ] [ Exit /demo/getHostMessage ]
异常场景测试,浏览器输入http://localhost:8080/demo/getHostMessage?age=16&type=exception
返回结果自行研究。
三种拦截功能拦截顺序为:
客户端请求 --》 Filter --》 HandlerInterceptor --》 Aspect --》 目标方法 --》 Aspect --》 HandlerInterceptor --》 Filter --》 客户端
.