Filter(过滤器)、Listener(监听器)
2018-03-09 23:37
281 查看
一: 过滤器: 可以把”不和谐”的东西给过滤掉
01.过滤器概述
02.过滤器的应用
03:开发和使用Filter
04.Filter的细节
05.请求编码过滤器CharacterEncodingFilter
XML配置文件
06.登陆检查过滤器
检查登录过滤器
从登录界面跳转到的Servlet中
login.jsp登录界面
welcom.jsp
Filter的配置文件
07.敏感字过滤
给Filter中的request赋予过滤字符的功能
过滤器(filter)使用
二: Listener(监听器)
01.过滤器概述
生活中的过滤器:带有过滤功能的净水器,滤纸,香烟的过滤嘴,测试,丈母娘. 程序中的过滤器:在JAVA中最小的程序单元是类,程序中的过滤器就是一个特殊的类 Servelt/Filter是Web的一个组件.
Web中过滤器的作用(简单理解为:过滤器处在客户端和服务端资源之间): 过滤器可以对所有的请求或者响应做拦截操作. 1:以常规的方式调用资源(Servelt/JSP); 2:利用修改过的请求信息调用资源; 3:调用资源之后,但在响应到客户端之前,对响应做出修改; 4:阻止当前资源调用,代之转带其他资源.
02.过滤器的应用
过滤器在开发中的应用: 1):可以对请求中的字符做编码. 2):登录验证过滤器. 3):敏感字(非法文字)过滤. 4):做MVC框架中的前端控制器(处理所有请求共同操作,再分发)
在开发中两个常用的思想: 1):DRY原则: Don't Repeat Yourself. 开发中拒绝代码重复,(重复会带来巨大的维护成本) 2):责任分离原则:各自做各自最擅长的事情.
03:开发和使用Filter
Servlet开发: 1:自定义一个类(XxxServlet),实现于javax.servlet.Servlet接口. 2:实现Servelt接口中的方法(init(初始化方法),service(处理请求)) 3:告诉Tomcat来帮我们管理该Servlet程序(1:使用web.xml做配置,2:WebServlet("/资源名")). <servlet> <servlet-name>Servlet的别名</servlet-name> <servlet-class>自定义Servelt的全限定名</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet的别名</servlet-name> <url-pattern>/资源名</url-pattern> </servlet-mapping> 注意:此时的url-pattern的文本内容是外界访问Servelt的资源名称.
Filter开发: 1:自定义一个类(XxxFilter),实现于javax.servlet.Filter接口. 2:实现Filter接口中的方法(init(初始化方法),doFilter(处理请求)) 3:告诉Tomcat来帮我们管理该Filter程序(1:使用web.xml做配置,2:WebFilter("/资源名")). <filter> <filter-name>Filter的别名</filter-name> <filter-class>自定义Filter的全限定名</filter-class> </filter> <filter-mapping> <filter-name>Filter的别名</filter-name> <url-pattern>/资源名</url-pattern> </filter-mapping> 注意:此时的url-pattern的文本内容是Filter对哪一些资源做过滤操作. 如: /hello.jsp :说明当前Filter只会对/hello.jsp做拦截/过滤. /employee :说明当前Filter只会对/enployee资源做过滤. /system/* :说明当前Filter只会对以/system/作为前缀的资源路径做拦截.
filterChain(过滤器链):多个过滤器按照一定的顺序,排列起来. 拦截器栈: -------------------------------------------------------- 程序中存在多个过滤器的时候,过滤器的先后执行顺序由谁来决定. 在WEB.xml中:配置的<fiter-mapping>的先后顺序来决定. ![过滤器的的先后执行顺序示意图](https://img-blog.csdn.net/20180310104230663?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzQwMTYxNzA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
04.Filter的细节
过滤器的映射细节: 1):filter中的url-pattern的文本内容是Filter对哪一些资源做过滤操作. 如: /hello.jsp :说明当前Filter只会对/hello.jsp做拦截/过滤. /employee :说明当前Filter只会对/enployee资源做过滤. /system/* :说明当前Filter只会对以/system/作为前缀的资源路径做拦截. /* :说明对所有的资源做过滤. /*.do :对所有以 .do 结尾的资源做拦截 2):Filter的dispatcher(表示对哪些动作作过滤). <filter-mapping> <filter-name>FilterDemo1</filter-name> <url-pattern>/*</url-pattern> <url-pattern>/x1</url-pattern> <!-- 只对请求做拦截(默认) --> <dispatcher>REQUEST</dispatcher> <!-- 增加对请求转发做拦截 --> <dispatcher>FORWARD</dispatcher> <!-- 增加请求包含做拦截 --> <dispatcher>INCLUDE</dispatcher> <!-- 增加跳转到错误页面做拦截 --> <dispatcher>ERROR</dispatcher> </filter-mapping> <error-pag 1006e e> <error-code>404</error-code> <location>/404.jsp</location> </error-page>
05.请求编码过滤器CharacterEncodingFilter
Servelt只管 1:获取 2:调用 3:跳转 就行,设置编码交给Filter就行, DRY原则 跟 责任分离原则!
//字符编码过滤器 public class CharacterEncodingFilter implements Filter{ private String encoding; private Boolean forceEncoding = false; public void init(FilterConfig config) throws ServletException { this.encoding = config.getInitParameter("encoding"); forceEncoding = Boolean.valueOf(config.getInitParameter("force")); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //类型 HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; //设置编码 //1:应用中没有编码,并且我自己设置了编码. //2:应用中已经存在编码了但是依然要使用我自己设置的编码:强制使用 if(haslength(encoding) && (req.getCharacterEncoding() == null || forceEncoding)){ req.setCharacterEncoding(encoding); } chain.doFilter(req, resp); } public void destroy() { } private boolean haslength(String str){ return str!=null && !"".equals(str.trim()); } }
XML配置文件
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com._520it._02_characterencoding.CharacterEncodingFilter</filter-class> <!-- 设置编码 --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <!-- 是否强制使用该编码 --> <init-param> <param-name>force</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
06.登陆检查过滤器
![登录检查的流程图](http://img.blog.csdn.net/20180310170822918?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzQwMTYxNzA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
检查登录过滤器
//登录检查过滤器 public class CheckLoginFilter implements Filter{ private String[] unCheckUris = {"/login.jsp","/login"}; public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; Object user = req.getSession().getAttribute("USER_IN_SESSION"); //当前正在过滤的资源 String requestURI = req.getRequestURI(); if(!Arrays.asList(unCheckUris).contains(requestURI)){ if(user == null){//没有登录 resp.sendRedirect("login.jsp"); return ; } } chain.doFilter(req, resp); } public void destroy() { } }
从登录界面跳转到的Servlet中
@WebServlet("/login") public class LoginServelt extends HttpServlet{ private static final long serialVersionUID = 1L; protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String username = req.getParameter("username"); //把登录信息存储到session中 req.getSession().setAttribute("USER_IN_SESSION",username); resp.sendRedirect("/welcome.jsp"); } }
login.jsp登录界面
<form action="/login" method="post"> 账号:<input type="text" name="username" required/><br/> 密码:<input type="text" name="password"/><br/> <input type="submit" value="登录"/> </form>
welcom.jsp
${sessionScope.USER_IN_SESSION} <hr/> <a href="function1.jsp">功能1</a><br/> <a href="function2.jsp">功能2</a><br/> <a href="function3.jsp">功能3</a><br/>
Filter的配置文件
<filter> <filter-name>CheckLoginFilter</filter-name> <filter-class>com._520it.checklogin.CheckLoginFilter</filter-class> <init-param> <param-name>unCheckUris</param-name> <!-- 以后这样做 对需要检查的放到/system/中来 --> <param-value>/system/*</param-value> </init-param> </filter> <filter-mapping> <filter-name>CheckLoginFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
07.敏感字过滤
利用装饰设计模式,给Request.getParameter赋予敏感字过滤功能 ![流程示意图](http://img.blog.csdn.net/20180310212548133?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzQwMTYxNzA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
给Filter中的request赋予过滤字符的功能
public class MessageRequestWapper extends HttpServletRequestWrapper{ public MessageRequestWapper(HttpServletRequest request) { super(request); } //覆盖getParameter方法,使之支持敏感字过滤 public String getParameter(String name){ //如果参数名为title或content if("title".equals(name) || "content".equals(name)){ //返回过滤之后的title和content FilterUtil.filter(super.getParameter(name)); //FilterUtils就是过滤的代码,现在先知道就行 } return super.getParameter(name); } }
过滤器(filter)使用
@WebFilter("/*") public class MessageFilter implements Filter{ public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //把不具有处理敏感字的请求对象换成可以处理敏感字的请求对象. HttpServletRequest req = (HttpServletRequest) request; HttpServletRequest requestWapper = new MessageRequestWapper(req); //放行 chain.doFilter(requestWapper, response); } public void destroy() { } }
二: Listener(监听器)
Web的另一大组件:Listener(监听器). Web中的监听器,主要用于监听作用域对象的创建,监听作用域对象属性的添加/删除/替换: 1):监听作用域对象的创建和销毁. ServletRequestListener:监听请求对象的创建和销毁. HttpSessionListener:监听会话对象(session) 的创建和销毁 ServletContextListener:监听应用的创建和销毁. 2):监听作用域对象的属性的添加/删除/替换. ServletRequestAttributeListener: 监听request作用域中属性的添加/删除/替换. HttpSessionAttributeListener: 监听session作用域中属性的添加/删除/替换. ServletContextAttributeListener: 监听application作用域中属性的添加/删除/替换. Web中的监听器组件,没有初始化参数配置如果要解决监听器中的硬编码,只能使用全局的初始化参数.
//监听系统(应用)的启动和销毁 public class ContextLoaderListener implements ServletContextListener{ public void contextInitialized(ServletContextEvent sce) { System.out.println("Web系统启动了....."); } public void contextDestroyed(ServletContextEvent sce) { System.out.println("Web系统销毁了....."); } }
@WebListener public class HttpSessionListenerDemo implements HttpSessionListener{ public void sessionCreated(HttpSessionEvent se) { System.out.println("会话开始了"); } public void sessionDestroyed(HttpSessionEvent se) { System.out.println("会话结束了"); } }
@WebListener public class HttpSessionAttributeListenerDemo implements HttpSessionAttributeListener{ public void attributeAdded(HttpSessionBindingEvent se) { System.out.println("属性添加"+se.getName()+","+se.getValue()); } public void attributeRemoved(HttpSessionBindingEvent se) { System.out.println("属性删除"+se.getName()+","+se.getValue()); } public void attributeReplaced(HttpSessionBindingEvent se) { System.out.println("属性替换"+se.getName()+","+se.getValue()+","+se.getSession().getAttribute(se.getName())); } }
预习,精通Struts2的hello开发:
相关文章推荐
- 过滤器(Filter)和监听器(Listener)
- 过滤器、监听器、拦截器的区别 filter listener interceptor
- 过滤器Filter与监听器Listener
- Servlet中的过滤器(拦截器)Filter与监听器Listener的作用和区别
- Servlet中的过滤器(拦截器)Filter与监听器Listener的作用和区别
- 小仙女—过滤器(filter)、监听器(listener)
- Servlet3.0介绍~使用注解标注监听器(Listener)和过滤器(Filter)
- Servlet3.0介绍~使用注解标注监听器(Listener)和过滤器(Filter)
- SpringBoot系列<八>过滤器filter和监听器listener配置
- web.xml 中的过滤器(拦截器)Filter与监听器Listener的作用和区别?
- Servlet中的过滤器(拦截器)Filter与监听器Listener的作用和区别
- 过滤器(Filter)、监听器(Listener)
- 过滤器(Filter)和监听器(listener)
- Servlet中的过滤器(拦截器)Filter与监听器Listener的作用和区别
- Web中的监听器【Listener】与过滤器【Filter】 实例
- servlet 过滤器(Filter)和监听器(listener)
- Servlet中的过滤器(拦截器)Filter与监听器Listener的作用和区别
- Servlet中的过滤器(拦截器)Filter与监听器Listener的作用和区别
- 过滤器Filter和监听器Listener
- [置顶] 过滤器(Filter)和监听器(Listener)