过滤器 Filter (重点)
Filter :过滤器,用来过滤网站的数据
-
过滤器中的所有代码,在过滤特定的请求时候都会执行
-
必须要让过滤器继续同行 :
chain.doFilter(request,response);
过滤器的作用 :
- 过滤中文乱码
- 登陆验证
需要用到的依赖
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!--jsp-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
<!-- jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
实现 Filter 的步骤
1、编写 filter :
注意 :导包不要导错
import javax.servlet.*;
import java.io.IOException;
public class CharacterEncodingFilter implements Filter {
/**
*初始化
* web 服务器启动的时候,就已经初始化了,随时等待过滤对象出现
* @param filterConfig
* @throws ServletException
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("开始初始化");
}
/**
* 过滤器中的所有代码,在过滤特定的请求时候都会执行
* 必须要让过滤器继续同行 : chain.doFilter(request,response);
* @param request
* @param response
* @param chain 链
* @throws IOException
* @throws ServletException
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("执行前");
//让我们的请求继续往前走,如果不写,程序到这里就会被拦截停止
chain.doFilter(request,response);
System.out.println("执行后");
}
/**
* 销毁
* web 服务器关闭时,过滤自动销毁
*/
@Override
public void destroy() {
System.out.println("开始销毁");
}
}
2、编写 servlt
什么都不写,这样输出到页面肯定是乱码,我们在web.xml 中配置两个映射路径,一个通过过滤器,一个不通过过滤器,我们来对比一下
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("你好,世界!!!");
}
3、配置 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>respDemo</servlet-name>
<servlet-class>com.hkp.servlet.RespDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>respDemo</servlet-name>
<url-pattern>/servlet/show</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>respDemo</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>
<!-- 格式与servlet的类似 -->
<!--这样设置的话,方式请求中以 /servlet 或 /sys 开头的请求都会走过滤-->
<filter>
<filter-name>characterEncoding</filter-name>
<filter-class>com.hkp.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>characterEncoding</filter-name>
<!--设置需要过滤的请求-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>characterEncoding</filter-name>
<!--设置需要过滤的请求-->
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
</web-app>
4、启动测试
通过过滤器的测试
没有通过过滤器的测试
实现登陆过滤
用户登陆后就可以进入主页,退出后就不能进入主页
1、准备三个 jsp 页面 login.jsp success.jsp failure.jsp
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="${pageContext.request.contextPath}/servlet/login">
用户名 :<input type="text" name="username"/>
密码 :<input type="password" name="password"/>
<input type="submit">
</form>
</body>
</html>
success.jsp
注意 :
这个jsp页面我们给他在webapp文件夹下创建一个文件夹,主要用于方便过滤
<%--
Created by IntelliJ IDEA.
User: han11
Date: 2021/8/31
Time: 14:43
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>${USER_SESSION}</h1>
<h1>欢迎<%=session.getAttribute("USER_SESSION")%>,登陆成功!!!</h1>
<h1><a href="${pageContext.request.contextPath}/servlet/logout">注销</a></h1>
</body>
</html>
failure.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>用户名或密码错误</h1>
<h1><a href="${pageContext.request.contextPath}/login.jsp">返回登陆页面</a></h1>
</body>
</html>
2、编写 servlet
LoginServlet
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 LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取用户请求过来的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
//判断用户信息是否正确
if(username.equals("root")&&password.equals("admin")){//登陆成功
//获取session
HttpSession session = req.getSession();
//将用户浏览器中的SessionID存入session中
session.setAttribute("USER_SESSION",session.getId());
//重定向 成功页面 filter 为项目名
resp.sendRedirect("/filter/sys/success.jsp");
}else{//登陆失败
//重定向 失败页面 filter 为项目名
resp.sendRedirect("/filter/failure.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
LogoutServlet
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 doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取 session
HttpSession session = req.getSession();
Object user_session = session.getAttribute("USER_SESSION");
if(user_session!=null){//登录
//移除session
session.removeAttribute("USER_SESSION");
// 重定向到登陆页面 filter 为项目名
resp.sendRedirect("/filter/login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3、编写 过滤器
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//由于我们的session 是HttpServletRequest 中的,所以我们要对 request 对象进行强转
HttpServletRequest req = (HttpServletRequest) servletRequest;
//由于 重定向需要的是 HttpServletResponse 中的sendRedirect方法,所以需要强转一下
HttpServletResponse resp = (HttpServletResponse) servletResponse;
//获取session
HttpSession session = req.getSession();
Object user_session = session.getAttribute("USER_SESSION");
if(user_session==null){//未登录
// filter 为项目名
resp.sendRedirect("/filter/login.jsp");
}
//注意 :这里不能再写 else 然后重定向到 成功页面了,因为我们在 LoginServlet 中已经将重定向过一次了,
// 在这里如果在写的话就会因重定向次数过多而访问不到
//保证 过滤器正常继续执行下去
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
4、配置web.xml
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.hkp.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<!--设置需要过滤的请求-->
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.hkp.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/servlet/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>logout</servlet-name>
<servlet-class>com.hkp.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>logout</servlet-name>
<url-pattern>/servlet/logout</url-pattern>
</servlet-mapping>
5、测试
- 启动项目 (项目的访问项目名称为 filter,路径为 http://localhost :8080/filter/index.jsp)
- 访问登陆页面
- 输入错误的用户信息,使其跳转到错误页面
- 点击错误页面的返回登陆页面
- 输入正确的用户信息,使其跳转到成功页面
- 点击成功页面的注销按钮
- 直接访问成功页面 http://localhost :8080/filter/sys/success.jsp 看过滤器是否生效
监听器
统计网站在线人数
1、编写 servlet
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 统计在线人数
* 统计session
*/
public class OnlineCountListener implements HttpSessionListener {
/**
* 创建session 监听
* 一旦创建session就会触发这个事件
*
* @param se
*/
@Override
public void sessionCreated(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Integer count = (Integer) context.getAttribute("OnlineCount");
if (count == null) {
//如果在线人数为null,在线人数为1
count = 1;
} else {
//如果在线人数不为null,在线人数加1
count++;
}
context.setAttribute("OnlineCount", count);
}
/**
* 销毁session监听
* 一旦销毁session就会触发这个事件
*
* @param se
*/
@Override
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Integer count = (Integer) context.getAttribute("OnlineCount");
if (count == null) {
//如果在线人数为null,在线人数为1
count = 0;
} else {
//如果在线人数不为null,在线人数加1
count--;
}
context.setAttribute("OnlineCount", count);
}
}
2、编写 jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--两种方式都可以取到值--%>
${OnlineCount}
<h1>当前有<span><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>人在线</h1>
</body>
</html>
3、配置 web.xml
<!--注册监听器-->
<listener>
<listener-class>com.hkp.listener.OnlineCountListener</listener-class>
</listener>
4、测试