Java 过滤器
什么是过滤器
Filter(过滤器)就是用来过滤请求/返回中的数据用的!
比如:
1、中文乱码的情况
1、登陆验证
3、非法字符
需要知道的:Filter类其实就是Servlet!
Filter本身是存在于哪个地方的?
都说是过滤器了,那么肯定就是处理web容器和Servelt之间的关系了(还需要知道的过滤器不止只有一个,可以有许多个),那么也就是如下显示:

Filter的源码
一个接口,那么也就是如果自己想写一个Filter那么就得继承这个接口,然后实现其中的方法
package javax.servlet;
import java.io.IOException;
public interface Filter {
//初始化调用的函数
default public void init(FilterConfig filterConfig) throws ServletException {}
//过滤器链下一个filter , 如果没有filter,那就是转发给你的Servlet,你所要请求的资源
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
//被销毁的时候调用
default public void destroy() {}
}
Filter简单实现
知识点:过滤器的顺序是web.xml,从上到下执行
编写注意的点:
1、web.xml需要写好对应的filter标签和对应的filter的mapping的标签
2、在实现doFilter方法中,一定要调用chain.doFilter的方法,否则当过滤器拦截了该请求之后,无法将请求进行转发,chain.doFilter将请求转发给过滤器链下一个filter , 如果没有filter,那就是转发给你的Servlet,你所要请求的资源
用到的包有下面的,直接导进去就好了(才知道mysql的驱动包其实直接用maven导入也OK的!!!)
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
Servlet中实现的代码如下:
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("我是doGet方法");
resp.getWriter().print("WOW 我爱上了你");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
过滤器实现的代码:
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("WOW Filter init");
}
@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); //chain.doFilter将请求转发给过滤器链下一个filter,如果没有filter那就是转发给Servlet,你需要请求的资源
System.out.println("我过滤完了...");
}
@Override
public void destroy() {
System.out.println("WOW Filter destroy");
}
}
结果如下,可以看到是 过滤器先接收到请求,然后再转发给Servlet,然后Servlet走了之后又回到过滤器中再之后doFilter之后的内容!

那么问题来了,如果再写一个过滤器,那么这两个过滤器之间的流程是怎么样的?添加的过滤器的内容如下:
public class MyNextFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("我是二号过滤器,我被初始化了");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("我是二号过滤器,我处理了请求");
chain.doFilter(request,response);
System.out.println("我是二号过滤器,我处理了返回的信息");
}
@Override
public void destroy() {
System.out.println("我是二号过滤器,我被销毁了");
}
}

并且过滤的顺序是根据web.xml写的过滤器的顺序一致的!

实现权限拦截
登录界面:login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/login">
账号:<input type="text" name="username" value="">
<input type="submit" value="登陆">
</form>
</body>
</html>
处理登录的逻辑:
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter(IConstant.USERSESSION);
if (username.equals("admin")){
req.getSession().setAttribute(IConstant.USERSESSION, 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);
}
}
映射对应的LoginServlet类
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.zpchcbd.realfilter.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
登录成功的页面:success.jsp
<%@ page import="com.zpchcbd.realfilter.IConstant" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>SESSION ID:<%=request.getSession().getAttribute(IConstant.USERSESSION)%>,登陆成功!!!</h1>
<h1><a href="/logout">注销</a></h1>
</body>
</html>
错误页面:error.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%response.getWriter().print("登陆失败,请检查你的账号是否正确!");%>
<h1><a href="/login.jsp">返回</a></h1>
</body>
</html>
权限拦截实现:无法直接访问success.jsp,若无权限访问则直接返回到error.jsp,通过当前的session中添加特征值来进行判断
public class Myfilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)resp;
Object attribute = request.getSession().getAttribute(IConstant.USERSESSION);
if(attribute == null){
response.sendRedirect("/error.jsp");
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}

浙公网安备 33010602011771号