将JSON响应格式化为Java数组

huangapple go评论59阅读模式
英文:

Formatting Json Response into an Array Java

问题

Currently I am receiving a response like this from my API:

[{"$id":"1","accommodation_type":"apartment","max_people":2},{"$id":"2","accommodation_type":"lodge","max_people":5}]

I would like to format it so that the output removes all the unnecessary punctuation so that it looks more like this whilst also placing it into an Array:

id, 1, accommodation_type, apartment, max_people, 2, id, 2, accommodation_type, lodge, max_people 5

OR

1, apartment, 2, ,2, lodge, 5

Currently I have tried:

String temp[]= AccommodationTypesStr.split(":|\\,|\\}"); // Where AccommodationTypesStr is the input json string

However between each row of data it leaves a empty space as a element in the array so its like:

id, 1, accomodation_type, apartment, max_people, 2,  ,id, 2, accommodation_type, lodge, max_people 5

Whilst also still having some brackets in the response.

I've messed around with JSON Object and Array but had no luck at all so was wondering if I could do it by formatting it myself.

英文:

Currently I am receiving a response like this from my API:

[{"$id":"1","accommodation_type":"apartment","max_people":2},{"$id":"2","accommodation_type":"lodge","max_people":5}]

I would like to format it so that the output removes all the unnecessary punctuation so that it looks more like this whilst also placing it into an Array.

id, 1, accommodation_type, apartment, max_people, 2, id, 2, accommodation_type, lodge, max_people 5

OR

1, apartment, 2, ,2, lodge, 5

Currently I have tried:

String temp[]= AccommodationTypesStr.split(":|\\,|\\}"); // Where AccommodationTypesStr is the input json string

However between each row of data it leaves a empty space as a element in the array so its like:

id, 1, accomodation_type, apartment, max_people, 2,  ,id, 2, accommodation_type, lodge, max_people 5

Whilst also still having some brackets in the response.

I've messed around with JSON Object and Array but had no luck at all so was wondering if I could do it by formatting it myself.

答案1

得分: 1

你可以使用ObjectMapperjson字符串转换为某个对象,在这种情况下,类似于List<Map<String,Object>>。然后使用java stream api迭代遍历这个列表。

Maven依赖:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.11.1</version>
</dependency>

读取json字符串值:

String json = "[{\"$id\":\"1\",\"accommodation_type\":\"apartment\",\"max_people\":2},{\"$id\":\"2\",\"accommodation_type\":\"lodge\",\"max_people\":5}]";
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> list = mapper.readValue(json, List.class);

然后遍历这个列表:

List<Object> flatList = list.stream()
    .flatMap(element -> element.values().stream())
    .collect(Collectors.toList());

System.out.println(flatList); // [1, apartment, 2, 2, lodge, 5]

或者更详细的变体:

List<Object> flatList = list.stream()
    .map(Map::values)
    .collect(Collectors.toList());

System.out.println(flatList); // [[1, apartment, 2], [2, lodge, 5]]

还有更多:

List<Object> flatList = list.stream()
    .flatMap(element -> element.entrySet().stream())
    .flatMap(entry -> Stream.of(
        entry.getKey().replace("$", ""), // without "$"
        entry.getValue()))
    .collect(Collectors.toList());

System.out.println(flatList);
// [id, 1, accommodation_type, apartment, max_people, 2, id, 2, accommodation_type, lodge, max_people, 5]

总的来说,你可以编写自己的扁平化算法。例如:

英文:

You can use ObjectMapper to convert json string to some object, in this case like List<Map<String, Object>>. Then iterate over this list using java stream api.

Maven dependency:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.11.1</version>
</dependency>

Read json string value:

String json = "[{\"$id\":\"1\",\"accommodation_type\":\"apartment\",\"max_people\":2},{\"$id\":\"2\",\"accommodation_type\":\"lodge\",\"max_people\":5}]";
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> list = mapper.readValue(json, List.class);

Then iterate over this list:

List<Object> flatList = list.stream()
    .flatMap(element -> element.values().stream())
    .collect(Collectors.toList());

System.out.println(flatList); // [1, apartment, 2, 2, lodge, 5]

Or more detailed variant:

List<Object> flatList = list.stream()
    .map(Map::values)
    .collect(Collectors.toList());

System.out.println(flatList); // [[1, apartment, 2], [2, lodge, 5]]

And more:

List<Object> flatList = list.stream()
    .flatMap(element -> element.entrySet().stream())
    .flatMap(entry -> Stream.of(
        entry.getKey().replace("$", ""), // without "$"
        entry.getValue()))
    .collect(Collectors.toList());

System.out.println(flatList);
// [id, 1, accommodation_type, apartment, max_people, 2, id, 2, accommodation_type, lodge, max_people, 5]

In general, you can write your own flattening algorithm. For example:

答案2

得分: 0

你可以创建一个POJO类,然后使用类似Jackson或Gson的库将JSON字符串映射到POJO实例数组中。在这种情况下,我将使用Jackson,你可以通过Maven导入它:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.11.0</version>
</dependency>

POJO类。请注意,我使用@JsonProperty注解来设置JSON字段名称,以便避免使用包含特殊字符的变量名称:

import com.fasterxml.jackson.annotation.JsonProperty;

public class APIResponse {

    @JsonProperty("$id")
    private int id;

    @JsonProperty("accommodation_type")
    private String accommodationType;

    @JsonProperty("max_people")
    private int maxPeople;

    public int getId() {
        return id;
    }

    public int getMaxPeople() {
        return maxPeople;
    }

    public String getAccommodationType() {
        return accommodationType;
    }

    @Override
    public String toString() {
        return "APIResponse{" +
                "id=" + id +
                ", accommodationType='" + accommodationType + '\'' +
                ", maxPeople=" + maxPeople +
                '}';
    }
}

然后,你可以使用以下方式进行反序列化:

final String json = "[{\"$id\":\"1\",\"accommodation_type\":\"apartment\",\"max_people\":2},{\"$id\":\"2\",\"accommodation_type\":\"lodge\",\"max_people\":5}]";
final ObjectMapper mapper = new ObjectMapper();
APIResponse[] responses = mapper.readValue(json, APIResponse[].class);
for (APIResponse response: responses) {
    System.out.println(response.toString());
}

结果:

APIResponse{id=1, accommodationType='apartment', maxPeople=2}
APIResponse{id=2, accommodationType='lodge', maxPeople=5}

最后,你可以通过调用POJO类中的getter方法来访问数据:

responses[0].getId(); // 1
responses[1].getAccommodationType(); // lodge

然后,如果你想要以逗号分隔的方式获取数据,可以使用以下方法:

public String[] getByCommas(APIResponse[] responses) {
    List<String> data = new ArrayList<>();
    for (APIResponse response: responses) {
        data.add("id,");
        data.add(response.getId() + ",");
        data.add("accommodation_type,");
        data.add(response.getAccommodationType() + ",");
        data.add("max_people,");
        data.add(response.getMaxPeople() + ",");
    }
    return data.toArray(new String[data.size()]);
}

然后,只需使用以下方式:

String[] formattedMessage = getByCommas(responses);
for (String s: formattedMessage) {
    System.out.print(s);
}

结果:

id,1,accommodation_type,apartment,max_people,2,id,2,accommodation_type,lodge,max_people,5,

使用JSON映射器在解析JSON数据时非常可靠。如果有其他问题,请告诉我!

英文:

You can create a POJO class and then use libraries like Jackson or Gson to map the JSON string into an array of POJO instances. In this case I will use Jackson you can import it via maven with:

&lt;!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
    &lt;artifactId&gt;jackson-databind&lt;/artifactId&gt;
    &lt;version&gt;2.11.0&lt;/version&gt;
&lt;/dependency&gt;
&lt;!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations --&gt;
&lt;dependency&gt;
    &lt;groupId&gt;com.fasterxml.jackson.core&lt;/groupId&gt;
    &lt;artifactId&gt;jackson-annotations&lt;/artifactId&gt;
    &lt;version&gt;2.11.0&lt;/version&gt;
&lt;/dependency&gt;

The POJO class. Note that I use the annotation @JsonProperty to set the JSON field names so I can avoid using variable names that contain special characters.

import com.fasterxml.jackson.annotation.JsonProperty;

public class APIResponse {

    @JsonProperty(&quot;$id&quot;)
    private int id;

    @JsonProperty(&quot;accommodation_type&quot;)
    private String accommodationType;

    @JsonProperty(&quot;max_people&quot;)
    private int maxPeople;

    public int getId() {
        return id;
    }

    public int getMaxPeople() {
        return maxPeople;
    }

    public String getAccommodationType() {
        return accommodationType;
    }

    @Override
    public String toString() {
        return &quot;APIResponse{&quot; +
                &quot;id=&quot; + id +
                &quot;, accommodationType=&#39;&quot; + accommodationType + &#39;\&#39;&#39; +
                &quot;, maxPeople=&quot; + maxPeople +
                &#39;}&#39;;
    }
}

Then you can deserialize using:

final String json = &quot;[{\&quot;$id\&quot;:\&quot;1\&quot;,\&quot;accommodation_type\&quot;:\&quot;apartment\&quot;,\&quot;max_people\&quot;:2},{\&quot;$id\&quot;:\&quot;2\&quot;,\&quot;accommodation_type\&quot;:\&quot;lodge\&quot;,\&quot;max_people\&quot;:5}]&quot;;
final ObjectMapper mapper = new ObjectMapper();
APIResponse[] responses = mapper.readValue(json, APIResponse[].class);
for (APIResponse response: responses) {
    System.out.println(response.toString());
}

Result:

APIResponse{id=1, accommodationType=&#39;apartment&#39;, maxPeople=2}
APIResponse{id=2, accommodationType=&#39;lodge&#39;, maxPeople=5}

Finally, you can access the data just by calling the getters in the POJO class:

responses[0].getId(); // 1
responses[1].getAccommodationType; // lodge

Then if you want the data separated by commas use:

public String[] getByComas(APIResponse[] responses) {
    List&lt;String&gt; data = new ArrayList&lt;&gt;();
    for (APIResponse response: responses) {
        data.add(&quot;id,&quot;);
        data.add(response.getId() + &quot;,&quot;);
        data.add(&quot;accommodation_type,&quot;);
        data.add(response.getAccommodationType() + &quot;,&quot;);
        data.add(&quot;max_people,&quot;);
        data.add(response.getMaxPeople() + &quot;,&quot;);
    }
    return data.toArray(new String[data.size()]);
}

Then just use:

String[] formattedMessage = getByComas(responses);
for (String s: formattedMessage) {
    System.out.print(s);
}

Result:

id,1,accommodation_type,apartment,max_people,2,id,2,accommodation_type,lodge,max_people,5,

Using JSON mappers is highly recommended as they are pretty reliable when parsing JSON data.

Let me know if this solves your problem!

huangapple
  • 本文由 发表于 2020年8月3日 03:45:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/63220342.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定