SpringBoot 2.x (6):使用Filter、Servlet、Listener
Filter的使用:
1.常见的默认Filter有:
characterEncodingFilter
hiddenHttpMethodFilter
httpPutFormContentFilter
requestContextFilter
2.Filter的优先级:
Ordered.HIGHEST_PRECEDENCE:最低优先级,值为int最大值
Ordered.LOWEST_PRECEDENCE:最高优先级,值为int最小值
低位值意味着更高的优先级
因此如果要自定义Filter,应该避免和默认的Filter优先级一样,不然会冲突
3.自定义Filter
可以使用Spring的FilterRegistrationBean,但是这种方式较为麻烦
所以这里采用Servlet3.0的方式:
结合实际应用的一个小Demo
Controller:
package org.dreamtech.springboot.controller; import java.util.HashMap; import java.util.Map; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DemoController { /** * 查看当前账户余额 * * @return */ @RequestMapping("/login/account") private Object account() { Map<String, Object> modelMap = new HashMap<String, Object>(); modelMap.put("money", 1000); return modelMap; } }
Filter:
package org.dreamtech.springboot.filter; 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.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebFilter(urlPatterns = "/login/*", filterName = "loginFilter") public class LoginFilter implements Filter { /** * 容器加载时候调用 */ @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("[ LoginFilter Init ]"); } /** * 请求被拦截的时候调用 */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("[ LoginFilter doFilter ]"); HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; String username = req.getParameter("username"); if (username != null) { chain.doFilter(req, resp); } else { System.out.println("[ username is null ]"); return; } } /** * 容易被销毁的时候调用 */ @Override public void destroy() { System.out.println("[ LoginFilter Destroy ]"); } }
特别注意:要在SpringBoot启动类中加入@ServletComponentScan注解
package org.dreamtech.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; @SpringBootApplication @ServletComponentScan public class SpringbootApplication { public static void main(String[] args) { SpringApplication.run(SpringbootApplication.class, args); } }
启动后的结果:
访问:http://localhost:8080/login/account显示空白页面
访问:http://localhost:8080/login/account?username=xxx显示{"money":1000}
Servlet的使用:
package org.dreamtech.springboot.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(urlPatterns = "/servlet/demo", name = "demoServlet") public class DemoServlet extends HttpServlet { private static final long serialVersionUID = -428928425699550712L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().print("demo servlet"); resp.getWriter().flush(); resp.getWriter().close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
注意:和Filter使用相同地,要在SpringBoot启动类中加入@ServletComponentScan注解
Listener的使用:
常见的Listener有
ServletContextListener、HttpSessionListener、ServletRequestListener
ServletRequestListener:用于统计(比如文章的浏览次数等)
Controller:
@RequestMapping("/listener") private Object listener() { System.out.println("listener controller"); return "listener"; }
Listener:
package org.dreamtech.springboot.listener; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; @WebListener("/listener") public class DemoListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("request destroyed"); } @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println("request initialized"); } }
打印顺序应该是:每一次访问/listener都会打印这三行
request initialized
listener controller
request destroyed
ServletContextListener:用于资源加载
package org.dreamtech.springboot.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; @WebListener("/listener") public class DemoListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("context initialized"); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("context destroyed"); } }
打印顺序:
一开始打印context initialized
结束进程的时候打印context destroyed
只打印一遍
至于HttpSessionListener不怎么使用,就不介绍了