Top

JAVA SERVLETJSP DAY08

  1. 过滤器——过滤敏感词汇
  2. 过滤器——多个过滤器
  3. 过滤器——过滤器的初始化参数
  4. 监听器——统计在线人数

1 过滤器——过滤敏感词汇

1.1 问题

针对用户输入的评论内容进行敏感词汇的过滤,如果包含“damn”字样,则提示用户评论已关闭。

1.2 方案

在评论内容到达处理Servlet之前,由过滤器拦截后先进行内容的过滤,如果包含敏感词汇则直接返回给客户端相应提示,不包含敏感词汇则可以将此请求传递给下一个过滤器或用于处理的Servlet。

1.3 步骤

步骤一:新建comment.jsp页面

comment.jsp页面用于收集用户评论信息,显示效果及页面源码如下:

图– 1

图 - 2

步骤二:新建CommentServlet.java文件

创建处理评论及显示的Servlet。并部署工程,测试评论是否能够正确发布。

图– 3

web.xml文件配置如下:

图 - 4

步骤三:新建CommentFilter类

图 - 5

步骤四:配置CommentFilter过滤器

图 - 6

步骤五:部署应用,输入评论查看结果

图 - 7

图 - 8

1.4 完整代码

comment.jsp页面的代码:

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<title>评论</title>
</head>
<body>
	<form action="comment" method="post">
		<fieldset>
			<legend>评论</legend>
			请输入评论:<textarea name="comment" 
			style="vertical-align:middle;
			width:140px;height:55px"></textarea><Br>
			<input type="submit" value="发表评论" />
		</fieldset>
	</form>
</body>
</html>

CommentServlet.java文件代码:

package web;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CommentServlet extends HttpServlet {
	public void service(HttpServletRequest request, 
						HttpServletResponse response)
						throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		//获取评论内容
		String str = request.getParameter("comment");
		//显示评论内容
		out.println("<h3>评论内容:" + str + "</h3>");
		out.close();
	}
}

CommentFilter1.java文件代码:

package web;

import java.io.IOException;
import java.io.PrintWriter;

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 javax.servlet.http.HttpServletResponse;

public class CommentFilter1 implements Filter{
	private String illegalWord;
	
	/**
	 * 容器删除过滤器实例之前调用,只执行一次
	 */
	public void destroy() {
				
	}
	
	/**
	 * 用于处理请求的主要方法
	 */
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse resp = (HttpServletResponse)response;
		req.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out = resp.getWriter();
		String comment = req.getParameter("comment");
		if(comment.indexOf("damn")!=-1){
			//有敏感词汇
			out.print("<h3>评论内容已关闭</h3>");
		}else{
			//没有敏感词汇则向后处理,交给其他过滤器或Servlet
			chain.doFilter(req, resp);
		}
	}
	
	/**
	 * 容器启动之后,创建过滤器实例
	 * 然后调用init方法,只会调用一次
	 * 容器会将已经创建好的FilterConfig对象作为参数传入
	 * 可以从该参数中获取初始化的配置信息
	 */
	public void init(FilterConfig filterConfig) throws ServletException {
		illegalWord = filterConfig.getInitParameter("illegalWord");
		System.out.println("Filter1:init is runnming...  " + illegalWord);
		
	}
	
}

web.xml文件代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<!-- 过滤器 -->
<filter>
	<filter-name>filter1</filter-name>
	<filter-class>web.CommentFilter1</filter-class>	
</filter>
<filter-mapping>
	<filter-name>filter1</filter-name>
	<url-pattern>/comment</url-pattern>
</filter-mapping>
<!-- Servlet -->
<servlet>
<servlet-name>CommentServlet</servlet-name>
<servlet-class>web.CommentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CommentServlet</servlet-name>
<url-pattern>/comment</url-pattern>
</servlet-mapping>
</web-app>

2 过滤器——多个过滤器

2.1 问题

在进行过滤评论时,如果发布内容多过20个字,则不允许发布,并出现相应提示。

2.2 方案

增加过滤器,用于检查评论内容的长度。

2.3 步骤

步骤一:新建CommentFilter2.java文件

图 - 9

步骤二:配置CommentFilter过滤器

图 - 10

步骤三:运行查看结果

图 - 11

图 - 12

图 - 13

图– 14

从运行结果中的,如果有多个过滤器存在,则执行顺序按<filter-mapping>的顺序执行。谁在前面,谁先执行。

2.4 完整代码

CommentFilter.java文件代码:

package web;

import java.io.IOException;
import java.io.PrintWriter;

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 javax.servlet.http.HttpServletResponse;

public class CommentFilter2 implements Filter {

	public void destroy() {
		
	}
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse resp = (HttpServletResponse)response;
		req.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out = resp.getWriter();
		String str = req.getParameter("comment");
		if(str.length()>20){
			out.print("评论太长,请重试");
		}else{
			chain.doFilter(request, response);
		}
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

}

web.xml文件代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<!-- 过滤器 -->
<filter>
	<filter-name>filter1</filter-name>
	<filter-class>web.CommentFilter1</filter-class>	
</filter>
<filter>
	<filter-name>filter2</filter-name>
	<filter-class>web.CommentFilter2</filter-class>
</filter>
<filter-mapping>
	<filter-name>filter2</filter-name>
	<url-pattern>/comment</url-pattern>
</filter-mapping>
<filter-mapping>
	<filter-name>filter1</filter-name>
	<url-pattern>/comment</url-pattern>
</filter-mapping>
<!-- Servlet -->
<servlet>
<servlet-name>CommentServlet</servlet-name>
<servlet-class>web.CommentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CommentServlet</servlet-name>
<url-pattern>/comment</url-pattern>
</servlet-mapping>
</web-app>

3 过滤器——过滤器的初始化参数

3.1 问题

动态设置敏感词汇及所限制的评论长度

3.2 方案

使用过滤器的初始化参数,在web.xml文件设定敏感的词汇及限制的评论长度。需要修改时,只需要使用记事本修改web.xml即可

3.3 步骤

步骤一:修改web.xml文件

图 - 15

步骤二:修改CommentFilter1类、CommentFitlter2类读取初始化参数

图 - 16

图 - 17

图 - 18

步骤三:运行,查看是否能正确输出获取到的初始化参数

图 - 19

3.4 完整代码

web.xml文件代码:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<!-- 过滤器 -->
<filter>
	<filter-name>filter1</filter-name>
	<filter-class>web.CommentFilter1</filter-class>
	<!-- 初始化参数 -->
	<init-param>
		<param-name>illegalWord</param-name>
		<param-value>damn</param-value>
	</init-param>
</filter>
<filter>
	<filter-name>filter2</filter-name>
	<filter-class>web.CommentFilter2</filter-class>
	<!-- 初始化参数 -->
	<init-param>
		<param-name>illegalLength</param-name>
		<param-value>30</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>filter2</filter-name>
	<url-pattern>/comment</url-pattern>
</filter-mapping>
<filter-mapping>
	<filter-name>filter1</filter-name>
	<url-pattern>/comment</url-pattern>
</filter-mapping>
<!-- Servlet -->
<servlet>
<servlet-name>CommentServlet</servlet-name>
<servlet-class>web.CommentServlet</servlet-class>
</servlet>
</servlet>
<servlet-mapping>
<servlet-name>CommentServlet</servlet-name>
<url-pattern>/comment</url-pattern>
</servlet-mapping>
</web-app>

CommentFilter1.java文件代码:

package web;

import java.io.IOException;
import java.io.PrintWriter;

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 javax.servlet.http.HttpServletResponse;

public class CommentFilter1 implements Filter{
	private String illegalWord;
	
	/**
	 * 容器删除过滤器实例之前调用,只执行一次
	 */
	public void destroy() {
				
	}
	
	/**
	 * 用于处理请求的主要方法
	 */
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse resp = (HttpServletResponse)response;
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter out = response.getWriter();
		String comment = request.getParameter("comment");
		if(comment.indexOf(illegalWord)!=-1){
			//有敏感词汇
			out.print("<h3>评论内容已关闭</h3>");
		}else{
			//没有敏感词汇则向后处理,交给其他过滤器或Servlet
			chain.doFilter(request, response);
		}
	}
	
	/**
	 * 容器启动之后,创建过滤器实例
	 * 然后调用init方法,只会调用一次
	 * 容器会将已经创建好的FilterConfig对象作为参数传入
	 * 可以从该参数中获取初始化的配置信息
	 */
	public void init(FilterConfig filterConfig) throws ServletException {
		illegalWord = filterConfig.getInitParameter("illegalWord");
		System.out.println("Filter1:init is runnming...  " + illegalWord);		
	}
	
}

CommentFilter2.java文件代码:

package web;

import java.io.IOException;
import java.io.PrintWriter;

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 javax.servlet.http.HttpServletResponse;

public class CommentFilter2 implements Filter {
	private int length;
	public void destroy() {
		
	}
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest)request;
		HttpServletResponse resp = (HttpServletResponse)response;
		req.setCharacterEncoding("UTF-8");
		resp.setContentType("text/html;charset=UTF-8");
		PrintWriter out = resp.getWriter();
		String str = req.getParameter("comment");
		if(str.length()>length){
			out.print("评论太长,请重试");
		}else{
			chain.doFilter(request, response);
		}
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		length = Integer.parseInt(filterConfig.getInitParameter("illegalLength"));
		System.out.println("Filter2:init is runnming...  " + length);
	}

}

4 监听器——统计在线人数

4.1 问题

实现对当前在线人数的统计。

4.2 方案

通过监听session的创建动作,修改存储在线总人数的计数器。这个计数器保存在Servlet上下文中。

4.3 步骤

步骤一:新建CountListener类

图 - 20

步骤二:配置监听器

图- 21

步骤三:添加index.jsp页面

图– 22

步骤四:添加LogoutServlet类

图 - 23

步骤四:配置LogoutServlet

图 - 24

步骤五:运行查看结果

图– 25

由于Chrome浏览器再打开选项卡也是与第一个窗口共用sessionId,所以使用火狐浏览器来模拟第二个上线的用户,运行效果如图-26

图– 26

回到Chrome浏览器,点击刷新,查看结果如图-27

图 - 27

点击火狐浏览器中的登出,然后回到Chrome浏览器刷新页面,查看结果与图-25结果一样。

4.4 完整代码

CountListener.java文件代码:

package web;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class CountListener implements HttpSessionListener {
	private int count = 0;
		
	public void sessionCreated(HttpSessionEvent se) {
		count++;
		HttpSession session = se.getSession();
		ServletContext sct = session.getServletContext();
		sct.setAttribute("count", count);
	}

	public void sessionDestroyed(HttpSessionEvent se) {
		count--;
		HttpSession session = se.getSession();
		ServletContext sct = session.getServletContext();
		sct.setAttribute("count", count);

	}

}

web.xml文件代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<!-- 全局初始化参数 -->
<context-param>
	<param-name>count</param-name>
	<param-value>1000</param-value>
</context-param>
<!-- 监听器 -->
<listener>
	<listener-class>web.CountListener</listener-class>
</listener>
<!-- 过滤器 -->
<filter>
	<filter-name>filter1</filter-name>
	<filter-class>web.CommentFilter1</filter-class>
	<!-- 初始化参数 -->
	<init-param>
		<param-name>illegalWord</param-name>
		<param-value>damn</param-value>
	</init-param>
</filter>
<filter>
	<filter-name>filter2</filter-name>
	<filter-class>web.CommentFilter2</filter-class>
	<!-- 初始化参数 -->
	<init-param>
		<param-name>illegalLength</param-name>
		<param-value>30</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>filter2</filter-name>
	<url-pattern>/comment</url-pattern>
</filter-mapping>
<filter-mapping>
	<filter-name>filter1</filter-name>
	<url-pattern>/comment</url-pattern>
</filter-mapping>
<!-- Servlet -->
<servlet>
<servlet-name>CommentServlet</servlet-name>
<servlet-class>web.CommentServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>web.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CommentServlet</servlet-name>
<url-pattern>/comment</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>	
</web-app>

index.jsp文件代码如下:

<%@ page contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
	<head>	
		<title></title>
	</head>
	<body>
		当前共有<%=application.getAttribute("count").toString()%>人在线<br>
		<a href="logout">登出</a>
	</body>
</html>

LogoutServlet.java文件代码:

package web;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class LogoutServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html; charset=utf-8");

        /*
         * 因为监听器是通过监听 session 的创建与销毁来计算 count,因此登出的请求应该是在此处进行 session 的注销,
         * 这样就能实现登出人数-1的效果。
         */
        HttpSession session = req.getSession();
        session.invalidate();// session 无效化
    }

}