Servlet过滤器与Servlet十分相似,但是它有拦截客户端请求的功能,它实质上是Web应用服务器上的一个Web应用组件,用于拦截客户端与目标资源的请求,并对这些请求进行一定过滤处理再发送给目标资源 可以类比于自来水的过滤器 那么也可以设置多个过滤器 一层一层的进行过滤
过滤器对象防止在javax.servlet包中 其名称为Filter 它是一个接口 三种方法如下
public void init()//初始化 public void doFilter()//对请求进行过滤处理 public void destroy()//销毁方法 以便释放资源
1:创建一个名为MyFilter的过滤器对象
代码如下
import java.io.IOExcepiton; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class Myfilter implements Filter { public void init(FilterConfig fConfig)throws ServletException{ } public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException,ServletException{ chain.doFilter(request,response); } public void destroy() { //释放资源 } }
过滤器中的init()
方法用于对过滤器的初始化进行处理 destroy是过滤器的销毁方法主要用于释放资源,对于过滤处理的业务逻辑需要编写到doFilter方法中 在请求过滤处理后,需要调用chain参数的doFilter方法将请求向下传递给下一过滤器或目标资源
过滤器与Servlet十分相似 在创建之后同样需要对其进行配置 分为两个步骤 分别是声明过滤器对象和创建过滤器映射
<!--过滤器声明--> <filter> <!--过滤器名称--> <filter-name>MyFilter</filter-name> <!--过滤器完整的类名> </filter> <!--过滤器映射> <filter-mapping> <filter-name>MyFilter</filter-name> <!--过滤器URL映射> <url-pattern>/MyFilter</url-pattern> </filter-mapping>
实战一
创建一个过滤器 实现网站访问计数器的功能 并在web.xml文件的配置中将网站访问初始值设为5000
import java.io.IOExcepiton; 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.HttpServletRequest; public class CountFilter implements Filter{ private int count; public void init(FilterConfig filterConfig)throws ServletException{ String param=filterConfig.getInitParmeter("count"); count=Integer.valueOf(param); } public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException,ServletException{ count++; HttpServletRequest req=(HttpServletRequest)request; SrevletContext context=req.getSession().getServletContext(); context.setAttribute("count",count); chain.doFilter(request,response); } public void destroy() { } }
对web.xml配置如下
<!--过滤器声明--> <filter> <!--过滤器名称--> <filter-name>CountFilter</filter-name> <filter-class>com.lyq.CountFilter</filter-class> <init-param> <param-name>count</param-name> <param-value>5000</param-value> </init-param> <!--过滤器完整的类名> </filter> <!--过滤器映射> <filter-mapping> <filter-name>CountFilter</filter-name> <!--过滤器URL映射> <url-pattern>/index.jsp</url-pattern> </filter-mapping>
创建程序的页面 index.jsp文件如下 通过JSP内置对象Application获取计数器的值
<body> <h2> 欢迎光临<br> 您是本站的第 <%=application.getAttribute("count")%> 位访客 </h2> </body>
实战二:字符编码过滤器
在Java Web程序开发中 由于Web容器内部所使用编码格式并不支持中文字符集 所以处理浏览器请求中的中文数据就会出现乱码现象
解决次问题的方法非常简单,在Web应用中部署字符编码过滤器 即使Web容器的编码格式不支持中文,但浏览器的每一次请求都会经过过滤器进行转码,所以可以避免中文乱码现象产生
public class CharactorFilter implements Filter{ String encoding=null; public void destroy(){ encoding=null; } public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException,ServletException{ if(encoding!=null){ request.setCharacterEncoding(encoding); response.setContentType("text/html";charset="+encoding); } chain.doFilter(request,response); } public void init(FilterConfig filteConfig)throws ServletException{ encoding=filterConfig.getInitParameter("encoding"); } }
代码中指定了request与response两个参数的字符集encoding进行编码处理 使得目标资源的字符集支持中文
Servlet监听器
Servlet监听器是当今Web应用开发中的一个重要组成部分 主要就是用来对Web应用进行监听和控制的 极大地增强了Web应用的事件处理能力
Servlet监听器的功能比较接近Java的GUI程序的监听器 可以监听Web应用中状态改变而引起的Servlet容器产生的相应事件 然后接受并处理这些事件
创建监听器 代码如下
public class MyContetnListener implements ServletContextListener{ // }
配置web.xml文件如下
<listener> <listener-class>com.listener.MyContentListener</listener-class> </listener>
1:HTTP会话监听
1.1:HttpSessionListener接口
实现监听HTTP会话创建 销毁
1.2:Servlet请求监听
监听客户端的请求 一旦能够在监听程序中获取客户端的请求 就可以对请求进行统一处理
实战三:Servlet监听器统计在线人数
UserInfoList.java文件 用来存储在线用户和对在线用户进行具体操作
public class UserInfoList{ private static UserInfoList user=new UserInfoList(); private Vector vector=null; public UserInfoList(){ return user; } public boolean addUserInfo(String user){ if(user!=null){ this.vector.add(user); return True; } else{ return False; } } public Vector getList(){ return vector; } public void removeUserInfo(String user){ if(user!=null){ vector.removeElement(user);} } }
创建UserInfoTrace.java文件 实现其中两个方法
public class UserInfoTrace impletments javax.servlet.http.HttpSessionBindingListener{ private String user; private UserInfoList container=UserInfoList.getInstance(); public UserInfoTrace(){ user=""; } public void setUser(String user){ this.user=user; } public String getUser(){ return this.user; } public void valueBound(HttpSessionBindingEvent arg0){ System.out.printIn("上线"+this.user); } public void valueUnBound(HttpSessionBindingEvent arg0){ System.out.printIn("下线"+this.user); if(user!=null){ container.removeUserInfo(user); } } }
创建showUser.jsp文件 在页面中设置session的setMaxInactiveInterval方法为10秒 这样可以缩短session的生命周期
<$@ page import="java.util.*"> <$@ page import="com.listener.*"> <% UserInfoList list=UserInfoList.getInstance(); UserInfoTrace ut=new UserInfoTrace(); String name=request.getParmeter("user"); ut.setUser(name); session.setAttribute("list",ut); list.addUserInfo(ut.getUser()); session.setMaxInactiveInterval(10); %> <textarea rows="8" cols="20"> <% Vector vector=list.getList(); if(vector!=null&&vector.size()>0){ for(int i=0;i<vector.size();i++){ out.printIn(vector.elementAt(i)); } } %> </textarea>