本文目录导读:

在Java中实现请求放行(即允许请求通过而不被拦截),最常见的方式是通过过滤器(Filter)或拦截器(Interceptor)来配置白名单,以下是几种主流实现方案:
Servlet Filter 方式(最基础)
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class AuthFilter implements Filter {
// 定义放行路径白名单
private static final List<String> WHITE_LIST = Arrays.asList(
"/login", "/register", "/public/**", "/static/**", "/error"
);
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
String requestURI = req.getRequestURI();
// 判断是否在白名单中
if (isWhiteList(requestURI)) {
// 放行:继续执行后续过滤器或目标资源
chain.doFilter(request, response);
return;
}
// 其他请求进行鉴权处理
if (req.getSession().getAttribute("user") == null) {
resp.sendRedirect("/login");
return;
}
// 放行
chain.doFilter(request, response);
}
private boolean isWhiteList(String uri) {
for (String pattern : WHITE_LIST) {
// 简单匹配,支持通配符 '/**'
if (pattern.endsWith("/**")) {
String base = pattern.substring(0, pattern.length() - 3);
if (uri.startsWith(base)) return true;
} else {
if (uri.equals(pattern)) return true;
}
}
return false;
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void destroy() {}
}
配置web.xml:
<filter>
<filter-name>authFilter</filter-name>
<filter-class>com.example.AuthFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>authFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Spring Boot + HandlerInterceptor 方式
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
@Component
public class AuthInterceptor implements HandlerInterceptor {
private static final List<String> WHITE_LIST = Arrays.asList(
"/login", "/register", "/public/**", "/error"
);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
String requestURI = request.getRequestURI();
// 判断是否放行
if (isWhiteList(requestURI)) {
return true; // 放行
}
// 检查用户是否登录
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/login");
return false; // 拦截
}
return true; // 放行
}
private boolean isWhiteList(String uri) {
for (String pattern : WHITE_LIST) {
if (pattern.endsWith("/**")) {
String base = pattern.substring(0, pattern.length() - 3);
if (uri.startsWith(base)) return true;
} else {
if (uri.equals(pattern)) return true;
}
}
return false;
}
}
配置拦截器:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/**") // 拦截所有请求
.excludePathPatterns( // 排除放行路径
"/login",
"/register",
"/public/**",
"/error",
"/static/**"
);
}
}
Spring Security 方式(最推荐)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
// 放行公共资源
.antMatchers("/login", "/register", "/public/**", "/static/**").permitAll()
// 其他请求需要认证
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
return http.build();
}
}
动态白名单(从数据库读取)
@Component
public class DynamicAuthFilter implements Filter {
@Autowired
private WhiteListService whiteListService;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String requestURI = req.getRequestURI();
// 从数据库获取白名单路径
List<String> whiteList = whiteListService.getWhiteList();
if (whiteList.contains(requestURI)) {
chain.doFilter(request, response); // 放行
return;
}
// 其他逻辑...
chain.doFilter(request, response);
}
}
最佳实践建议
-
使用Spring Security:如果项目使用了Spring Boot,推荐使用Spring Security,它提供了完整的权限管理方案。
-
配置优先级:精确路径 > 通配符路径 > 默认路径
-
性能考虑:对于高频访问的静态资源,建议使用Web服务器(Nginx)直接放行
-
安全提示:避免放行敏感URL如
/admin/**,除非有特殊需求
选择哪种方式取决于你的项目架构:
- Servlet项目:使用Filter
- Spring MVC项目:使用Interceptor
- Spring Boot安全项目:使用Spring Security