过滤器与监听器的使用

实例一、编码过滤

在进行WEB开发中,编码过滤是必不可少的操作,如果按照之前的做法,在每一个JSP或者是Servlet中都重复编写“request.setCharacterEncoding(“utf-8”)”的语句肯定是不可取的,会造成大量的代码重复,此时就可以通过过滤器完成这种编码过滤。即:在服务器运行servlet和JSP之前,过滤器就把请求编码统一设置为指定的编码。具体过程如下:
(说明:setCharacterEncodingFilter.java是一个过滤器,用来设置所有请求的编码。DoServlet.java和DoServlet1.java是两个servlet,用来输出其字符编码)
在eclipse中创建如下工程和文件:
图1

在setCharacterEncodingFilter.java的Filter中,编写如下代码:

	public static String encoding;
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here

		// pass the request along the filter chain
		request.setCharacterEncoding(encoding);
		chain.doFilter(request, response);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
		encoding=fConfig.getInitParameter("encoding");
	}
DoServlet.java和DoServlet1.java的代码是一样的,它们什么都不做,只输出请求的编码。代码如下:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter out=response.getWriter();
		out.print(request.getCharacterEncoding());
	}

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>fiter1-1</display-name>
  <filter>
  	<filter-name>SetCharacterEncodingFilter</filter-name>
  	<filter-class>swu.smxy.jsj.SetCharacterEncodingFilter</filter-class>
  	<init-param>
  		<param-name>encoding</param-name>
  		<param-value>utf-8</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>SetCharacterEncodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

运行结果:
运行.DoServlet.java和DoServlet1.java的结果如下图所示:
图2
图3

从结果我们可以看出,Filter已经把请求的编码都设置成了“utf-8”。

实例二、通过注解的方式实现编码过滤

在实例一中修改。具体步骤如下:
(1)删除web.xm中关于过滤器的配置信息。
(2)在setCharacterEncodingFilter.java中增加如下红色框里的代码。

@WebFilter(filterName="SetCharacterEncodingFilter",urlPatterns={"/*"},initParams={@WebInitParam(name="encoding",value="utf-8")})
public class SetCharacterEncodingFilter implements Filter {

    /**
     * Default constructor. 
     */
    public SetCharacterEncodingFilter() {
        // TODO Auto-generated constructor stub
}

运行效果与实例一一模一样,只是不需要配置web.xml。这样是不是更简单呢?。所以,注解使用的主要目的就是避免编写配置文件,提高编程效率。

实例三、登录验证

创建工程和文件:
图4

SessionFilter.java的Filter文件中使用了注解方式配置,其代码如下:

package swu.smxy.jsj;
import java.io.IOException;
@WebFilter(filterName="SessionFilter",urlPatterns="/admin/*")
public class SessionFilter implements Filter {

    /**
     * Default constructor. 
     */
    public SessionFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here

		// pass the request along the filter chain
		HttpServletResponse res=(HttpServletResponse) response;
		HttpServletRequest req=(HttpServletRequest) request;//向下转型
		HttpSession session =req.getSession();//取得session
		if(session.getAttribute("username")==null){
			res.sendRedirect("../login/login.jsp");
		}else{
		chain.doFilter(request, response);
		}
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

LoginServlet的代码如下:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String name=request.getParameter("name");
		String password=request.getParameter("password");
		if(name.equals("张三")&password.equals("123456")){
			HttpSession session=request.getSession();
			session.setAttribute("username", name);
			session.setAttribute("password", password);
			response.sendRedirect("admin/admin.jsp");
		}else{
			
		}
	}
setCharacterEncodingFilter.java代码如下:
	public static String encoding;
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here

		// pass the request along the filter chain
		request.setCharacterEncoding(encoding);
		chain.doFilter(request, response);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
		encoding=fConfig.getInitParameter("encoding");
	}

login.jsp页面的代码如下:

<body>
<form action="${pageContext.request.contextPath }/LoginServlet" method="post">
	姓名:		<input type="text"	name="name"><br>
	密码:		<input type="password"	name="password"><br>
	<input type="submit" value="提交">
	<input type="reset" value="重置">
</form>
</body>

创建adduser.jsp、admin.jsp、search.jsp三个页,不用输入任何代码
运行效果:
a. 依次运行adduser.jsp、admin.jsp、search.jsp文件时的结果是什么?
都是如下界面
图5
图6

b. 先运行login.jsp,并输入正确的用户名和密码后,再依次运行adduser.jsp、admin.jsp、search.jsp文件时的结果又是什么?
提交信息后,出现空页面

实例四、禁止浏览器缓存页面

在eclipse中创建如下工程和文件:
图7

在NoCacheFilter.java过滤器,编写如下代码:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here

		// pass the request along the filter chain
		HttpServletRequest req=(HttpServletRequest) request;
		//把ServletResponse强转成HttpServletResponse
		HttpServletResponse res=(HttpServletResponse) response;
		//禁止浏览器缓存所有动态页面
		res.setDateHeader("Expires", -1);
		res.setHeader("Cache-Control", "no-cache");
		res.setHeader("Pragma", "no-cache");
		chain.doFilter(request, response);
	}

index.jsp页面不用写任何代码,这里只是测试。
运行结果:
运行index.jsp页面,下图是在谷歌浏览器的开发者模式下,查看Header得出的结果。
图8

ie浏览器没法查看Header得出的结果

实例五、控制浏览器缓存页面中的静态资源

在eclipse中创建如下工程和文件:
图9

ResourceCacheFilter.java的代码如下:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub
		// place your code here

		// pass the request along the filter chain
		HttpServletRequest req=(HttpServletRequest) request;
		HttpServletResponse res=(HttpServletResponse) response;
		res.setHeader("Cache-Control", "max-age=3600");
		res.setDateHeader("expires", System.currentTimeMillis()+1000L*3600);
		chain.doFilter(request, response);
	}
web.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>filter1-3</display-name>
  <filter>
  	<filter-name>ResourceCacheFilter</filter-name>
  	<filter-class>swu.smxy.filter.ResourceCacheFilter</filter-class>
  </filter>
  <!-- 配置要缓存的web资源的后缀 -->
 <filter-mapping>
 	<filter-name>ResourceCacheFilter</filter-name>
 	<url-pattern>*.png</url-pattern>
 	<url-pattern>*.jpg</url-pattern>
 	<url-pattern>*.bmp</url-pattern>
 	<url-pattern>*.gif</url-pattern>
 	<url-pattern>*.css</url-pattern>
 </filter-mapping>
</web-app>
jsp的页面引用一张图片
<body>
<img alt="" src="images/1.png">
</body>

运行结果:
第1次运行1.jsp页面,在谷歌浏览器中我们得到如下信息:
图10

再次在谷歌浏览器中运行1.jsp,得到如下结果。红色框内信息表示该图片来自于缓存。由此可见,我们把资源设置缓存浏览成功。其他资源不再测试。同学们也可以自己测试一下。
图11

实例六、监听项目的启动与停止。

在eclipse中创建如下工程和文件:
图12

在MyServletContextListener,编写如下代码:

   public void contextDestroyed(ServletContextEvent arg0)  { 
         // TODO Auto-generated method stub
    	System.out.print("contextDestroyed");
    }

    public void attributeReplaced(ServletContextAttributeEvent arg0)  { 
         // TODO Auto-generated method stub
    }

    public void contextInitialized(ServletContextEvent arg0)  { 
         // TODO Auto-generated method stub
    	String name=arg0.getServletContext().getInitParameter("name");
    	System.out.println("contextInitialized : name-"+name);
}
在web.xml中配置监听器。Web.xml的配置如下:
<display-name>listener1-1</display-name>
  <listener>
  	<listener-class>swu.smxy.listener.MyServletContextListener</listener-class>
  </listener>
  <context-param>
  	<param-name>name</param-name>
  	<param-value>swu</param-value>
  </context-param>
运行结果:
启动Tomcat服务器,控制台打印的信息如下:
![图13](https://img-blog.csdnimg.cn/20201202170822283.png)


停止Tomcat服务器,控制台打印如下信息。

# 实例七、监听session的创建和销毁
在eclipse中创建如下工程和文件:
 ![图14](https://img-blog.csdnimg.cn/20201202170634171.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pieXl3bA==,size_16,color_FFFFFF,t_70)

login.html的代码::
<body>
<form action="/listener1-1/loginServlet" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/>
<input type="submit" value="提交">
</form>
</body>
index.jsp页面的代码:
</head>
 <% UserInfoList user = UserInfoList.getInstance(); %>
 <%  
        //如果未登录,转向登录页面  
        if (request.getSession(false).getAttribute("username") == null) {  
            response.sendRedirect(request.getContextPath()+"/login.html");  
        }  
       Vector vector = user.getList(); //获取存储在线用户名的vector对象  
 %>  
<body>
<center>
    <h2>欢迎您:【${sessionScope.username}】</h2>
    <p>当前在线人数:<%=user.getCount() %>人</p>
    在线人员:
    <%
    for(int i=0;i<user.getCount();i++){
    out.println(vector.get(i));
    }
    %>
    <p><a href="${pageContext.request.contextPath}/ExitServlet">退出</a><p>
    </center>
</body>
LoginServlet.java的主要代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html");
		String username=request.getParameter("username");
		String password=request.getParameter("password");
		HttpSession session=request.getSession(true);
		session.setAttribute("username", username+":"+password);
		response.sendRedirect(request.getContextPath()+"/index.jsp");
	}
ExitServlet.java的主要代码:
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		request.getSession(false).invalidate();
		response.sendRedirect(request.getContextPath()+"/login.html");
	}
UserInfoList.java的主要代码:
public class UserInfoList {
	private static UserInfoList user = new UserInfoList();
	private Vector vector = null;
	private UserInfoList(){
	this.vector = new Vector();
}
	
	//使用单例模式
	public static UserInfoList getInstance(){
	return user;
	}
	
	/**
	 * 增加用户
	 */
	public boolean addUserInfo(String user){
	if(user!=null){
	this.vector.add(user);
	return true;
	}else{
	return false;
	}
	}
	
	/**
	 * 删除用户
	 */
	public void removeUserInfo(String user){
	if(user!=null){
	vector.removeElement(user);
	}
	}
	
	/**
	 * 获取用户列表
	 */
	public Vector getList(){
	return vector;
	}
	/**
	 * 统计在线人数
	 */
	public int getCount(){
	return vector.size();
	}
	}
OnlineListener.java的代码如下:
@WebListener
public class OnlineListener implements ServletContextListener, ServletContextAttributeListener, HttpSessionActivationListener, HttpSessionBindingListener {

	private UserInfoList user=UserInfoList.getInstance();
	
	public void sessionCreated(HttpSessionEvent arg0){
		System.out.println("session已经创建");
	}
	
	public void sessionDestroyed(HttpSessionEvent arg0){
		System.out.println("session已经销毁");
	}
   
    public void attributeAdded(ServletContextAttributeEvent sadd)  { 
         // TODO Auto-generated method stub
    	//将session中内容添加到vector集合
    	user.addUserInfo(String.valueOf(sadd.getValue()));
    	System.out.println(sadd.getSession().getId()+":"+sadd.getName()+":"+sadd.getValue());
    }

	/**
     * @see ServletContextAttributeListener#attributeRemoved(ServletContextAttributeEvent)
     */
    public void attributeRemoved(ServletContextAttributeEvent srem)  { 
         // TODO Auto-generated method stub
    	//移除
    	user.removeUserInfo(String.valueOf(srem.getValue()));
    	System.out.println(srem.getSession().getId()+":"+srem.getName()+":"+srem.getValue());
    }

	
    public void attributeReplaced(ServletContextAttributeEvent supd)  { 
         // TODO Auto-generated method stub
    	//更改;获取旧的属性
    	String oldValue=String.valueOf(supd.getValue());
    	//获取新的属性
    	String newValue=String.valueOf(supd.getSession().getAttribute(supd.getName()));		
    	//移除旧属性
    	user.removeUserInfo(newValue);
    	//添加新属性
    	user.addUserInfo(newValue);
    	System.out.println("更改属性");
    }

}

运行效果
先运行login.jsp页面,结果如下:
图15

在打开浏览器,输入浏览地址,结果如下:
图16

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值