课时1 过滤器的入门
JavaWeb三大组件
1、都需要在web.xml中进行配置
Servlet
Filter
Listener
2、过滤器
会在一组资源(jsp, servlet, css, html等等)的前面执行
可以让请求得到目标资源,也可以不让请求达到
过滤器有拦截请求的能力
3、编写过滤器
(1)实现Filter接口
(2)在web.xml中进行配置
(3)Filter是单例的
4、配置web.xml
<web-app> <filter> <filter-name>FilerName</filter-name> <filter-class>FilerClass</filter-class> </filter> <filter-mapping> <filter-name>FilerName</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
继承示例
package com.pengshiyu.filtrer; import javax.servlet.*; import java.io.IOException; public class Afilter implements Filter { /** * 创建之后马上执行,用来做初始化 */ @Override public void init(FilterConfig filterConfig) throws ServletException { } /** * 每次过滤都会执行 */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("进入过滤器"); // 调用后序方法 filterChain.doFilter(servletRequest, servletResponse); System.out.println("离开过滤器"); } /** * 销毁之前的调用,用来释放资源 */ @Override public void destroy() { } }
FilterConfig -> 与ServletConfig相似
获取初始化参数 getInitParameter()
获取过滤器名称 getFilterName()
获取application getServletContext()
FilterChain
放行,执行后序方法 doFilter()
课时2 多个过滤器的执行顺序
执行下一个过滤器或目标资源
FilterChain.doFilter()
Afilter进入过滤器
Bfilter进入过滤器
getAge
Bfilter离开过滤器
Afilter离开过滤器
课时3 四种拦截方式
请求 REQUEST 默认
转发 FORWARD
包含 INCLUDE
错误 ERROR
<filter-mapping> <filter-name>FilerName</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>
页面出错
<error-page> <error-code>500</error-code> <location>500.html</location> </error-page>
课时4 使用filter-mapping控制多个Filter的执行顺序
filter-mapping的配置顺序决定过滤器执行顺序
课时5 Filter的应用场景、Filter的目标资源、小结
预处理:执行目标资源之前做预处理工作,例如设置编码
拦截:通过条件判断是否放行,例如用户登录校验
回程拦截:目标资源执行之后,做一些后序的特殊处理工作,例如目标资源输出的数据进行处理
直接指定servlet-name
<filter-mapping> <filter-name>FilerName</filter-name> <servlet-name>ServletName</servlet-name> </filter-mapping>
小结
Filter3个方法
FilterChain类
4中拦截方式
课时6 案例1:分IP统计访问次数
数据结构:
统计工作在所有资源之前都执行,使用Filter
这个过滤器只做统计,不做拦截
数据Map<String, Integer>
Map保存到ServletContext中
从request中获取客户端ip
使用监听器创建 map
AListener.java
package com.pengshiyu.listener; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import java.util.LinkedHashMap; import java.util.Map; public class AListener implements ServletContextListener { // 服务器启动时创建map public void contextInitialized(ServletContextEvent sce) { Map<String, Integer> map = new LinkedHashMap<String, Integer>(); sce.getServletContext().setAttribute("map", map); } public void contextDestroyed(ServletContextEvent sce) { } }
使用过滤器统计数据
AFilter.java
package com.pengshiyu.filter; import javax.servlet.*; import java.io.IOException; import java.util.Map; public class AFilter implements Filter { private FilterConfig config; /** * 创建之后马上执行,用来做初始化 */ @Override public void init(FilterConfig filterConfig) throws ServletException { this.config = filterConfig; } /** * 每次过滤都会执行 */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { ServletContext app = this.config.getServletContext(); Map<String, Integer> map = (Map<String, Integer>)app.getAttribute("map"); String ip = request.getRemoteAddr(); System.out.println("ip: " + ip); if(map.containsKey(ip)){ Integer count = map.get(ip); map.put(ip, count+1); } else{ map.put(ip, 1); } // 放行 filterChain.doFilter(request, response); } /** * 销毁之前的调用,用来释放资源 */ @Override public void destroy() { } }
显示数据
BServlet.java
package com.pengshiyu.servlet; import javax.servlet.ServletContext; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Map; public class BServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { ServletContext app = getServletContext(); Map<String, Integer> map = (Map<String, Integer>) app.getAttribute("map"); response.setContentType("text/html; charset=UTF-8"); response.getWriter().println(map.toString()); } }
配置监听器和过滤器生效
web.xml
<?xml version="1.0" encoding="utf-8"?> <web-app> <servlet> <servlet-name>BServlet</servlet-name> <servlet-class>com.pengshiyu.servlet.BServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>BServlet</servlet-name> <url-pattern>/b</url-pattern> </servlet-mapping> <filter> <filter-name>AFilter</filter-name> <filter-class>com.pengshiyu.filter.AFilter</filter-class> </filter> <filter-mapping> <filter-name>AFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>com.pengshiyu.listener.AListener</listener-class> </listener> </web-app>