公众号merlinsea
- 过滤器
过滤器:当用户请求访问某个路径的时候,会先执行过滤器中的逻辑,然后在决定是否放行执行接下去的controller层的逻辑。
登陆过滤器的执行流程:
1、用户首先通过公有路径登陆,登陆了以后会为用户生成一个token并返回给用户同时把token存在本地。
2、用户下单通过私有路径,(因为必须先登录再下单)
3、由于过滤器配置的是对私有路径进行拦截,因此当用户下单的时候会先执行过滤器的逻辑再决定是否放行。
4、过滤器发现用户没有携带token或者是token异常那么就不会进行放行,并把登陆不成功的信息通过HttpServletResponse返回给前端。
LoginFileter登陆过滤器编写
/** * 实现的是WebFilter包下的过滤器 * 当访问路径是api/v1/pri/开头的都要先经过这个过滤器处理以后在决定是否执行后面的controller逻辑 * @WebFilter 标记这个类是一个过滤器类,交给spring扫描并配置过滤路径 * init()方法是在过滤器逻辑执行之前使用 * doFilter()方法是过滤器的核心逻辑,通常会判断token信息是否合法 * destroy()方法是过滤器核心逻辑之后使用 */ @WebFilter(urlPatterns = "/api/v1/pri/*", filterName = "loginFilter") public class LoginFilter implements Filter { private static final ObjectMapper objectMapper = new ObjectMapper(); /** * 容器加载的时候 * @param filterConfig * @throws ServletException */ @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init LoginFilter======"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("doFilter LoginFilter======"); HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletResponse resp = (HttpServletResponse) servletResponse; String token = req.getHeader("token"); if(StringUtils.isEmpty(token)){ token = req.getParameter("token"); } if(!StringUtils.isEmpty(token)){ //判断token是否合法 User user = UserServiceImpl.sessionMap.get(token); if(user!=null){ //token合法逻辑,放行 filterChain.doFilter(servletRequest,servletResponse); }else { //token不合法逻辑,不放行,通过HttpServletResponse返回token不合法给前端 JsonData jsonData = JsonData.buildError("登录失败,token无效",-2); String jsonStr = objectMapper.writeValueAsString(jsonData); renderJson(resp,jsonStr); } }else { //token没有,通过HttpServletResponse返回token为空给前端 JsonData jsonData = JsonData.buildError("未登录",-3); String jsonStr = objectMapper.writeValueAsString(jsonData); renderJson(resp,jsonStr); } } //自定义的把数据返回给前端 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(); } } /** * 容器销毁的时候 */ @Override public void destroy() { System.out.println("destroy LoginFilter======"); } }
- 监听器
监听器:监听某一个动作,然后做出相应的反应,主要用于排错定位,不做业务逻辑!!
监听器用@WebListner注解标识。
- ServletContextListener
- 应⽤启动监听,开启springboot项目和关闭springboot项目的时候调用,主要用于资源初始化。
- ServletRequestListener
- 请求监听,开启一个url请求和关闭一个url请求的时候调用,可以用于定位请求日志。
- HttpSessionLisener
- 会话监听,分布式系统中很少使用。
1、ServletContextListener,应用启动监听器
/** * 应用上下文监听器 * 启动项目和关闭项目的时候调用 * @WebListner 告诉springboot这是一个监听器 */ @WebListener class ApplicationListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("contextInitialized===="); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("contextDestroyed===="); } }
2、ServletRequestListener 请求监听,开启一个url请求的时候调用,可以用于定位请求日志
/** * 请求监听器,用于监听每一个请求的创建和销毁,可以用于打印日志排错 * 开启一个url请求和关闭一个url请求的时候调用 * @WebListener 告诉springboot这是一个监听器 */ @WebListener class CustomRequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("requestDestroyed===="); } @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println("requestInitialized===="); } }
3、HttpSessionLisener 会话监听
/** * 会话监听器,现在分布式应用中很少使用 */ @WebListener class CustomSessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("sessionCreated===="); } @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("sessionDestroyed===="); } }