Filter(过滤器)
1.过滤器的概念和作用
1.1概念:
滤器位于客户端和web应用程序之间,用于检查和修改两者之间流过的请求;
在请求到达Servlet/JSP之前,过滤器截获请求;
1.2.作用:在客户端的请求访问后端资源之前,拦截这些请求(添加处理)。
Filter接口
2.1. Filter接口是过滤器类必须实现的接口,该接口中有三个方法:
init(FilterConfig filterConfig):该方法是对filter对象进行初始化的方法,参数FilterConfig可以获得filter的初始化参数;
doFilter(ServletRequest request,ServletResponse response,FilterChain chain):该方法是filter进行过滤操作的方法,是最重要的方法。
过滤器实现类必须实现该方法,方法体中可以对request和response进行预处理。其中FilterChain可以将处理后的request和response对象传递到过滤链上的下一个资源。
destroy():该方法在容器销毁对象前被调用。
2.2.FilterChain接口
该方法类型作为Filter接口中的doFilter方法的参数使用,FilterChain接口中有一个方法:
doFilter(ServletRequest request,ServletResponse response),该方法可以将当前的请求和响应传递到过滤链上的下一个资源,可能是下一个过滤器,也可能是目标资源。
2.3.FilterConfig接口
该接口类型作为Filter接口中的init方法的参数使用,FilterConfig接口中有一个常用方法:
getInitParameter(String name),该方法用来获得过滤器的初始化参数值。
在web.xml中,可以为每一个filter配置需要的初始化参数,与Servlet的< init-param >类似。
过滤器的初始化参数即可通过FilterConfig中的getInitParameter方法获取。
demo代码:
Filter类;
package com.servlet;
import jakarta.servlet.*;
import java.io.IOException;
public class Filter implements jakarta.servlet.Filter {
@Override
//初始化过滤器,等待过滤对象出现
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("FilterStart");
}
@Override
//使用过滤器
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//设置过滤器做的事情
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=UTF-8");
System.out.println("FilterStartBefore");
//让程序向下运行,如果不写,程序到这就会被拦截不走了
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("FilterOverEnd");
}
@Override
//过滤器销毁,web服务器关闭是自动销毁
public void destroy() {
//通知垃圾站回收垃圾
System.gc();
System.out.println("FilterOver");
}
}
Demo类;
package com.show;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Demo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("管");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<servlet>
<servlet-name>Demo</servlet-name>
<servlet-class>com.show.Demo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Demo</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Demo</servlet-name>
<url-pattern>/show/demo</url-pattern>
</servlet-mapping>
<filter>
<filter-name>Filter</filter-name>
<filter-class>com.servlet.Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter</filter-name>
<!--设置过滤的请求路径-->
<url-pattern>/show/*</url-pattern>
</filter-mapping>
</web-app>
问题报错
org.apache.catalina.core.StandardContext.startInternal 一个或多个筛选器启动失败。完整的详细信息将在相应的容器日志文件中找到
org.apache.catalina.core.StandardContext.startInternal 由于之前的错误,Context[]启动失败

检查jar包,导入的jar包是否进来、有用、正确,有无导错包。
例如上面导入的 jakarta.servlet-api 包,如果换成javax.servlet-api 包就会报错,


这两个很像,包不一样就会出问题。导入的包很重要
过滤器在登录中运用
用户登录之后才能进入主页!用户注销后就不能进入主页了!
-
用户登录之后,向Sesison中放入用户的数据
-
进入主页的时候要判断用户是否已经登录;要求:在过滤器中实现!


LoginServlet.java
package com.servlet;
import com.dao.SessionName;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
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 passwd = req.getParameter("passwd");
//判断值
if (username.equals("guan") && passwd.equals("123123")){
//获取一个session,根据key为USER_SESSION,存入sessionID来确保session唯一
req.getSession().setAttribute(SessionName.USER_SESSION,req.getSession().getId());
resp.sendRedirect("/sys/success.jsp");
}
else {
//跳转失败页面
resp.sendRedirect("/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
LogoutServlet.java
package com.servlet;
import com.dao.SessionName;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
//销毁用户登录状态
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取key为USER_SESSION的值
Object user_session = req.getSession().getAttribute(SessionName.USER_SESSION);
if (user_session != null){
//移除key为USER_SESSION的值
req.getSession().removeAttribute(SessionName.USER_SESSION);
}
resp.sendRedirect("/Login.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
SysFilter.java
package com.filter;
import com.dao.SessionName;
import jakarta.servlet.*;
import jakarta.servlet.Filter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
//过滤器
public class SysFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//将ServletRequest、ServletResponse转换为HttpServletRequest、HttpServletResponse
//因为ServletRequest、ServletResponse下没有getSession、setSession
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//获取session中key为USER_SESSION的值
Object user_session = request.getSession().getAttribute(SessionName.USER_SESSION);
//判断是否为空
if (user_session == null){
//跳转失败页面
response.sendRedirect("/error,jsp");
}
//使项目继续运行
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
//回收session垃圾
System.gc();
}
}
SessionName.java
package com.dao;
public class SessionName {
//将session的key设为常量,避免session的key太多和重复
public final static String USER_SESSION="USER_SESSION";
}
Login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录</h1>
<form action="/servlet/login" method="post" >
<label>
账号:<input type="text" name="username"><br>
</label>
<label>
密码:<input type="password" name="passwd"><br>
</label>
<input type="submit" value="登录">
</form>
</body>
</html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>主页</h1>
<p><a href="/servlet/logout">注销</a> </p>
</body>
</html>
error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>404</h1>
<h3>账号或密码错误,无权限访问</h3>
<p><a href="Login.jsp">返回登录页面</a> </p>
</body>
</html>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/servlet/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>com.servlet.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/servlet/logout</url-pattern>
</servlet-mapping>
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
</web-app>
依照代码写时注意,在跳转resp.sendRedirect("");注意application Context
本文来自博客园,作者:mo-de,转载请注明原文链接:https://www.cnblogs.com/mo-de/p/16742165.html

浙公网安备 33010602011771号