拦截器(Interceptor)和过滤器(Filter)的执行顺序
- tomcat->Filter->Interceptor->Controller
过滤器(Filter)概述?
Filter过滤器是JavaWeb的三大组件之一,三大组件分别为:Servlet程序、Listener监听器、Filter过滤器。
过滤器(Filter)可以在请求到达Servlet之前或响应离开Servlet之前对请求和响应进行过滤和修改。
Filter的生命周期
Filter的生命周期可分为初始化、请求处理、销毁三个阶段。
1.创建阶段:Web服务器启动的时候会创建Filter实例对象,并调用init()方法(只调用一次!!可以进行读取配置文件,建进行数据库连接等操作),完成对象的初始化。
2.执行阶段:当客户端请求目标资源时,服务器会筛选出符合映射条件的Filter,并按照类名的的先后顺序依次执行doFilter() 方法(可对请求进行预处理、检查请求头、修改请求参数、修改相应数据等操作)。
3.销毁阶段:服务器关闭时,Web服务器调用destroy()方法(只调用一次!!可以进行释放资源、关闭数据库连接等操作)销毁Filter对象。
使用方法
@Component
public class MyFilterOne implements Filter {
/**
* filter对象只创建一次,init方法只执行一次
* FilterConfig对象:代表当前filter配置信息
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 完成实际过滤操作,当客户请求访问与过滤器相关联的URL的时候,Servlet过滤器将先执行doFilter方法,FilterChain参数用于访问后续过滤器
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest,servletResponse);
}
/**
* filter创建后会保存在内存中,当web应用移除或者服务器停止时才销毁,该方法在Filter的生命周期中仅执行一次,可释放过滤器使用的资源
*/
@Override
public void destroy() {
}
}
springboot中,添加多个过滤器,使用示例:
- 创建你的过滤器类:创建一个实现
javax.servlet.Filter
接口的类,实现过滤器的逻辑。例如,你可以创建一个名为MyFilter1
的过滤器类。
import javax.servlet.*;
import java.io.IOException;
public class MyFilter1 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化操作
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 过滤器逻辑
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
// 销毁操作
}
}
- 注册过滤器:在Spring Boot的配置类中,使用
@Bean
注解将过滤器注册到应用程序上下文中。例如,你可以创建一个名为FilterConfig
的配置类,并在其中注册MyFilter1
过滤器。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<MyFilter1> myFilter1() {
FilterRegistrationBean<MyFilter1> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new MyFilter1());
registrationBean.addUrlPatterns("/*"); // 设置过滤器的URL模式
registrationBean.setOrder(1); // 设置过滤器的执行顺序
return registrationBean;
}
}
- 添加其他过滤器:如果你想要添加更多的过滤器,可以按照相同的步骤创建并注册它们。只需创建另一个过滤器类,然后在
FilterConfig
配置类中注册它即可。
@Bean
public FilterRegistrationBean<MyFilter2> myFilter2() {
FilterRegistrationBean<MyFilter2> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new MyFilter2());
registrationBean.addUrlPatterns("/*");
registrationBean.setOrder(2);
return registrationBean;
}
通过以上步骤,你可以在Spring Boot项目中添加多个过滤器,并按照指定的顺序执行它们。记得在过滤器类中实现你需要的逻辑,并在配置类中设置过滤器的URL模式和执行顺序。
FilterRegistrationBean类是Spring框架中用于注册和配置过滤器的类。它允许我们以编程方式注册和配置过滤器,而不是通过web.xml文件进行配置。
常用方法包括:
1. setFilter(Filter filter):设置要注册的过滤器实例。
2. addUrlPatterns(String... urlPatterns):设置过滤器的URL模式,用于指定过滤器要拦截的URL路径。
3. setOrder(int order):设置过滤器的执行顺序,数字越小越先执行。
4. setInitParameters(Map<String, String> initParameters):设置过滤器的初始化参数。
HttpServletRequest和HttpServletResponse
HttpServletRequest
HttpServletRequest是ServletRequest的子接口,ServletRequest是通用接口,里面定义了与HTTP请求相关方法,包括获取请求参数、请求方法、请求头等。HttpServletRequest接口在ServletRequest的基础上,增加了一些专门处理HTTP请求的方法。
例如,客户端请求的地址是:http://www.xuexi.com/demo/test?name=luxifa&&age=25
HttpServletRequest对象的常用方法
- getHeader(string name)方法:根据header参数名称获取值
- getHeaderNames()方法:获取header里面的参数名称
- getParameterMap()方法:获取请求参数对应的map
- getParameter(name)方法:根据请求参数的名称获取对应的值
- getParameterNames():获取所有请求参数的名称的枚举
- getParameterValues(String name):获取指定名称的请求参数的所有值
- getRemoteAddr()方法:获取客户端的IP地址
- getScheme()方法:获取正确的协议,如http协议
- getServerName()方法:服务器主机名
- getServerPort()方法:服务器上web应用的访问端口
- getContextPath()方法:获取域名后的斜杆加工程名,即/demo部分
- getRemoteAddr()方法:发送请求的客户端主机的IP
- getRequestURI()方法:将URL的域名和尾随的参数截取掉,剩下的那部分就是URI,即/demo/test
- getRequestURL()方法:客户请求的url,不包括参数数据;例如http://www.xuexi.com/demo/test
- getMethod()方法:HTTP请求的的方法名,默认是GET,也可指定PUT或POST
- getRealPath(“/WEB-INF”)方法:获取虚拟目录的硬盘实际路径
- getSession():获取与请求关联的会话对象
- getCookies():获取请求中的所有Cookie
- getInputStream():获取请求的输入流,用于读取请求体的内容
HttpServletRequest由Servlet容器在每次接收到HTTP请求时创建,开发者无需手动创建。在Servlet的doGet()、doPost()等方法中,可以通过方法的HttpServletRequest参数获取请求的相关信息
HttpServletResponse
HttpServletResponse用来封装HTTP响应的信息和操作。HttpServletResponse是ServletResponse的子接口,ServletResponse可用于处理任何类型响应,可进行获取输出流、设置相应的内容类型等操作。HttpServletResponse专门用来处理HTTP类型的响应。
一般,使用HttpServletResponse处理HTTP请求响应,使用HttpServletResponse处理其他协议的响应或自定义响应。
HttpServletResponse对象常用功能:
- 设置响应头
- 设置响应状态码
- 设置响应内容类型
- 获取写字符流
- 获取输出流
- 设置重定向
- 设置响应缓存
- 设置错误页面
- 设置Cookie
HttpServletResponse response;
设置响应头
- 可使用setHeader()方法设置响应头,设置的响应头最终会发送给客户端浏览器。
- response.setHeader(“content-type”,
“text/html;charset=utf-8”):设置content-type响应头,告诉浏览器响应内容为html类型,编码为utf-8。 - 还可response.setContentType(“application/json; charset=utf-8”);
- 设置response字符流编码为utf-8:response.setCharaceterEncoding(“utf-8”);
- addheader(name,value):添加头信息。键可以重复
设置响应状态码
- response.setContentType(“text/html;charset=utf-8”):等同于response.setHeader(“content-type”,
“text/html;charset=utf-8”); - response.setCharacterEncoding(“utf-8”):设置字符响应流的字符编码为utf-8;
- response.setStatus(200):设置状态码;
- response.sendError(404,“资源不存在”):当发送错误状态码时,Tomcat会跳转到固定的错误页面,但可以显示错误信息。
设置响应内容类型
- response.setContentType(“application/json; charset=utf-8”); 响应内容类型为json数据
- response.setContentType(“text/html; charset=utf-8”); 响应内容类型为HTML文档
获取写字符流
- PrintWriter out = response.getWriter();调用out 的write()方法可写数据
获取输出流
- ServletOutputStream out = response.getOutputStream()
如果响应正文内容为字符,使用response.getWriter(),如果响应内容是字节,例如下载,则使用response.getOutputStream()。
在一个请求中,不能同时使用这两个流!要么你使用repsonse.getWriter(),要么使用response.getOutputStream(),但不能同时使用,否则会抛IllegalStateException异常。
设置重定向
- 假设访问http://www.a.com时,浏览器地址栏中的URL变成http://www.b.com,这就是重定向即重定向是服务器通知浏览器去访问另一个地址,即再发出另一个请求。
- 使用sendRedirect()方法
设置响应缓存
- 可用setDateHeader()、setIntHeader()和addDateHeader()等方法设置响应的缓存控制信息,如缓存验证、设置过期时间等。
设置错误页面
- sendError()方法可将请求重定向到指定的错误页面。
设置Cookie
- Cookie newCookie=new Cookie(String name,String value);然后调用addCookie()方法
参考博客:
https://blog.csdn.net/Go_Joe/article/details/128535136
https://blog.csdn.net/hanziang1996/article/details/78967400
https://blog.csdn.net/baidu_32935221/article/details/130160185
https://blog.csdn.net/m0_37834446/article/details/81385843
https://blog.csdn.net/u013089490/article/details/83654899