为什么 ResponseEntity<Foo> 得到的结果与 ResponseEntity<String> 不同?

问题描述 投票:0回答:1

对于我的 Java Spring Boot 应用程序 (v2.7.12),我使用

restTemplate.exchange()
执行 GET 请求,该请求传入我正确的
url
、具有正确标头的
HttpEntity
以及响应类型
Profile.class

它将其分配给

ResponseEntity<Profile> response

ResponseEntity<Profile> response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Profile.class);

现在, 当我将其分配给 String 类型:

ResponseEntity<String> response
而不是 Profile 时,
response.getBody()
返回正确的 json 正文,并包含正确的数据:
name: random

<200,{"user":{"username='instagram', full_name='instagram'}

然而, 当我将其分配给配置文件类型:

ResponseEntity<Profile> response
时,它返回正确的 json 正文,但数据无效:
name: null

<200,{"user":{"username='null', full_name='null'}

我想要做的是将确切的 API 属性分配给我的 Profile 模型类,而不需要自己解析 JSON 以获得 HTML 类型。

    @JsonIgnoreProperties(ignoreUnknown = false)
public class Profile {
    @JsonProperty("username")
    private String username;
    @JsonProperty("full_name")
    private String full_name;
    @JsonProperty("is_private")
    private boolean is_private;
    @JsonProperty("status")
    private String status;
    @JsonProperty("profile_pic_url")
    private String profile_pic_url;
    @JsonProperty("follower_count")
    private int follower_count;
    @JsonProperty("following_count")
    private int following_count;
    @JsonProperty("biography")
    private String biography;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

这是我的休息模板:

@Controller
public class WebController {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder){
        return builder.build();
    }

我知道这个问题有一个简单的解决方法。我尝试过使用 Jackson API 从 String 类型响应主体中解析 JSON,但我希望这是 B 计划。

我尝试过更改 URL 格式,但没有什么区别。 标题很好。 API本身并没有错。

Profile profile = restTemplate.getForObject(uri, Profile.class)

我尝试使用之前有效的

.getForObject
,但我需要传入标头,但它不能做到这一点。

java spring-mvc
1个回答
1
投票

您的 JSON 有一个名为

user
的根元素。您正在尝试反序列化,假设没有根元素。这就是为什么它不起作用,Jackson 尝试在根上查找
Profile
类的字段,但它从未找到其中任何一个,因为它们被包装到另一个对象中。

首先,以这种方式配置您的

ObjectMapper
(最好将此代码放在
@Configuration
带注释的类中:

@Bean
public ObjectMapper objectMapper(ObjectMapper objectMapper) {
    objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
    
    return objectMapper;
}

这将告诉对象映射器允许使用根值进行反序列化。

现在,用

Profile
注释你的
@JsonRootName
类:

@JsonRootName(value = "user")
public class Profile {
    // ...
}

这样,在反序列化时,Jackson 将在将 JSON 反序列化为

Profile
对象之前解开您的值。

© www.soinside.com 2019 - 2024. All rights reserved.