【问题标题】:Json string to Java object with dynamic keys带有动态键的 Java 对象的 Json 字符串
【发布时间】:2021-03-24 09:53:57
【问题描述】:

我想向 java 对象插入一个 REST API 响应。我的示例响应如下。

    {
        "key1": [
          {
            "name": "test1",
            "id": "id1",            
          }
        ],
        "key2": [
          {
            "name": "test2",
            "id": "id2",            
          },
          {
            "name": "test3",
            "id": "id3", 
          }
        ]
      }

为此,我为重复对象创建了“用户”类

@Data
public class User {
    private String name;
    private String id;    
}

API 响应正文只接受 Class<T>,为此我将 Map.class 解析为该函数,因为我想将 json 响应数据插入到 Map<String, List<User>> 而不是 java 类对象。

public Mono<Map> getUserInfo(String number) {
        return apiAdaptor.getRequest(urlConfiguration.getUserApi(), Map.class, true
                , number);
    }


public <T> Mono<T> getRequest(String url, Class<T> responseClass, boolean isDds,
                                  String... urlArgs) {
        return Mono.just(this.accessToken)
                .flatMap(token -> this.webClient.get()
                        .uri(url, urlArgs)                     
                        .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                        .exchange()
                        .flatMap(clientResponse -> getClassResponse(clientResponse, responseClass, isDds))                        
                );
    }


private UserResponse handleSuccess(Map map) {        
        Map<String, List<User>> apiRes = map;
}

但是当我遍历 API 响应 (apiRes) 时,它给出了“java.util.LinkedHashMap 无法转换为用户”。正如我检查的那样,如果杰克逊无法识别确切的格式,它将自动转换为“LinkedHashMap”。请帮忙。

请注意,我是 Java 开发新手。

【问题讨论】:

  • 你能补充一下,API 响应正文只接受 Class 是什么意思?如果您将对象定义为Map,它就是Map(所以LinkedHashMap)并且不会有任何额外的类型信息。每个 complex 值也将是 Map,并且无法将其转换为 User
  • 请发布您正在使用的代码,它会给出您的错误
  • @pirho 更新了问题。
  • @Toerktumlare 更新了问题。

标签: spring-boot spring-mvc java-8 spring-webflux


【解决方案1】:

一个技巧是声明自己的类,以保留要正确编译和转换的泛型类型。比如:

@SuppressWarnings("serial")
public class DynKeyUserMap extends HashMap<String, List<User>> {}

然后,不要使用Map.class,而是使用DynKeyUserMap.class 来防止转换问题。

【讨论】:

  • 需要对上面创建的类进行硬编码以进行单元测试。你能解释一下,如何为上面创建实例。我尝试了以下一个,但它显示编译错误。 DynKeyUserMap dynKeyUserMap = new HashMap>();
  • @udith 只是DynKeyUserMap dynKeyUserMap = new DynKeyUserMap();?
【解决方案2】:

我不确定您使用哪个 Httpclient 进行开发。但是,使用 RestTemplate 客户端,您可以执行以下操作

Map<String, List<User>> responseMap= new HashMap<>();
ResponseEntity<Map<String, List<User>>> response =new RestTemplateBuilder().build().getForEntity(url, responseMap.getClass());

我使用了构建器,以便使用默认消息转换器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-17
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 2019-01-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多