Java Boot过滤器案例怎么编写

wen java案例 31

本文目录导读:

Java Boot过滤器案例怎么编写

  1. 基础过滤器实现
  2. 方式二:Java配置方式
  3. 实用案例:JWT认证过滤器
  4. 实用案例:XSS过滤过滤器
  5. 完整配置示例
  6. 注意事项

我为您整理了一个Java Boot过滤器的完整案例,包含常见的实现方式和应用场景。

基础过滤器实现

1 方式一:注解方式(推荐)

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(urlPatterns = "/*", filterName = "logFilter")
public class LogFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("日志过滤器初始化");
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
                        FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        long start = System.currentTimeMillis();
        System.out.println("请求URL: " + request.getRequestURL());
        System.out.println("请求Method: " + request.getMethod());
        // 放行请求
        filterChain.doFilter(request, response);
        long end = System.currentTimeMillis();
        System.out.println("请求处理时间: " + (end - start) + "ms");
    }
    @Override
    public void destroy() {
        System.out.println("日志过滤器销毁");
    }
}

2 启动类添加扫描

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan  // 扫描过滤器
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

方式二:Java配置方式

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<AuthFilter> authFilter() {
        FilterRegistrationBean<AuthFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new AuthFilter());
        registration.addUrlPatterns("/*");  // 拦截所有请求
        registration.setName("authFilter");
        registration.setOrder(1);  // 设置执行顺序,数字越小越先执行
        // 设置初始化参数
        registration.addInitParameter("excludePaths", "/login,/register");
        return registration;
    }
    @Bean
    public FilterRegistrationBean<LogFilter> logFilter() {
        FilterRegistrationBean<LogFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new LogFilter());
        registration.addUrlPatterns("/api/*");  // 只拦截/api下的请求
        registration.setName("logFilter");
        registration.setOrder(2);
        return registration;
    }
}

实用案例:JWT认证过滤器

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.util.StringUtils;
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 JwtAuthFilter implements Filter {
    private static final String SECRET_KEY = "your-secret-key";
    private static final String[] EXCLUDE_PATHS = {"/api/login", "/api/register"};
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
                        FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String path = request.getRequestURI();
        // 跳过不需要认证的路径
        if (isExcludedPath(path)) {
            filterChain.doFilter(request, response);
            return;
        }
        // 获取token
        String token = request.getHeader("Authorization");
        if (StringUtils.isEmpty(token) || !token.startsWith("Bearer ")) {
            response.setStatus(401);
            response.getWriter().write("{\"code\":401,\"message\":\"未授权访问\"}");
            return;
        }
        try {
            token = token.substring(7); // 去掉"Bearer "
            Claims claims = Jwts.parser()
                    .setSigningKey(SECRET_KEY)
                    .parseClaimsJws(token)
                    .getBody();
            // 将用户信息存储到request中
            request.setAttribute("userId", claims.get("userId"));
            request.setAttribute("username", claims.get("username"));
            filterChain.doFilter(request, response);
        } catch (Exception e) {
            response.setStatus(401);
            response.getWriter().write("{\"code\":401,\"message\":\"Token无效或已过期\"}");
        }
    }
    private boolean isExcludedPath(String path) {
        for (String excludePath : EXCLUDE_PATHS) {
            if (path.equals(excludePath)) {
                return true;
            }
        }
        return false;
    }
}

实用案例:XSS过滤过滤器

import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class XssFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                        FilterChain chain) throws IOException, ServletException {
        XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper(
                (HttpServletRequest) request);
        chain.doFilter(xssRequest, response);
    }
    // 自定义Request包装器,过滤XSS
    private static class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
        public XssHttpServletRequestWrapper(HttpServletRequest request) {
            super(request);
        }
        @Override
        public String getParameter(String name) {
            String value = super.getParameter(name);
            return cleanXss(value);
        }
        @Override
        public String[] getParameterValues(String name) {
            String[] values = super.getParameterValues(name);
            if (values != null) {
                for (int i = 0; i < values.length; i++) {
                    values[i] = cleanXss(values[i]);
                }
            }
            return values;
        }
        private String cleanXss(String value) {
            if (value != null) {
                // 使用Jsoup清理XSS
                value = Jsoup.clean(value, Whitelist.basic());
                // 额外处理特殊字符
                value = value.replaceAll("<", "&lt;")
                           .replaceAll(">", "&gt;")
                           .replaceAll("\"", "&quot;");
            }
            return value;
        }
    }
}

完整配置示例

1 application.yml配置

server:
  port: 8080
# 过滤器配置(可选)
filter:
  auth:
    exclude-paths: /login,/register,/public/**
logging:
  level:
    com.example.filter: DEBUG

2 使用示例的Controller

import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class TestController {
    @GetMapping("/user/list")
    public String getUserList() {
        return "用户列表数据";
    }
    @PostMapping("/login")
    public String login(@RequestBody LoginRequest request) {
        return "登录成功";
    }
}

注意事项

  1. 执行顺序:多个过滤器时,通过Order属性控制执行顺序
  2. 性能影响:不要写耗时操作在过滤器中
  3. 异常处理:过滤器中异常需要妥善处理,否则可能返回500
  4. 路径匹配:urlPatterns支持通配符,如 /api/**

这个案例涵盖了过滤器的主要使用场景,您可以根据实际需求进行修改和扩展。

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