简体   繁体   中英

Spring Boot - Returning JSON with array of objects

Using this answer as a hint, I developed a Spring Boot controller for /greetings to return greeting in different languages in JSON.

While I am getting the output in the format (array of objects) I wanted, can you please let me know if there is a better way?

package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;

@RestController
public class GreetingController {
    @GetMapping("/greetings")
    public HashMap<String, Object> getGreeting() {
        ArrayList<Object> al = new ArrayList<Object>();
        HashMap<String, String> map1 = new HashMap<String, String>();
        map1.put("en", "Greetings!");
        al.add(map1);
        HashMap<String, String> map2 = new HashMap<>();
        map2.put("hi", "Namaste!");
        al.add(map2);
        //
        HashMap<String, Object> finalMap = new HashMap<>();
        finalMap.put("all", al);
        return finalMap;
    }
}

Received (valid) output:

{
    "all": [
        {
            "en": "Greetings!"
        },
        {
            "hi": "Namaste!"
        }
    ]
}

If you just need array of objects you shouldn't choose map rather use List type. For example, if you have Greeting objects and you want to return a list of all greetings your GetMapping would be something like below:

@GetMapping("/greetings")
    public ResponseEntity<List<Map<String,String>>> getGreeting() {
        ArrayList<Object> al = new ArrayList<Object>();
        HashMap<String, String> map1 = new HashMap<String, String>();
        map1.put("en", "Greetings!");
        al.add(map1);
        HashMap<String, String> map2 = new HashMap<>();
        map2.put("hi", "Namaste!");
        al.add(map2);
        return ResponseEntity.ok(al);
    }

Using ResponseEntity ensures that you are returning right status code and as it's wrapping up your response, it's more maintainable.

Edit: For key value pairs that you have created using map you can use POJO.

class Greeting{
   private String greetingLangCode;
   private String greetingText;
   // getters and setters

 @JsonValue
public String info(){
 return this.greetingLangCode + ":" + "greetingText";
}
}

With this endpoint changes to

    @GetMapping("/greetings")
    public ResponseEntity<List<Greeting>> getGreeting() {
        List<Greeting> al = new ArrayList<>();
        al.add(new Greeting("en", "Greetings!"));
        al.add(new Greeting("hi", "Namaste!"));
        return ResponseEntity.ok(al);
    }

But in case above don't work, you will require a custom serializer to serialize like map's key:value pair.

Probably this post is helpful. This post have a complete example of how to write custom serializer and deserializer .

While you can use nested List and Map objects, your code becomes unreadable quite soon. It is better to create actual objects. Eg:

public class TranslatedGreeting {
  private String language;
  private String greeting;

  public TranslatedGreeting(String language, String greeting) {
    this.language = language;
    this.greeting = greeting;
  }

  // add getters
}

Then use that in the controller:

@RestController
public class GreetingController {

  @GetMapping("/greetings")
  public List<TranslatedGreeting> greetings() {
    List<TranslatedGreeting> result = new ArrayList<>();
    result.add(new TranslatedGreeting("en", "Greetings!"));
    result.add(new TranslatedGreeting("hi", "Namaste!");
    return result;
  }
}

The resulting JSON will be like:

[
  {"language":"en","greeting":"Greetings!"},
  {"language":"hi","greeting":"Namaste!"},
]

This JSON structure is also easier to parse for clients as the keys are fixed on language and greeting .

If you really want to keep the original structure, declare a custom serializer like this:

@JsonComponent
public class TranslatedGreetingSerializer extends JsonSerializer<TranslatedGreeting> {
    @Override
    public void serialize(TranslatedGreeting translatedGreeting, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeStringField(translatedGreeting.getLanguage(), translatedGreeting.getGreeting());
        jsonGenerator.writeEndObject();
    }
}

This will output:

[
  {
    "en": "Greetings!"
  },
  {
    "hi": "Namaste!"
  }
]

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