2

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.

Ross
  • 141
  • 7

2 Answers2

1

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:

0

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:

<!-- 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>

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("$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 +
                '}';
    }
}

Then you can deserialize using:

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());
}

Result:

APIResponse{id=1, accommodationType='apartment', maxPeople=2}
APIResponse{id=2, accommodationType='lodge', 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<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()]);
}

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!

PauMAVA
  • 1,163
  • 14
  • 23