问题描述
今天在写系统的时候,配置jwt的密钥和过期时间时,application.yaml
中没有提示,且在工具类JwtUtils
爆出idea的错误信息如下:
properties.yaml中没有提示信息:
原因分析:
@ConfigurationProperties 的作用: 让JavaBean中属性值要和配置文件进行映射
由于我在JwtUtils
中使用了该注解,但是又没有进行自动配置,
JwtUtils.java
package com.cycyong.utils;
import com.cycyong.pojo.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Data
@ConfigurationProperties(prefix = "jwt")
@Component
public class JwtUtils {
//密钥
private String secret;
// 过期时间 毫秒
private Long expiration;
/**
* 从数据声明生成令牌
*
* @param claims 数据声明
* @return 令牌
*/
private String generateToken(Map<String, Object> claims) {
Date expirationDate = new Date(System.currentTimeMillis() + expiration);
return Jwts.builder().setClaims(claims).setExpiration(expirationDate).signWith(SignatureAlgorithm.HS512, secret).compact();
}
/**
* 从令牌中获取数据声明
*
* @param token 令牌
* @return 数据声明
*/
public Claims getClaimsFromToken(String token) {
Claims claims;
try {
claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
} catch (Exception e) {
claims = null;
}
return claims;
}
/**
* 生成令牌
*
* @param userDetails 用户
* @return 令牌
*/
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>(2);
claims.put(Claims.SUBJECT, userDetails.getUsername());
claims.put(Claims.ISSUED_AT, new Date());
return generateToken(claims);
}
/**
* 从令牌中获取用户名
*
* @param token 令牌
* @return 用户名
*/
public String getUsernameFromToken(String token) {
String username;
try {
Claims claims = getClaimsFromToken(token);
username = claims.getSubject();
} catch (Exception e) {
username = null;
}
return username;
}
/**
* 判断令牌是否过期
*
* @param token 令牌
* @return 是否过期
*/
public Boolean isTokenExpired(String token) {
Claims claims = getClaimsFromToken(token);
Date expiration = claims.getExpiration();
return expiration.before(new Date());
}
/**
* 刷新令牌
*
* @param token 原令牌
* @return 新令牌
*/
public String refreshToken(String token) {
String refreshedToken;
try {
Claims claims = getClaimsFromToken(token);
claims.put(Claims.ISSUED_AT, new Date());
refreshedToken = generateToken(claims);
} catch (Exception e) {
refreshedToken = null;
}
return refreshedToken;
}
/**
* 验证令牌
*
* @param token 令牌
* @param userDetails 用户
* @return 是否有效
*/
public Boolean validateToken(String token, UserDetails userDetails) {
User user = (User) userDetails;
String username = getUsernameFromToken(token);
return (username.equals(user.getUsername()) && !isTokenExpired(token));
}
}
解决方案:
在使用
@ConfigurationProperties
注解时可以使用spring-boot-configuration-processor.jar 轻松地从带有注释的项目中生成自己的配置元数据文件。该jar包含一个Java注释处理器,在您的项目被编译时会被调用。要使用处理器,请包含对的依赖spring-boot-configuration-processor。
1 添加spring-boot-configuration-processor的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
2 在pom.xml中添加一个新的plugin
添加完成之后,刷新一下即可!!!
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<annotationProcessorPaths>
<path>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
3 查看生成的配置元数据文件
在刷新之后,在target->classes->META-INF目录下生成配置元数据文件:spring-configuration-metadata.json文件
{
"groups": [
{
"name": "jwt",
"type": "com.cycyong.utils.JwtUtils",
"sourceType": "com.cycyong.utils.JwtUtils"
}
],
"properties": [
{
"name": "jwt.expiration",
"type": "java.lang.Long",
"sourceType": "com.cycyong.utils.JwtUtils"
},
{
"name": "jwt.secret",
"type": "java.lang.String",
"sourceType": "com.cycyong.utils.JwtUtils"
}
],
"hints": []
}
到此为止!!!在properties.yaml中自定义的配置会得到提示