SpringBoot中过滤器、监听器、拦截器
1.使用Servlet3.0的注解过滤器
-
启动类添加@ServletComponentScan进行扫描
-
新建一个Filter类,implements Filter,并实现对应的接口
package com.gen.filter; import com.fasterxml.jackson.databind.ObjectMapper; import com.gen.mo.User; import com.gen.service.impl.UserServiceImpl; import com.gen.util.JsonData; import org.springframework.util.StringUtils; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * 登录过滤器 * @WebFilter:标记一个类为filter,被Spring进行扫描 urlPatterns:拦截规则,支持正则 */ @WebFilter(urlPatterns = "/api/v1/pri/*", filterName = "loginFilter") public class LoginFilter implements Filter { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; // 获取token String token = request.getHeader("token"); if (!StringUtils.hasLength(token)) { token = request.getParameter("token"); } if (StringUtils.hasLength(token)) { // 判断token是否合法 User user = UserServiceImpl.sessionMap.get(token); if (user != null) { // token合法,放行 filterChain.doFilter(request, response); } else { // token失效 JsonData jsonData = JsonData.buildError(-2, "token失效"); String jsonStr = OBJECT_MAPPER.writeValueAsString(jsonData); renderJson(response, jsonStr); } } else { // 未登录 JsonData jsonData = JsonData.buildError(-3, "未登录"); String jsonStr = OBJECT_MAPPER.writeValueAsString(jsonData); renderJson(response, jsonStr); } } /** * 工具类:返回json字符串 */ private void renderJson(HttpServletResponse response, String json) { response.setCharacterEncoding("utf-8"); response.setContentType("application/json"); try (PrintWriter writer = response.getWriter()) { writer.print(json); } catch (Exception e) { e.printStackTrace(); } } }
2.使用Servlet3.0的注解原生Servlet
package com.gen.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "userServlet", urlPatterns = "/api/v1/test/servlet")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.print("this is my servlet");
writer.flush();
writer.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.使用Servlet3.0的注解监听器
-
什么是监听器
监听器是一个实现了特定接口的普通Java类,用于监听其他对象的创建和销毁,监听其他对象的方法执行和属性改变
-
监听器分类
- ServletContextListener 应用启动监听
- HttpSessionListener 会话监听
- ServletRequestListener 请求监听
package com.gen.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; /** * 应用上下文监听 */ @WebListener public class ApplicationListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("contextInitialized==========="); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("contextDestroyed==========="); } }
4.拦截器
-
SpringBoot2.x新版本配置拦截器 implements WebMvcConfigurer,代码如下:
package com.gen.interceptor; 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 CustomWebMvcConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/api/v1/pri/**"); } } -
自定义拦截器HandlerInterceptor
-
preHandle:调用Controller某个方法之前
-
postHandle:Controller之后调用,视图渲染之前,如果控制器Controller出现了异常,则不会执行此方法
-
afterCompletion:不管有没有异常,这个方法都会被调用,用于资源清理
-
登录拦截器代码示例
package com.gen.interceptor; import com.fasterxml.jackson.databind.ObjectMapper; import com.gen.mo.User; import com.gen.service.impl.UserServiceImpl; import com.gen.util.JsonData; import org.springframework.util.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; /** * 登录拦截器 */ public class LoginInterceptor implements HandlerInterceptor { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取token String token = request.getHeader("token"); if (!StringUtils.hasLength(token)) { token = request.getParameter("token"); } if (StringUtils.hasLength(token)) { // 判断token是否合法 User user = UserServiceImpl.sessionMap.get(token); if (user != null) { // token合法,放行 return true; } else { // token失效 JsonData jsonData = JsonData.buildError(-2, "token失效"); String jsonStr = OBJECT_MAPPER.writeValueAsString(jsonData); renderJson(response, jsonStr); return false; } } else { // 未登录 JsonData jsonData = JsonData.buildError(-3, "未登录"); String jsonStr = OBJECT_MAPPER.writeValueAsString(jsonData); renderJson(response, jsonStr); return false; } } /** * 工具类:返回json字符串 */ private void renderJson(HttpServletResponse response, String json) { response.setCharacterEncoding("utf-8"); response.setContentType("application/json"); try (PrintWriter writer = response.getWriter()) { writer.print(json); } catch (Exception e) { e.printStackTrace(); } } }
-
-
和Filter过滤器的区别
- Filter和Interceptor二者都是AOP编程思想的体现,功能基本都可以实现,拦截器功能更强大,Filter能做的事情它都能做
- Filter只在Servlet前后起作用,而Interceptor深入到方法前后、异常抛出前后等
- Filter依赖于Servlet容器即web应用中,而Interceptor不依赖于Servlet容器所以可以运行在多种环境
- 在接口调用的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次
- FIlter和Interceptor的执行顺序:过滤前-->拦截前-->action执行-->拦截后-->过滤后
浙公网安备 33010602011771号