[英]Unexpected serialization behavior with configured Jackson ObjectMapper
[英]Strange jackson ObjectMapper behavior
我的 Java 应用程序接收 Spotify API 授权令牌并将它们映射到 Jackson 的 POJO 时遇到问题。
每次我的应用程序从 Spotify API 请求数据时,我都会从这个链接获取一个新的访问令牌: https://accounts.spotify.com/api/token?grant_type=client_credentials
答案是 JSON,看起来像这样:
{
"access_token":"BQAJmzZOdh2egvWEOEwy4wv-VKdhTUc4eZYJrIfAibjWLR4MPfrbV6KBNIiomPwJKsQN-3vmrGmG7lOXFaI",
"token_type":"Bearer",
"expires_in":3600,
"scope":""
}
每次我启动我的应用程序时,第一次运行良好,但随后崩溃:
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `com.slowedandthrowed.darkjazzbot.mapping.spotify.TokenRequest` (although at least
one Creator exists): no String-argument constructor/factory method to deserialize from String value ('BQCcDMOKUiVPscDrrBH77b2QbN9FuqjAJHuM3_1QD39MO9L20XzXneZUlJeIyukBVhPpaCWnKWRjUdggaCM') at [Source: (String)"{"access_token":"BQCcDMOKUiVPscDrrBH77b2QbN9FuqjAJHuM3_1QD39MO9L20XzXneZUlJeIyukBVhPpaCWnKWRjUdggaCM","token_type":"Bearer","expires_in":3600,"scope":""}"; line: 1, column: 17]
每次我需要 map 访问令牌 JSON 到 POJO 时,我通过创建一个新的 ObjectMapper 来解决这个问题,但如果它是一个生产应用程序,它会损害性能,所以我需要找出使用一个的问题是什么一直是 ObjectMapper 实例。
我还尝试将 map 这个 JSON 映射到 Map<String,String> 而不是将其映射到TokenRequest.class
结果是一样的,所以我认为这不是映射失败的原因。
private String requestAccessToken() throws IOException {
TokenRequest tokenRequest = null;
URL accessTokenUrl = new URL(SPOTIFY_TOKEN_LINK);
HttpURLConnection tokenConnection = (HttpURLConnection) accessTokenUrl.openConnection();
tokenConnection.setRequestProperty("Authorization", authString);
tokenConnection.setDoOutput(true);
tokenConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
tokenConnection.setRequestMethod("POST");
OutputStreamWriter wr = new OutputStreamWriter(tokenConnection.getOutputStream());
wr.write(TOKEN_REQUEST_PARAMETERS);
wr.flush();
System.out.println("Wow! Posted!");
InputStream inputStream = tokenConnection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
StringBuilder inputBuilder = new StringBuilder();
String input = null;
while ((input = reader.readLine()) != null) inputBuilder.append(input);
System.out.println("================================= TOKEN INPUT ======================================");
System.out.println(inputBuilder.toString());
System.out.println("================================= TOKEN INPUT ======================================");
tokenRequest = spotifyObjectMapper.readValue(inputBuilder.toString(), TokenRequest.class);
inputStream.close();
reader.close();
tokenConnection.disconnect();
return tokenRequest.getAccessToken();
}
令牌请求.java:
package com.slowedandthrowed.darkjazzbot.mapping.spotify;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonRootName;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"access_token",
"token_type",
"expires_in",
"scope"
})
@JsonRootName("access_token")
public class TokenRequest {
@JsonProperty("access_token")
private String accessToken;
@JsonProperty("token_type")
private String tokenType;
@JsonProperty("expires_in")
private Long expiresIn;
@JsonProperty("scope")
private String scope;
@JsonProperty("access_token")
public String getAccessToken() {
return accessToken;
}
@JsonProperty("access_token")
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
@JsonProperty("token_type")
public String getTokenType() {
return tokenType;
}
@JsonProperty("token_type")
public void setTokenType(String tokenType) {
this.tokenType = tokenType;
}
@JsonProperty("expires_in")
public Long getExpiresIn() {
return expiresIn;
}
@JsonProperty("expires_in")
public void setExpiresIn(Long expiresIn) {
this.expiresIn = expiresIn;
}
@JsonProperty("scope")
public String getScope() {
return scope;
}
@JsonProperty("scope")
public void setScope(String scope) {
this.scope = scope;
}
}
我修复了我的程序,因为我为自己制造了问题。 我通过不同的 API 接收到不同的数据,并通过 Jackson ObjectMapper 的单个实例将其映射到 POJO。 一些JSON object自己包含数据:
{
"property1":value1,
"property2":value2
}
而其他人有单个嵌套的 object,其中包含数据:
{
"object":{"property1":value1,
"property2":value2
}}
所以我决定将 UNWRAP_ROOT_VALUE 变为 TRUE,然后我的 object 映射器更改了它的 state,因此它的行为在我第一次和第二次尝试接收访问令牌时变得不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.