在SpringBootApplication上使用@ServletComponentScan注解后,
Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。
过滤器
默认使用的4个
在启动打印出来的日志里有:
-
Filter 'requestContextFilter' configured for use
-
-
Filter 'characterEncodingFilter' configured for use
-
Filter 'formContentFilter' configured for use
优先级
低位值意味着更高的优先级。自定义Filter,避免和默认的Filter优先级一样,不然会冲突。
作用(使用场景)
-
比如用户验证。
-
如果涉及页面跳转,filter就不适合 前后端分离的情况。
启动类 加上 注解
@ServletComponentScan
自定义的filter
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(urlPatterns = {"/api/*"})
public class LoginFilter implements Filter {
/**
* 容器加载的时候调用
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init loginFilter");
}
/**
* 请求被拦截的时候进行调用
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("doFilter loginFilter");
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String username = request.getParameter("username");
if ("xdclass".equals(username)) {
filterChain.doFilter(request, response);
}else {
response.sendRedirect("/index.html"); // 重定向
}
}
@Override
public void destroy() {
System.out.println("destroy loginFilter");
}
}
测试
添加controller的访问方法。
@GetMapping(value="/api/v1/account")
public Object account(){
params.put("money", "1000");
return params;
}
访问 http://localhost:8080/api/v1/account?username=xdclass
{
"money": "1000"
}
测试通过。
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = {"/v1/api/test/customs"}, name = "userServlet")
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().print("custom sevlet");
resp.getWriter().flush();
resp.getWriter().close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
启动类 加上 @ServletComponentScan , 和 过滤器的使用 很像。
@WebListener
public class RequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
// TODO Auto-generated method stub
System.out.println("======requestDestroyed========");
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
System.out.println("======requestInitialized========");
} 、
}
1、老方法,jdk8之前
继承 WebMvcConfigurerAdapter
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class CustomOldWebMvcConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api/");
super.addInterceptors(registry);
}
2、jdk8之后的新方法
使用 implements WebMvcConfigurer
import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configurationpublic class CustomWebMvcConfigurer implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginIntercepter()) .addPathPatterns("/api/login/**"); WebMvcConfigurer.super.addInterceptors(registry); }}
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
public class LoginIntercepter implements HandlerInterceptor{
/**
* 进入controller方法之前
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("LoginIntercepter------->preHandle");
// String token = request.getParameter("access_token");
//
// response.getWriter().print("fail");
return HandlerInterceptor.super.preHandle(request, response, handler);
}
/**
* 调用完controller之后,视图渲染之前
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("LoginIntercepter------->postHandle");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
/**
* 整个完成之后,通常用于资源清理
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("LoginIntercepter------->afterCompletion");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
小结
-
-
Filter在只在Servlet前后起作用,而Interceptor能够深入到方法前后、异常抛出前后等。
-
依赖于Servlet容器即web应用中,而Interceptor不依赖于Servlet容器所以可以运行在多种环境。
-
在接口调用的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。
-
Filter和Interceptor的执行顺序 过滤前->拦截前->action执行->拦截后->过滤后。
来源:https://www.cnblogs.com/wuyicode/p/11251983.html