Filter介绍
在计算机编程中,Filter(过滤器)是一种用于对数据流进行处理的软件组件。Filter 的作用是从输入流中获取数据,对其进行处理后再将其写入输出流中。Filter 组件通常用于数据校验、数据转换、数据压缩等方面,以及对网络通信进行处理。在 Web 开发中,Filter 是 Servlet 标准中的一种组件,用于在 Servlet 执行之前或之后对请求和响应进行处理。可以通过 Filter 实现各种功能,如请求参数过滤、字符编码转换、请求重定向、登录验证等。使用 Filter 组件可以提高 Web 应用的易用性、安全性和可扩展性。
Filter应用场景
Filter(过滤器)是Java Servlet API中一种可以在请求和响应的处理过程中,干预或修改请求和响应的内容的组件。它主要用来过滤HTTP请求和响应,对前端的输入进行过滤,保护系统安全,提高应用的性能等。
Filter应用的场景包括:
-
参数校验:用户输入的参数可能包含恶意字符或参数格式错误,通过使用Filter可以拦截并进行参数校验,以保证应用安全。
-
多语言选择:通过获取请求头的语言参数,Filter可以根据用户的语言选择相应的语言。
-
登录拦截:通过Filter对所有请求进行拦截,检查用户是否登录,若未登录则跳转至登录页面。
-
编码转换:对于不同的请求和响应,可能需要采用不同的编码方式,Filter可以将请求和响应进行编码转换。
-
访问控制:通过Filter实现拦截指定路径的请求,实现权限访问控制。
以上是Filter应用的常见场景,它可以通过Java Servlet API提供的Filter接口进行实现。同时,Filter的执行顺序可以通过在web.xml中配置Filter的顺序来决定。
Filter拦截流程图:
Filter过滤敏感字符
servlet代码
package com.qcnel;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SensitiveWordsFilter implements Filter {
private String[] sensitiveWords = {"你是猪头", "你是笨蛋"};
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化代码
}
public void destroy() {
// 过滤器销毁代码
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
// 获取请求中的输入内容
String content = httpServletRequest.getParameter("content");
// 防止中文乱码
response.setContentType("text/html;charset=utf-8");
// 遍历敏感词列表,检查输入内容是否包含敏感词
for (String sensitiveWord : sensitiveWords) {
if (content.contains(sensitiveWord)) {
// 如果包含敏感词,返回错误响应
httpServletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
httpServletResponse.getWriter().write("您提交的内容包含敏感词,请修改后重试");
return;
}
}
// 如果不包含敏感词,继续处理请求
chain.doFilter(request, response);
}
}
jsp代码
如果没有默认路径,就直接填上"/fl"即可
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/s1/fl" method="get">
敏感字:<input type="text" placeholder="请输入敏感字" name="content"><br>
<input type="submit">
</form>
</body>
</html>
web.xml
大致的流程就是,浏览器先加载到jsp页面,然后再输入框输入值,提交;servlet获取到提交的值,因为servlet的敏感词需要自己添加,我们这里的敏感词是直接先放进去的,实际项目中,肯定是存在数据库中;我这里创建了数组存储敏感词,把表单获取的值跟servlet中的存储敏感词的数组进行比较,为true,则提示或者输出"****";否则false就不屏蔽,当然我这里没有设置;我这个仅仅只过滤一个页面,可以"/*"过滤多个页面;当然我这个有很多缺陷,大概就是这样的流程。希望对大家有帮助。
简单的说就是,创建数组存储敏感词,获取用户输入的值,判断是否存在敏感词,如果出现了敏感词,我们就用*号来替换或者给出提示。
Filter实现权限拦截
文件的目录
success.jsp代码,就是要登录的主页,就是内容页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>主页</title>
</head>
<body>
<h1>主页</h1>
<p><a href="/servlet/logout">注销</a></p>
</body>
</html>
login.jsp代码,登录页面,需要输入用户名,并且匹配成功
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<h1>登录</h1>
<form action="/servlet/login" method="post">
用户名:<input type="text" name="username">
<input type="submit">
</form>
</body>
</html>
error.jsp代码,错误页面,也就是注销页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>error</title>
</head>
<body>
<h1>错误</h1>
<h3>没有权限,用户名错误</h3>
<a href="/login.jsp">返回登录页面</a>
</body>
</html>
SysFilter代码,它是一个过滤器,判断session中的USER_SESSION是否为空,如果为空,则不可以登录主页;意思就是,如果直接把主页的链接复制在浏览器回车,没有拦截,这个过滤器就是拦截的作用
package com.qing.listener;
import com.qing.util.Constant;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SysFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
//ServletRequest HttpServletRequest
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
if(request.getSession().getAttribute(Constant.USER_SESSION) == null){
response.sendRedirect("/error.jsp");
}
chain.doFilter(req,resp);
}
public void destroy() {
}
}
LoginServlet代码
package com.qing.servlet;
import com.qing.util.Constant;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.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");
if(username.equals("admin")){ //登录成功
req.getSession().setAttribute(Constant.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代码
package com.qing.servlet;
import com.qing.util.Constant;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object user_session = req.getSession().getAttribute(Constant.USER_SESSION);
//user_session != null,就说明现在在登录状态
if(user_session != null){
//移除Session
req.getSession().removeAttribute(Constant.USER_SESSION);
//重定向到登录页面
resp.sendRedirect("/login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Constant代码
package com.qing.util;
public class Constant {
public final static String USER_SESSION = "USER_SESSION";
}
web.xml配置映射路径
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.qing.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.qing.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.qing.listener.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
代码效果执行顺序:
我的默认路径是:http://localhost:8080/
第一步:开始运行的时候,需要进入登录页面,浏览器输入"/login.jsp",如下图:
第二步,进入到登录页面之后,输入用户名,然后提交,如果用户名正确,则跳转主页,否则跳转错误页面
第三步,提交之后,进入主页,主页有注销功能,点击注销之后,跳转到登录页面,必须输入用户名才能进入主页,而不能复制主页的url直接登录,因为filter过滤了这个请求,就相当于登进去的时候需要一个标志,表示登陆了,现在我把这个标志移除,就需要在输入账户才能进
注意:这个登录没有请求数据库