Java Web Spring Boot中的Filter过滤器详解
概念解释
Filter(过滤器):Filter是Java Web的三大组件之一,另外两个是Servlet和Listener。Filter用于在请求到达目标资源之前或响应返回客户端之前,对请求和响应进行预处理和后处理。Filter可以实现一些通用的操作,如登录校验、统一编码处理、敏感字符处理等。
JWT令牌:JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用环境间安全地将信息作为JSON对象传输。JWT令牌通常用于身份验证和授权。
Spring Boot:Spring Boot是一个用于简化Spring应用开发的框架,它提供了自动配置、嵌入式服务器等特性,使得开发者可以快速构建和部署Spring应用。
Filter的基本使用
1. 定义过滤器
首先,我们需要定义一个过滤器类,实现javax.servlet.Filter
接口,并重写其所有方法。
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class DemoFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init 初始化方法执行了");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Demo 拦截到了请求...放行前逻辑");
// 放行
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("destroy 销毁方法执行了");
}
}
init
方法:过滤器的初始化方法,在Web服务器启动时调用一次。doFilter
方法:每次拦截到请求时调用,可以进行预处理和后处理。destroy
方法:过滤器的销毁方法,在Web服务器关闭时调用一次。
2. 配置过滤器
在Spring Boot中,我们可以使用@WebFilter
注解来配置过滤器,并指定拦截的请求路径。
import javax.servlet.annotation.WebFilter;
@WebFilter(urlPatterns = "/*") // 拦截所有请求
public class DemoFilter implements Filter {
// 过滤器实现代码
}
为了使@WebFilter
注解生效,我们需要在启动类上添加@ServletComponentScan
注解,开启Servlet组件支持。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class TliasWebManagementApplication {
public static void main(String[] args) {
SpringApplication.run(TliasWebManagementApplication.class, args);
}
}
3. 测试过滤器
启动Spring Boot应用,访问任意URL,控制台将输出过滤器的日志信息。
init 初始化方法执行了
Demo 拦截到了请求...放行前逻辑
使用Filter进行JWT令牌验证
1. 添加JWT依赖
在pom.xml
中添加JWT相关的依赖。
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2. 创建JWT工具类
创建一个工具类JwtUtil
,用于生成和验证JWT令牌。
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JwtUtil {
private static final String SECRET = "your_secret_key";
public static String generateToken(String username) {
Map<String, Object> claims = new HashMap<>();
return Jwts.builder()
.setClaims(claims)
.setSubject(username)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10小时
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
}
public static boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
return true;
} catch (Exception e) {
return false;
}
}
public static String getUsernameFromToken(String token) {
Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token).getBody();
return claims.getSubject();
}
}
3. 创建JWT过滤器
创建一个过滤器JwtFilter
,用于拦截请求并验证JWT令牌。
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")
public class JwtFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化操作
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String token = httpRequest.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7);
if (JwtUtil.validateToken(token)) {
chain.doFilter(request, response);
return;
}
}
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
@Override
public void destroy() {
// 销毁操作
}
}
4. 配置启动类
在启动类上添加@ServletComponentScan
注解,开启Servlet组件支持。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class TliasWebManagementApplication {
public static void main(String[] args) {
SpringApplication.run(TliasWebManagementApplication.class, args);
}
}
5. 测试JWT过滤器
启动Spring Boot应用,访问任意URL,如果没有携带有效的JWT令牌,将返回401未授权状态码。
总结
通过上述步骤,我们实现了一个简单的JWT令牌验证过滤器。在实际应用中,可以根据需求进一步扩展和优化,例如处理异常情况、配置白名单、集成Spring Security等。Filter在Spring Boot中是一个非常强大的工具,可以用于各种预处理和后处理任务,帮助我们更好地控制请求和响应的处理流程。