---Filter
创建一个servlet的Filter步骤:
1)创建Filter处理类
2)在web.xml中通过配置文件配置Filter
或:在Filter类中通过Annotation配置Filter
创建Filter类要实现javax.servlet.Filter接口,Filter接口定义了以下方法:
1.init(FilterConfig filterConfig)由Web容器调用,初始化此Filter。
2.destory()由Web容器调用,初始化此Filter。
3.doFilter(ServletRequest request,ServletResponse response,FilterChain chain)具体过滤处理代码。
--demo1:
//web.xml <filter> <filter-name>log</filter-name> <filter-class>test.LogFilter</filter-class> </filter> <filter-mapping> <filter-name>log</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
//Filter处理类 package test; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.*; //@WebFilter(filterName="log", urlPatterns={"/*"}) public class LogFilter implements Filter { //FilterConfig可用于访问Filter的配置信息 private FilterConfig config; //实现初始化方法 public void init(FilterConfig config) { this.config = config; } //实现销毁方法 public void destroy() { this.config = null; } //执行过滤的核心方法 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException { ServletContext context = this.config.getServletContext();//获取ServletContext对象,用于记录日志 long before = System.currentTimeMillis(); System.out.println("开始过滤..."); HttpServletRequest hrequest = (HttpServletRequest)request;//将请求转换成HttpServletRequest请求 System.out.println("Filter已经截获到用户的请求的地址: " + hrequest.getServletPath()); chain.doFilter(request, response); //控制请求是否被放行 System.out.println("过滤结束"); long after = System.currentTimeMillis(); System.out.println("请求被定位到" + hrequest.getRequestURI() + ",所花的时间为: " + (after - before)); } }
--demo2:
//web.xml <!-- 定义Filter --> <filter> <filter-name>authority</filter-name> <filter-class>test.AuthorityFilter</filter-class> <!-- 下面三个init-param元素配置了三个参数 --> <init-param> <param-name>encoding</param-name> <param-value>GBK</param-value> </init-param> <init-param> <param-name>loginPage</param-name> <param-value>/login.jsp</param-value> </init-param> <init-param> <param-name>proLogin</param-name> <param-value>/proLogin.jsp</param-value> </init-param> </filter> <!-- 定义Filter拦截的URL地址 --> <filter-mapping> <filter-name>authority</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
//Filter处理类 package test; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.*; @WebFilter(filterName="authority" , urlPatterns={"/*"} , initParams={ @WebInitParam(name="encoding", value="GBK"), @WebInitParam(name="loginPage", value="/login.jsp"), @WebInitParam(name="proLogin", value="/proLogin.jsp")}) public class AuthorityFilter implements Filter { //FilterConfig可用于访问Filter的配置信息 private FilterConfig config; //实现初始化方法 public void init(FilterConfig config) { this.config = config; } //实现销毁方法 public void destroy() { this.config = null; } //执行过滤的核心方法 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,ServletException { //获取该Filter的配置参数 String encoding = config.getInitParameter("encoding"); String loginPage = config.getInitParameter("loginPage"); String proLogin = config.getInitParameter("proLogin"); //设置request编码用的字符集 request.setCharacterEncoding(encoding); HttpServletRequest requ = (HttpServletRequest)request; HttpSession session = requ.getSession(true); //获取客户请求的页面 String requestPath = requ.getServletPath(); //如果session范围的user为null,即表明没有登录 //且用户请求的既不是登录页面,也不是处理登录的页面 if( session.getAttribute("user") == null && !requestPath.endsWith(loginPage) && !requestPath.endsWith(proLogin)) { //forward到登录页面 request.setAttribute("tip" , "您还没有登录"); request.getRequestDispatcher(loginPage) .forward(request, response); } //"放行"请求 else { chain.doFilter(request, response); } } }
附:
@WebFilter修饰一个Filter类,用于对Filter进行配置,它支持如下属性:
属 性 |
是否必需 |
说 明 |
asyncSupported |
否 |
指定该Filter是否支持异步操作模式。 关于Filter的异步调用请参考2.15节 |
dispatcherTypes |
否 |
指定该Filter仅对那种dispatcher模式的 请求进行过滤。该属性支持ASYNC、 ERROR、FORWARD、INCLUDE、REQUEST 这5个值的任意组合。默认值为同时 过滤5种模式的请求 |
displayName |
否 |
指定该Filter的显示名 |
filterName |
|
指定该Filter的名称 |
initParams |
否 |
用于为该Filter配置参数 |
servletNames |
否 |
该属性值可指定多个Servlet的名称, 用于指定该Filter仅对这几个Servlet执行过滤 |
urlPatterns/value |
否 |
这两个属性的作用完全相同。都指 定该Filter所拦截的URL |
---Listener
Servlet API提供大量监听器来监听Web应用的内部事件,从而允许当Web内部事件发生时回调事件监听器内的方法。
使用Listener步骤:
1)定义Listener实现类
2)通过web.xml文件或Annotation注解配置Listener。如
//方式一;
使用@WebListener修饰Listener实现类MyListener.java
//方式二:
在web.xml文件中配置:
<listener>
<listener-class>test.MyListener</listener-class>
</listener>
---常用的listener
链接:http://blog.csdn.net/will_awoke/article/details/8820297
当Web应用在Web容器中运行时,Web应用内部会不断地发生各种事件:如Web应用被启动、Web应用被停止,用户session开始、用户session结束,用户请求到达等,通常来说这些Web事件对开发者是透明的。
常用的Web事件监听器接口有如下几个。
① ServletContextListener:用于监听Web应用的启动和关闭
监听器类需要实现javax.servlet.ServletContextListener接口,实现:
contextInitialized(ServletContextEventsce):启动Web应用时,系统调用Listener的该方法
contextDestroyed(ServletContextEventsce):关闭Web应用时,系统调用Listener的该方法
ServletContextListener的作用有点类似于load-on-startupServlet,都可以用于在Web应用启动时,回调方法来启动某些后台程序,这些后台程序负责为系统运行提供支持
② ServletContextAttributeListener:用于监听ServletContext范围(application)内属性的改变
监听器类需要实现ServletContextAttributeListener接口,实现:
attributeAdded(ServletContextAttributeEventevent);当程序把一个属性存入application范围时触发该方法。
attributeRemoved(ServletContextAttributeEventevent);当程序把一个属性从application范围删除时触发该方法。
attributeReplaced(ServletContextAttributeEventevent);当程序替换application范围内的属性时触发该方法。
③ ServletRequestListener:用于监听用户请求
监听器类需要实现ServletRequestListener接口,实现:
requestInitialized(ServletRequestEventsre):用户请求到达、被初始化时触发该方法
requestDestroyed(ServletRequestEventsre):用户请求结束、被销毁时触发该方法
④ ServletRequestAttributeListener:用于监听ServletRequest范围(request)内属性的改变。
监听器类需要实现ServletRequestAttributeListener接口,实现:
attributeAdded(ServletRequestAttributeEventevent);当程序把一个属性存入request范围时触发该方法。
attributeRemoved(ServletRequestAttributeEventevent);当程序把一个属性从v范围删除时触发该方法。
attributeReplaced(ServletRequestAttributeEventevent);当程序替换request范围内的属性时触发该方法。
⑤ HttpSessionListener:用于监听用户session的开始和结束
监听器类需要实现HttpSessionListener接口,实现:
sessionInitialized(HttpSessionEventsre):用户请求到达、被初始化时触发该方法
sessionDestroyed(HttpSessionEventsre):用户请求结束、被销毁时触发该方法
⑥ HttpSessionAttributeListener:用于监听HttpSession范围(session)内属性的改变
监听器类需要实现HttpSessionAttributeListener接口,实现:
attributeAdded(HttpSessionAttributeEventevent);当程序把一个属性存入request范围时触发该方法。
attributeRemoved(HttpSessionAttributeEventevent);当程序把一个属性从v范围删除时触发该方法。
attributeReplaced(HttpSessionAttributeEventevent);当程序替换request范围内的属性时触发该方法。
---web.xml中的listener、filter、servlet加载顺序
链接:http://zhxing.iteye.com/blog/399668
由此,可以看出,web.xml 的加载顺序是:context-param -> listener -> filter -> servlet ,
而同个类型之间的实际程序调用的时候的顺序是根据对应的 mapping 的顺序进行调用的。
注:摘自轻量级JavaEE企业应用实战第三版