【问题标题】:Java - Deserialize a JSON with random root elements without key namesJava - 使用没有键名的随机根元素反序列化 JSON
【发布时间】:2020-07-01 12:46:46
【问题描述】:

我收到以下 JSON 作为来自 rest api 调用的响应:

{
   "RandomTextA" : {
      "Name" : "Test1",
      "Host" : "127.0.0.1",
      "Port" : 435
   },
   "RandomTextB" : {
      "Name" : "Test2",
      "Host" : "123.10.10.4",
      "Port" : 435
   },
    ...
}

根元素值(“RandomTextA”、“RandomTextB”)在调用未知之前是随机的,可以是任何值,因此我不能使用这些值来尝试解析 JSON 或为根项创建 POJO 类。

我想将其反序列化为对象的地图或列表。

我的问题是 JSON 数组的根元素没有键名,我正在寻找一种类似于 C# 字典的方法,以便能够将每个对象数组存储到可搜索的 字典或地图。

目标是能够通过根元素(RandomTextA、RandomTextB)遍历 JSON 树。

这是我的根元素下项目的 POJO 类:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
    "Name",
    "Port",
    "Host"
})
public class InnerEntity implements Serializable {
    
    @JsonProperty("Name")
    private String Name;
    
    @JsonProperty("Port")
    private String Port;
    
    @JsonProperty("Host")
    private String Host;  
    
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();
    
    public InnerEntity(){        
    }
    
    public InnerEntity(String Name,String Port,String Host,String Manufacturer,Boolean AllowEcho,Boolean AllowFind,Boolean AllowMove,Boolean AllowStore){
        super();
        this.Name = Name;
        this.Port = Port;
        this.Host = Host;
    }

    @JsonProperty("Name")
    public String getName() {
        return Name;
    }

    @JsonProperty("Name")
    public void setName(String Name) {
        this.Name = Name;
    }

    @JsonProperty("Port")
    public String getPort() {
        return Port;
    }

    @JsonProperty("Port")
    public void setPort(String Port) {
        this.Port = Port;
    }

    @JsonProperty("Host")
    public String getHost() {
        return Host;
    }

    @JsonProperty("Host")
    public void setHost(String Host) {
        this.Host = Host;
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
    return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
    this.additionalProperties.put(name, value);
    }
}

这里是 api 调用的代码:

public String GetEntities() {
        
        String entities = null;
        
        ClientConfig clientConfig = new ClientConfig();
        if(IS_AUTH_REQ == true) {
            HttpAuthenticationFeature feature = HttpAuthenticationFeature.basic(USERNAME, PASSWORD);
            clientConfig.register(feature);
        }
        
        Client client = ClientBuilder.newClient(clientConfig);
        WebTarget target = client.target(BASE_URL)
                .path("entities")
                .queryParam("expand","");
        Response response =
                target.request(MediaType.APPLICATION_JSON)
                        .get();
        
        if(response.getStatus() == 200) {
            
            String output = response.readEntity(String.class);
            //ObjectMapper mapper = new ObjectMapper();
            //entities = mapper.readValue(output, InnerEntity[].class);
            entities = output;
            
        } else {
                LOG.info("# No entities found.");
        }
        
        return entities;
    }

我可以通过一种非常简单明了的方式实现 C# 中所需的功能:

List<Dictionary<string, InnerEntity>> entities= JsonConvert.DeserializeObject<List<Dictionary<string, InnerEntity>>>(response);

如何在 java 中以类似的方式反序列化 JSON?

【问题讨论】:

    标签: java json serialization deserialization


    【解决方案1】:

    您可以为此目的使用广泛使用的库 FasterXML / jackson。 (Link) 请参阅下面代码示例中的函数“parseJsonToTypedMap()”,了解如何将 JSON-String 解析为 'Map' 对象。 (Java 中的 Map 与 C# 中的 Dictionary 相同)。 如果您不想要一个类型化的 Map,而实际上只是一个 'Map 对象,请查看函数“parseJsonToNotTypedMap()”。

    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.Serializable;
    import java.util.HashMap;
    import java.util.Map;
    
    import com.fasterxml.jackson.annotation.JsonProperty;
    import com.fasterxml.jackson.core.JsonParseException;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    
    public class JsonTest {
    
        String JSON_SOURCE = 
            "{" +
                "\"RandomTextA\" : {" +
                    "\"Name\" : \"Test1\","+
                    "\"Host\" : \"127.0.0.1\","+
                    "\"Port\" : 435" +
                "},"+
                "\"RandomTextB\" : {"+
                    "\"Name\" : \"Test2\","+
                    "\"Host\" : \"123.10.10.4\","+
                    "\"Port\" : 435"+
                "}" +
            "}";
        
        public static class InnerEntity implements Serializable {
            
            @JsonProperty("Name")
            private String Name;
            
            @JsonProperty("Port")
            private String Port;
            
            @JsonProperty("Host")
            private String Host;
    
            @Override
            public String toString() {
                return "InnerEntity [Name=" + Name + ", Port=" + Port + ", Host=" + Host + "]";
            }
        }
        
        public Map<String, InnerEntity> parseJsonToTypedMap(String json) throws JsonParseException, JsonMappingException, IOException {
            TypeReference typedRef = new TypeReference<Map<String, InnerEntity>>() { };
            
            return (Map<String, InnerEntity>) new ObjectMapper().readValue(
                    new ByteArrayInputStream(json.getBytes()), 
                    typedRef);
        }
        
        public Map<String, Object> parseJsonToNotTypedMap(String json) throws JsonMappingException, JsonProcessingException {
            return (Map<String, Object>) new ObjectMapper().readValue(JSON_SOURCE, HashMap.class);
        }
        
        public void runTest() {
            
            try {
                Map<String, InnerEntity> typedResult = parseJsonToTypedMap(JSON_SOURCE);
        
                System.out.println("Typed result:");
                for (Map.Entry<String,JsonTest.InnerEntity> entity : typedResult.entrySet()) {
                    System.out.println("Element Name: " + entity.getKey());
                    System.out.println("Element Values: " + entity.getValue().toString());
                    System.out.println("**********************************************");
                }
                
                System.out.println();
                System.out.println("Untyped result:");
                Map<String,Object> untypedResult = parseJsonToNotTypedMap(JSON_SOURCE);
                for (Map.Entry<String, Object> entity : untypedResult.entrySet()) {
                    System.out.println("Element Name: " + entity.getKey());
                    System.out.println("Element Values: " + entity.getValue().toString());
                    System.out.println("**********************************************");
                }
            
            } catch (JsonParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (JsonMappingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用以下代码。 Foreach "RandomText" 它将创建一个 InnerEntity-Object。

       final ObjectMapper mapper = new ObjectMapper();
              try {
                  mapper.readTree(JSON).fields().forEachRemaining(entry -> {
                      try {
                          final InnerEntity innerEntity = mapper.readValue(entry.getValue().traverse(), InnerEntity.class);
                      } catch (final IOException e) {
                          //handle ex
                      }
                  });
              } catch (final IOException e) {
                  //handle ex
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-06-21
        • 2012-07-27
        • 1970-01-01
        • 2013-10-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多