Java案例怎么实现请求放行?

wen java案例 30

本文目录导读:

Java案例怎么实现请求放行?

  1. Servlet Filter 方式(最基础)
  2. Spring Boot + HandlerInterceptor 方式
  3. Spring Security 方式(最推荐)
  4. 动态白名单(从数据库读取)
  5. 最佳实践建议

在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);
    }
}

最佳实践建议

  1. 使用Spring Security:如果项目使用了Spring Boot,推荐使用Spring Security,它提供了完整的权限管理方案。

  2. 配置优先级:精确路径 > 通配符路径 > 默认路径

  3. 性能考虑:对于高频访问的静态资源,建议使用Web服务器(Nginx)直接放行

  4. 安全提示:避免放行敏感URL如 /admin/**,除非有特殊需求

选择哪种方式取决于你的项目架构:

  • Servlet项目:使用Filter
  • Spring MVC项目:使用Interceptor
  • Spring Boot安全项目:使用Spring Security

抱歉,评论功能暂时关闭!