如何用Jackson的ObjectMapper将REST返回的JSON的token节点映射为Java对象
嗨,我来帮你搞定这个Jackson映射的问题!咱们需要解决两个核心点:精准提取JSON里的token子节点,以及处理expiresIn字段的类型不匹配(JSON里是ISO日期字符串,你的Token类里是long类型)。下面给你两种实用的实现方式:
使用Jackson ObjectMapper映射JSON的"token"节点到Token对象
方法一:通过JsonNode先提取节点再映射(无需额外POJO)
如果只需要提取token部分,这种方式更直接,不用创建多余的类:
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.time.Instant; public class TokenMappingDemo { public static void main(String[] args) throws IOException { // 替换成你从REST服务拿到的实际JSON字符串 String jsonResponse = "{\"token\":{\"tokenType\":\"Bearer\",\"accessToken\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MTU0MDY0MjgsImlhdCI6MTUxNTQwNTUyOCwic3ViIjoiNWE1MzQwZDg4NmUxYTc2ZGU2MTY2NTQ2In0.7YjmghgAQLtyNaPuWDp9StQBJv79JQZD3G_XbKvYOaQ\",\"refreshToken\":\"5a5340d886e1a76de6166546.35e821dd2042efad2add8da80d6c765bded3ca37078415a4ebe46f9ba8da312a6d16cc05e91431bc\",\"expiresIn\":\"2018-01-08T10:13:48.261Z\"},\"user\":{\"id\":\"5a5340d886e1a76de6166546\",\"email\":\"testingsest@gmail.com\",\"role\":\"user\",\"createdAt\":\"2018-01-08T09:58:48.153Z\"}}"; ObjectMapper objectMapper = new ObjectMapper(); // 先把整个JSON解析成树形结构 JsonNode rootNode = objectMapper.readTree(jsonResponse); // 精准提取"token"子节点 JsonNode tokenNode = rootNode.get("token"); // 处理expiresIn的类型转换:把ISO日期转成毫秒时间戳(如果要秒级就用toEpochSecond()) String expiresInStr = tokenNode.get("expiresIn").asText(); long expiresInTimestamp = Instant.parse(expiresInStr).toEpochMilli(); // 把token节点转成Token对象,再手动设置转换后的时间戳 Token token = objectMapper.treeToValue(tokenNode, Token.class); token.setExpiresIn(expiresInTimestamp); // 验证结果 System.out.println("AccessToken: " + token.getAccessToken()); System.out.println("ExpiresIn(毫秒戳): " + token.getExpiresIn()); } }
方法二:用外层POJO+自定义反序列化器(更优雅规范)
如果后续可能用到user节点,或者想让代码更符合POJO设计规范,推荐这种方式:
步骤1:自定义ExpiresIn的反序列化器
用来自动把ISO日期字符串转成long类型的时间戳:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.io.IOException; import java.time.Instant; public class ExpiresInDeserializer extends JsonDeserializer<Long> { @Override public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String dateStr = p.getText(); // 转成毫秒时间戳,需要秒级就换成toEpochSecond() return Instant.parse(dateStr).toEpochMilli(); } }
步骤2:修改Token类,添加反序列化注解
在expiresIn字段上标注使用我们自定义的转换器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; public class Token { String tokenType; String accessToken; String refreshToken; @JsonDeserialize(using = ExpiresInDeserializer.class) long expiresIn; // 原有getter/setter保持不变 public String getTokenType() { return tokenType; } public void setTokenType(String tokenType) { this.tokenType = tokenType; } public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public String getRefreshToken() { return refreshToken; } public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; } public long getExpiresIn() { return expiresIn; } public void setExpiresIn(long expiresIn) { this.expiresIn = expiresIn; } }
步骤3:创建外层响应POJO
用来包裹整个JSON的结构:
public class AuthResponse { private Token token; private User user; // 不需要的话可以删掉,需要的话自己创建对应的User类即可 // getter/setter public Token getToken() { return token; } public void setToken(Token token) { this.token = token; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
步骤4:直接映射整个JSON到AuthResponse
import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; public class TokenMappingDemo { public static void main(String[] args) throws IOException { String jsonResponse = "{\"token\":{...},\"user\":{...}}"; // 实际JSON字符串 ObjectMapper objectMapper = new ObjectMapper(); // 直接把整个JSON映射到AuthResponse,Jackson会自动处理所有字段转换 AuthResponse authResponse = objectMapper.readValue(jsonResponse, AuthResponse.class); Token token = authResponse.getToken(); // 验证结果 System.out.println("TokenType: " + token.getTokenType()); System.out.println("ExpiresIn(毫秒戳): " + token.getExpiresIn()); } }
额外注意
- 确保项目引入了Jackson核心依赖,比如Maven的pom.xml添加:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> <!-- 用最新稳定版即可 --> </dependency>
内容的提问来源于stack exchange,提问作者Ferguson
相关产品推荐
相关产品推荐

