JavaWeb之过滤器Filter(通俗易懂版)
今天开发遇到了,简单记录一下!
简介:Filter是JavaWeb三大组件之一(Servlet程序、Listener监听器、Filter过滤器)
作用:既可以对请求进行拦截,也可以对响应进行处理。
1、Filter中的三个方法
import javax.servlet.*;
import java.io.IOException;
/**
* @author 星悦糖
* @createDate 2023/4/28 10:00
*/
public class FilterController implements Filter {
/**
* web应用启动时,web服务器将创建Filter的实例对象,并调用init方法,读取web.xml的配置,完成对象的初始化功能,
* 从而为后续的用户请求做好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次,开发人员通过init的参数,
* 可或得代表当前filter配置信息的FilterConfig对象)
* @param filterConfig
* @throws ServletException
* */
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
/**
* 这个方法完成实际的过滤操作,当客户请求访问与过滤器相关联的URL的时候,Servlet过滤器将先执行doFilter方法,FilterChain参数用于访问后续过滤器
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
* */
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
}
/**
* filter创建后会保存在内存中,当web应用移除或者服务器停止时才销毁,该方法在Filter的生命周期中仅执行一次,在这个方法中,可以释放过滤器使用的资源
* */
@Override
public void destroy() {
}
}
2、Filter的用法
2.1、用法一
- 自定义一个过滤器实现Filter接口、添加@WebFilter注解,配置拦截路径;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
/**
* @author 星悦糖
* @createDate 2023/4/28 10:00
*/
@WebFilter(urlPatterns = "/*")
@Slf4j
public class FilterController implements Filter {
/**
* web应用启动时,web服务器将创建Filter的实例对象,并调用init方法,读取web.xml的配置,完成对象的初始化功能,
* 从而为后续的用户请求做好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次,开发人员通过init的参数,
* 可或得代表当前filter配置信息的FilterConfig对象)
* @param filterConfig
* @throws ServletException
* */
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("过滤器初始化");
}
/**
* 这个方法完成实际的过滤操作,当客户请求访问与过滤器相关联的URL的时候,Servlet过滤器将先执行doFilter方法,FilterChain参数用于访问后续过滤器
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
* */
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("执行过滤操作");
}
/**
* filter创建后会保存在内存中,当web应用移除或者服务器停止时才销毁,该方法在Filter的生命周期中仅执行一次,在这个方法中,可以释放过滤器使用的资源
* */
@Override
public void destroy() {
log.info("web应用被移除或者服务器停止,过滤器终止执行,资源被释放");
}
}
- 在启动类上加上@ServletComponentScan注解
@SpringBootApplication
@ServletComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- controller中和之前一样正常写即可;
2.2、用法二
- 自定义一个过滤器实现Filter接口,在doFilter方法中控制filterChain.doFilter(servletRequest, servletResponse)调用;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import java.io.IOException;
/**
* @author 星悦糖
* @createDate 2023/4/28 10:00
*/
@Slf4j
public class FilterController implements Filter {
/**
* web应用启动时,web服务器将创建Filter的实例对象,并调用init方法,读取web.xml的配置,完成对象的初始化功能,
* 从而为后续的用户请求做好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次,开发人员通过init的参数,
* 可或得代表当前filter配置信息的FilterConfig对象)
* @param filterConfig
* @throws ServletException
* */
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("过滤器初始化");
}
/**
* 这个方法完成实际的过滤操作,当客户请求访问与过滤器相关联的URL的时候,Servlet过滤器将先执行doFilter方法,FilterChain参数用于访问后续过滤器
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
* */
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("执行过滤操作");
filterChain.doFilter(servletRequest, servletResponse);
}
/**
* filter创建后会保存在内存中,当web应用移除或者服务器停止时才销毁,该方法在Filter的生命周期中仅执行一次,在这个方法中,可以释放过滤器使用的资源
* */
@Override
public void destroy() {
log.info("web应用被移除或者服务器停止,过滤器终止执行,资源被释放");
}
}
- 在启动类上注册
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
/**
* 注册Filter
* */
@Bean
public FilterRegistrationBean getFilterRegistrationBean(){
FilterRegistrationBean bean = new FilterRegistrationBean(new FilterController());
bean.addUrlPatterns("/*");
return bean;
}
}
2.3、方法三
- 自定义一个过滤器实现Filter接口、添加@Component注解,配置拦截路径;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 星悦糖
* @createDate 2023/4/28 10:00
*/
@Component
@Slf4j
public class FilterController implements Filter {
/**
* web应用启动时,web服务器将创建Filter的实例对象,并调用init方法,读取web.xml的配置,完成对象的初始化功能,
* 从而为后续的用户请求做好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次,开发人员通过init的参数,
* 可或得代表当前filter配置信息的FilterConfig对象)
* @param filterConfig
* @throws ServletException
* */
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("过滤器初始化");
}
/**
* 这个方法完成实际的过滤操作,当客户请求访问与过滤器相关联的URL的时候,Servlet过滤器将先执行doFilter方法,FilterChain参数用于访问后续过滤器
* @param request
* @param response
* @param filterChain
* @throws IOException
* @throws ServletException
* */
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
//请求参数打印
String filterUrl = httpServletRequest.getRequestURI();
log.info("uri: " + filterUrl);
String url = "/student/user/access"; //controller中的请求路径
if(filterUrl.equals(url)){
log.info("执行要拦截的操作");
filterChain.doFilter(request, response);
}else {
filterChain.doFilter(request, response);
}
}
/**
* filter创建后会保存在内存中,当web应用移除或者服务器停止时才销毁,该方法在Filter的生命周期中仅执行一次,在这个方法中,可以释放过滤器使用的资源
* */
@Override
public void destroy() {
log.info("web应用被移除或者服务器停止,过滤器终止执行,资源被释放");
}
}
- controller中的代码示例
@RestController
@Slf4j
@RequestMapping("/student")
public class UserController {
@PostMapping(value = "/user/access")
public Result getUser(@RequestBody User user) {
return Result.buildSuccess("获取人员信息");
}
}
3、Filter解决前后端交互跨域问题
@Slf4j
public class FilterController implements Filter {
/**
* web应用启动时,web服务器将创建Filter的实例对象,并调用init方法,读取web.xml的配置,完成对象的初始化功能,
* 从而为后续的用户请求做好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次,开发人员通过init的参数,
* 可或得代表当前filter配置信息的FilterConfig对象)
* @param filterConfig
* @throws ServletException
* */
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("过滤器初始化");
}
/**
* 这个方法完成实际的过滤操作,当客户请求访问与过滤器相关联的URL的时候,Servlet过滤器将先执行doFilter方法,FilterChain参数用于访问后续过滤器
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
* */
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest) servletRequest;
log.info(request.getRequestURL().toString());
httpResponse.addHeader("Access-Control-Allow-Origin", "*");
httpResponse.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
httpResponse.addHeader("Access-Control-Max-Age", "3600");
httpResponse.addHeader("Access-Control-Allow-Headers", request.getHeader("Access-Control-Request-Headers"));
httpResponse.addHeader("Access-Control-Allow-Credentials", "true");
if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
httpResponse.setStatus(HttpStatus.OK.value());
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
/**
* filter创建后会保存在内存中,当web应用移除或者服务器停止时才销毁,该方法在Filter的生命周期中仅执行一次,在这个方法中,可以释放过滤器使用的资源
* */
@Override
public void destroy() {
log.info("web应用被移除或者服务器停止,过滤器终止执行,资源被释放");
}
}