简体   繁体   中英

How to create a json array with multiple objects java spring boot

I have created the user with most comments and highest rated game fine, but stuck on how to create the json array for the average_likes_per_game. I want to make something that looks like this:

{
    "user_with_most_comments": "Alison",
    "highest_rated_game": "Uncharted 4",
    "average_likes_per_game": [
    {
        "title": "Call of Duty, Infinite Warfare",
        "average_likes": 4,
    },
    {
        "title": "Uncharted 4",
        "average_likes": 7,
    }
  ] 
}

Currently it looks like:

{ "user_with_most_comments": "Alison", "highest_rated_game": "Uncharted 4", "average_likes_per_game": "[\"Uncharted 4 \",\"7\",\"Call of Duty, Infinite Warfare \",\"7\"]" }

I can see I've missed out adding the average likes to the number related to the game. And I can't seem to format it correctly even using the Gson setPrettyPrinting thing.

The data I have for the average_likes_per_game at hand is a map containing the name of the game, and the average likes against it. It's just converting that to this json array.

This is done using Spring Boot and I am trying to return everything at once in a pretty json format

@RequestMapping(value = "/games/report", method = RequestMethod.GET)
    public String getReport() throws IOException {
        Map<String, String> report = new HashMap<>();

        String highestRankedGame = gameService.findHighestRatedGame();
        String userWithMostComments = gameService.findUserWithMostComments();
        Map<String,String> averageLikesPerGame = gameService.findAverageLikesPerGame();
        String likesToJsonArray = String.valueOf(gameService.convertLikesToJsonArray(averageLikesPerGame));

        report.put("highest_rated_game",highestRankedGame);
        report.put("user_with_most_comments", userWithMostComments);
        report.put("average_likes_per_game",likesToJsonArray);

        String jsonReport = gameService.convertReportToJson(report);
        String finalJsonReport = gameService.makeMePretty(jsonReport);

        return finalJsonReport;
    }

The find average likes per game returns a map of 2 strings so that it won't cause problems being added to the final report map at the end. Currently my 'convertLikesToJsonarray' is pretty bad and is where I am stuck

    public JSONArray convertLikesToJsonArray(Map<String, String> averageLikesPerGame) throws JSONException {
        JSONArray myArray = new JSONArray();

        for(Map.Entry<String,String> entry : averageLikesPerGame.entrySet()) {
            myArray.put(entry.getKey());
            myArray.put(entry.getValue());
        }
        return myArray;
    }

Worth noting that I convert the final report to json at the end, which may complicate things with the array, as I don't think it's fit for that

    @Override
    public String convertReportToJson(Map<String, String> report) {

        ObjectMapper mapper = new ObjectMapper();
        String jsonArray = null;
        try {
            jsonArray = mapper.writeValueAsString(report);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonArray;
    }
String.valueOf(gameService.convertLikesToJsonArray(averageLikesPerGame)); 

You are making this a single value in the json, instead of it being actual json. That's why it's all escaped in your JSON output. You also haven't shown your pretty print method, so can't comment on the output of that. Try

    //Use object instead of String as you want nested objects in output
    Map<String, Object> report = new HashMap<>();

    String highestRankedGame = gameService.findHighestRatedGame();
    String userWithMostComments = gameService.findUserWithMostComments();
    Map<String,String> averageLikesPerGame = gameService.findAverageLikesPerGame();

    report.put("highest_rated_game",highestRankedGame);
    report.put("user_with_most_comments", userWithMostComments);
   //Add averageLikesPerGame directly to report without modifying
    report.put("average_likes_per_game",averageLikesPerGame.entrySet());

    String jsonReport = gameService.convertReportToJson(report);

    return jsonReport;

And

public String convertReportToJson(Map<String, Object> report) {

    ObjectMapper mapper = new ObjectMapper();
    String jsonArray = null;
    try {
        //Don't need Gson, can use writerWithDefaultPrettyPrinter with Jackson which 
        //You are already using
        jsonArray = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(report);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
    return jsonArray;
}

If you want mapped values in the array with labels then you could do something like this

    List<Map<String,String>> labelledAvgLikesPerGame =
            averageLikesPerGame.entrySet().stream()
                    .map( entry ->
                           //Needs java 9+ for ofEntries
                           //You'll need to make new HashMap,put + return
                           // for java 8
                            Map.ofEntries(
                                    Map.entry("title", entry.getKey()),
                                    Map.entry("average_likes", entry.getValue())
                            )).collect(Collectors.toList());

    report.put("highest_rated_game",highestRankedGame);
    report.put("user_with_most_comments", userWithMostComments);
    report.put("average_likes_per_game",labelledAvgLikesPerGame);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM