Spring Boot集成JWT令牌报错:javax.xml.bind.DatatypeConverter缺失
问题:Spring Boot集成JWT时获取令牌触发500错误(ClassNotFoundException: javax.xml.bind.DatatypeConverter)
按照教程搭建集成JWT令牌的Spring Boot应用,通过Postman发送POST请求、JSON格式传入用户名密码获取令牌时,触发500内部服务器错误,具体报错为java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter。
报错堆栈信息
java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na] at io.jsonwebtoken.impl.Base64Codec.decode(Base64Codec.java:26) ~[jjwt-0.9.1.jar:0.9.1] at io.jsonwebtoken.impl.DefaultJwtBuilder.signWith(DefaultJwtBuilder.java:99) ~[jjwt-0.9.1.jar:0.9.1] at com.JavaInUseSpringSECURITY.JavaInUseSpringSECURITY.JWTTOKEN.JwtUtil.doGenerateToken(JwtUtil.java:49) ~[classes/:na] at com.JavaInUseSpringSECURITY.JavaInUseSpringSECURITY.JWTTOKEN.JwtUtil.generateToken(JwtUtil.java:43) ~[classes/:na]
JwtUtil类代码
@Service public class JwtUtil { private String secret; private int jwtExpirationInMs; @Value("${jwt.secret}") public void setSecret(String secret) { this.secret = secret; } @Value("${jwt.jwtExpirationInMs}") public void setJwtExpirationInMs(int jwtExpirationInMs) { this.jwtExpirationInMs = jwtExpirationInMs; } // generate token for user public String generateToken(UserDetails userDetails) { Map<String, Object> claims = new HashMap<>(); Collection<? extends GrantedAuthority> roles = userDetails.getAuthorities(); if (roles.contains(new SimpleGrantedAuthority("ROLE_ADMIN"))) { claims.put("isAdmin", true); } if (roles.contains(new SimpleGrantedAuthority("ROLE_USER"))) { claims.put("isUser", true); } return doGenerateToken(claims, userDetails.getUsername()); } private String doGenerateToken(Map<String, Object> claims, String subject) { return Jwts.builder().setClaims(claims).setSubject(subject) .setIssuedAt(new Date(System.currentTimeMillis())) .setExpiration(new Date(System.currentTimeMillis() + jwtExpirationInMs)).signWith(SignatureAlgorithm.HS512, secret).compact(); } }
接口响应内容
{ "timestamp": "2022-10-31T16:35:00.188+00:00", "status": 500, "error": "Internal Server Error", "path": "/authenticate" }
解决方案
原因
你使用的JJWT版本(0.9.1)依赖javax.xml.bind.DatatypeConverter,但该类在Java 9及以上版本中已从JDK核心模块中移除,导致类找不到。
方法1:添加JAXB依赖
如果坚持使用JJWT 0.9.1,在Maven的pom.xml中加入以下依赖:
<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.1</version> <scope>runtime</scope> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0.1</version> </dependency> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency>
Gradle项目则在build.gradle中添加:
implementation 'javax.xml.bind:jaxb-api:2.3.1' runtimeOnly 'com.sun.xml.bind:jaxb-impl:2.3.1' implementation 'com.sun.xml.bind:jaxb-core:2.3.0.1' implementation 'javax.activation:activation:1.1.1'
方法2:升级JJWT版本(推荐)
JJWT 0.10.0及以上版本不再依赖JAXB,建议升级到最新稳定版。修改Maven依赖:
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.5</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency>
同时调整JwtUtil中的signWith方法(新版本API变化):
// 修改doGenerateToken方法内的signWith代码 .signWith(SignatureAlgorithm.HS512, Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8)))
需要导入以下类:
import io.jsonwebtoken.security.Keys; import java.nio.charset.StandardCharsets;
内容的提问来源于stack exchange,提问作者Anxheloo
相关产品推荐
相关产品推荐

