目录
- 1. filter过滤器
- 1.1 原理
- 1.2 配置
- 1.3 过滤掉脏话demo
- 2. listener监听器
- 2.1 作用
- 2.2 ServletContextListener demo
1. filter过滤器
- 作用:
- 过滤servlet,jsp,js,css,图片对象,以及一切在服务器,客户端想访问的对象
- 用来设置编码,过滤掉脏话等…
- 过滤器链:你有多个过滤器,你如果多个filter过滤一个servlet,配置一个servlet,那么这个多个过滤器会形成过滤器链。
1.1 原理
- 不多bb,请看下面的图
- 就像学校的图书馆,你进学校有保安守着校门,这是一次过滤,进学校图书馆,你得刷卡,才可自习。只是过滤器可以配置多个,对不同得对象…
1.2 配置
- 比如我想创建一个过滤掉脏话的过滤器叫FilterDirtyTalk
- 对DirtyMsg servlet进行过滤
<filter><filter-name>FilterDirtyTalk</filter-name><filter-class>filter.FilterDirtyTalk</filter-class><!-- 与servlet配置相似 --></filter><filter-mapping><filter-name>FilterDirtyTalk</filter-name><url-pattern>/DirtyMsg</url-pattern> <!-- 想进入dirtymsg servlet 得先经过filter --></filter-mapping>
-
但是上面的servlet只能过滤从jsp进来的 !假如,你有业务,从一个servlet转发到jsp后台页面,但是这个页面要登录才行。你没登录,按上面的配置,过滤器过滤不到,所以来了解过滤器的规则。
-
过滤器过滤规则
FORWARD:转发时进行过滤
REQUEST:浏览器直接请求时进行过滤(默认:没有配置dispatcher节点的时候)
INCLUDE:动态包含的时候执行过滤器
<%@ include %>:静态包含,把被包含的页面的源代码拷贝过来与包含页面一起转译编译运行;包含的过程中不能传参
jsp:include动态包含:包含页面和被包含页面分开转译编译运行,然后将结果合并到一起;包含的过程中可以传参
ERROR:在出错的时候进入过滤器
- 在web.xml <filter-mapping>加上
<dispatcher>REQUEST</dispatcher> <!-- 默认对请求进行过滤 --><dispatcher>FORWARD</dispatcher> <!-- 会检查请求转发-->
1.3 过滤掉脏话demo
- 过滤掉脏话filter_config.txt 文本文件
你妹=妹妹
你弟=弟弟
你妈=妈妈
- 拿到request对象中的用户请求数据,继承HttpServletRequestWrapper
package servlet;import java.util.Map;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;public class MyRequest extends HttpServletRequestWrapper {private Map<String, String[]> map;public MyRequest(HttpServletRequest request) {super(request);map = request.getParameterMap(); }@Overridepublic String getParameter(String name) {// 返回第一个值String[] str = map.get(name);if (str.length > 0 && str != null)return str[0];return null;}@Overridepublic Map<String, String[]> getParameterMap() {// 返回mapreturn map;}@Overridepublic String[] getParameterValues(String name) {// string数组值return map.get(name);}}
- 把脏话转成civilized word
package filter;import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;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 servlet.MyRequest;public class FilterDirtyTalk implements Filter {@Overridepublic void destroy() {// 过滤掉 你妹,你妈,你弟等 -> 你妹=妹妹 // tomcat8.0 给你的版本map是副本, 重写HttpServletRequestWrapper 重新拿到map的值 ... }@Overridepublic void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {HttpServletRequest hreq = (HttpServletRequest) req;// 把请求改变为我的请求类,里面正真的改变了map集合req = new MyRequest(hreq);if (hreq.getMethod().equalsIgnoreCase("get")) { // get方式// tomcat 8.0 已经设置好了get编码} else if (hreq.getMethod().equalsIgnoreCase("post")) {req.setCharacterEncoding("utf-8");}resp.setContentType("text/html;charset=utf-8");File file = new File("E:\\servletStudy\\Servlet3\\filter_config.txt");// 读取脏话FileReader fr = new FileReader(file);BufferedReader br = new BufferedReader(fr);HashMap<String, String> dirtyMap = new HashMap<String, String>();// 改变value的值 如果是dirty-talk// 读取filter-configString str = br.readLine();while (str != null) {dirtyMap.put(str.split("=")[0], str.split("=")[1]);str = br.readLine();} // 把脏话放入集合。。。Set<Entry<String, String>> dirtySet = dirtyMap.entrySet();// 请求对象键值对Map<String, String[]> map = req.getParameterMap();Set<Entry<String,String[]>> entrySet = map.entrySet();for (Entry<String, String[]> entry : entrySet) {String key = entry.getKey(); // 请求对象参数String[] value = entry.getValue(); // 请求对象值System.out.println(key + "\t" + Arrays.toString(value));for (int i = 0; i < value.length; i++) {for(Entry<String, String> set : dirtySet) {String dirty = set.getKey();if (dirty.equals(value[i]))value[i] = set.getValue();}}System.out.println("转换后");System.out.println(key + "\t" + Arrays.toString(value));}br.close();fr.close();// 放行 jsp才可访问servlet...chain.doFilter(req, resp);}@Overridepublic void init(FilterConfig arg0) throws ServletException {}}
- DirtyMsg 拿到jsp页面过滤的值
package servlet;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class DirtyMsg extends HttpServlet {/*** dirty msg*/private static final long serialVersionUID = 1L;@Overrideprotected void service(HttpServletRequest req, HttpServletResponse arg1)throws ServletException, IOException {String name1 = req.getParameter("name1");String name2 = req.getParameter("name2");String name3 = req.getParameter("name3");System.out.println(name1 + name2 + name3);}
}
-
jsp页面
-
正确过滤后:
2. listener监听器
2.1 作用
- 用来监听request/session/application的创建/销毁/数据操作
- 讲一个ServletContextListener, 用来监听application的创建和销毁(监听tomcat的开启和关闭)
2.2 ServletContextListener demo
- 配置
<listener><listener-class>test.MyServletContextListener</listener-class></listener>
- 实现
package test;import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;public class MyServletContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("服务器开启啦。。。 可以初始配置文件啦...");}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("服务器销毁啦。。。");}}
- ServletContextAttributeListener,元素的移除,可得到移除信息,rbr
- request,session的套路类似