过滤器实现过程:
答题实现步骤:
- 编写**Fiter.java 实现Filter接口
- 在启动项添加注解 @ServletComponentScan
Filter 配置编写
@Slf4j
@WebFilter(filterName = "LoginCheckFilter" ,urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// 被拦截的 uri
String uri = request.getRequestURI();
log.info("拦截该请求 {}",request.getRequestURI());
// 进行拦截后的处理逻辑
//释放拦截
filterChain.doFilter(request, response);
}
详解
Filter 使用方法:
暂时记录两种实现方法,具体细节简单测了一下,以后学了注解之类的只是在进行细节分析
- 使用@WebFilter注解,指定拦截路径及一些参数,但是无法确定优先级。同时需要在启动类,使用@ServletComponentScan扫描带@WebFilter、@WebServlet、@WebListener并将其注入bean中。
- 通过@FilterRegistrationBean 实例注册实现
@WebFilter + @ServletComponentScan
@Slf4j
@WebFilter(filterName = "LoginCheckFilter" ,urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
log.info("拦截该请求 {}",request.getRequestURI());
filterChain.doFilter(request, response);
String uri = request.getRequestURI();
// 至少登录界面不应该进行拦截, 写出不需要拦截的所有uri
String[] freeUris = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
boolean check = cheak(uri, freeUris);
if (check) {
log.info("自由权限网页");
filterChain.doFilter(request, response);
return;
}
// 判断登录状态,若一登陆,则直接释放
if (request.getSession().getAttribute("employee") != null) {
log.info("用户已登录");
filterChain.doFilter(request, response);
return;
}
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
log.info("跳转ing....");
return;
}
public boolean cheak(String uri, String[] freeUris) {
for (String u : freeUris ) {
if (PATH_MATCHER.match(u,uri)) {
return true;
}
}
return false;
}
}
在启动类上 添加@ServletComponentScan注解。
如果忘记添加这个注解。就没有将我们编写的过滤器注入spring管理的bean中. 整个程序的没有产生任何拦截 出现任何效果.
@FilterRegistrationBean
package com.itheima.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.R;
import com.sun.javafx.webkit.CursorManagerImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author serendipity
* @version 1.0
* @date 2022/10/21 15:13
**/
@Slf4j
// @WebFilter(filterName = "LoginCheckFilter" ,urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
log.info("拦截该请求 {}",request.getRequestURI());
String uri = request.getRequestURI();
// 至少登录界面不应该进行拦截, 写出不需要拦截的所有uri
String[] freeUris = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
boolean check = check(freeUris,uri);
if (check) {
log.info("自由权限网页");
filterChain.doFilter(request, response);
return;
}
// 判断登录状态,若一登陆,则直接释放
if (request.getSession().getAttribute("employee") != null) {
log.info("用户已登录");
filterChain.doFilter(request, response);
return;
}
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
log.info("跳转ing....");
return;
}
public boolean check(String[] urls,String requestURI) {
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if (match) {
return true;
}
}
return false;
}
}
package com.itheima.reggie.filter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author serendipity
* @version 1.0
* @date 2022/10/21 16:05
**/
@Configuration
public class FilterConfiguration {
@Bean
public FilterRegistrationBean<LoginCheckFilter> test(){
FilterRegistrationBean<LoginCheckFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new LoginCheckFilter()); // 注册自定义过滤器
bean.setName("LoginCheckFilter");// 过滤器名称
bean.addUrlPatterns("/*");// 过滤所有路径
// bean.setOrder(1);// 设置优先级
return bean;
}
}
第二个与上面相比, 唯一的区别就是在实现Filter接口的类, 少了@WebFilter(filterName = "LoginCheckFilter" ,urlPatterns = "/*"), 启动类也没有了@ServletComponentScan 注解.
出现一个问题:
2022-10-21 16:20:01.595 WARN 32632 --- [io-8080-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Failure while trying to resolve exception [org.springframework.http.converter.HttpMessageNotReadableException]
2022-10-21 16:20:01.597 ERROR 32632 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.IOException: Stream closed] with root cause
这个warn 和 error 的话
注意是在filter实现类的代码逻辑处理过程中,将拦截释放掉了,但是后面没有使用return,结束后面的操作.
filterChain.doFilter(request, response);
标签:return,String,request,response,过滤器,import,public
From: https://www.cnblogs.com/serendipity-igao/p/16813893.html