提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
- filter的作用
拦截用户请求,并可以在拦截后修改request和response - filter的执行顺序
首先看web.xml中配置的的顺序有关,越往前的越先执行,进行目标的拦截。若用FIlter类,改写url-pattern,则加载的顺序与Filter的名字有关,类似于字符串比较大小,越小的越先执行。 - filter的作用对象
即中url-pattern中你所写的
一、filter拦截请求
拦截多简单
当filter不调用chain.doFilter(request, response)方法就可实现实现拦截
当然你可设置一些条件来判断是否进行拦截,
这里我有两个过滤器MyFilter01和MyFilter02,以及一个核心业务也就是我的servlet,MyServlet
下面是我的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>j2018001001_08_servletAndMultiFilters</display-name>
<filter>
<filter-name>MyFilter01</filter-name>
<filter-class>com.example.demo2.MyFilter01</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter01</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<filter>
<filter-name>MyFilter02</filter-name>
<filter-class>com.example.demo2.MyFilter02</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter02</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.example.demo2.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
从配置文件中可知 我两个过滤器的都是/MyServlet。也就是所他们的作用对象是/MyServlet。当我请求/MyServlet时,过滤器开始起作用。
以及可知它们的执行顺序,先执行MyFilter01,再执行MyFilter02
- MyServlet
package com.example.demo2;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 用servlet来模拟核心业务动作
*/
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1这里不用再设置编码和处理中文乱码问题,因为过滤器已经预设过了
// 2这里只需要处理核心业务
PrintWriter out = response.getWriter();
out.write("这里是Servlet的输出,Servlet工作中...模拟的是核心业务");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- MyFilter01
package com.example.demo2;
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.annotation.WebFilter;
/**
* <h1> 过滤器1</h1>
* @author fhzheng
*
*/
public class MyFilter01 implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 过滤器也可以给出响应,但不是处理业务,它只是准备的需要
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
// 让客户端也可以看到过滤效果,相当于是把核心内容包装成了一个HTML页【HTML标签首】
out.write("<html>"
+ "<head><title>Filter and Servlet</title></head>"
+ "<body>");
out.write("这里是过滤器01工作中开始...模拟的是一号过滤器<br />");
// 但核心业务仍然得放行,交给相应的Servlet去处理,项目中,职责要清晰
chain.doFilter(request, response);
// 【HTML标签尾】
out.write("<br />这里是过滤器01工作中结束...<br />");
out.write("</body></html>");
}
}
- MyFilter02
package com.example.demo2;
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.annotation.WebFilter;
/**
* <h1>过滤器2</h1>
* <li>与过滤器1,形成两级过滤动作
*/
public class MyFilter02 implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 过滤器在这里做的工作,与之前对比,仅只是想在客户端,即浏览器中也可以看到它的存在
PrintWriter out = response.getWriter();
out.write("这里是过滤器02工作中开始...模拟的是二号过滤器<br />");
// 放行后,核心业务仍然走Servlet处理
chain.doFilter(request, response);
out.write("<br />这里是过滤器02工作中结束...<br />");
}
}
最后运行,请求MyServlet
浏览器显示如下
当我们删除 MyFilter01中的chain.doFilter(request, response);方法调用时。也就实现了拦截,浏览器显示如下
可以看出没有显示servlet中的那句话,就是请求被拦截了。
二、filter修改请求
我的解就是重写方法,或者说通过重写String getParameter(String name)方法,来达到修改请求的目的
下面我的copy到的关于修改请求的文字
Filter中修改请求参数、请求头原理:
在servlet、Controller中处理request的对象是HttpServletRequest接口实现类,HttpServletRequestWrapper类实现类该接口;我们可以利用装饰模式,创建一个装饰类继承HttpServletRequestWrapper,然后重写其中关于请求参数、请求头的方法,最后在Filter中将装饰类再传递下去,这样servlet中就可以通过getParameter方法获取被修改过的请求参数来。
我看了一下其他的博客,那么长,直接就不想看了。
下面是连接
链接: https://blog.youkuaiyun.com/liuxiao723846/article/details/117701643