Spring Boot - 返回带有对象数组的 JSON

Posted

技术标签:

【中文标题】Spring Boot - 返回带有对象数组的 JSON【英文标题】:Spring Boot - Returning JSON with array of objects 【发布时间】:2020-02-11 18:46:33 【问题描述】:

使用answer 作为提示,我为/greetings 开发了一个 Spring Boot 控制器,以 JSON 格式返回不同语言的问候语。

当我得到我想要的格式(对象数组)的输出时,如果有更好的方法,请告诉我?

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;
    

收到(有效)输出:


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

【问题讨论】:

【参考方案1】:

如果您只需要对象数组,则不应选择 map 而应使用 List 类型。例如,如果您有 Greeting 对象并且想要返回所有问候的列表,您的 GetMapping 将如下所示:

@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);
    

使用ResponseEntity 可确保您返回正确的状态代码,并且在结束您的响应时,它更易于维护。

编辑:对于您使用 map 创建的键值对,您可以使用 POJO。

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

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


随着这个端点的变化

    @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);
    

但如果上述方法不起作用,您将需要一个自定义序列化程序来像 map 的 key:value 对那样序列化。

this 的帖子可能很有帮助。这篇文章有一个如何编写自定义serializerdeserializer 的完整示例。

【讨论】:

那么,添加个人HashMap&lt;String, String&gt; 是填充List 的唯一方法吗?顺便说一句,您可能想要编辑 &lt;List&lt;Student&gt;&gt; 部分。 谢谢!不,其他方式是您可以实际使用 POJO。更新学生部分,因为我正在考虑举这个例子 能否添加一个 POJO 示例? 已添加示例,以及发布链接以防 JsonValue 注释不起作用,这有助于编写自定义序列化器和反序列化器。【参考方案2】:

虽然您可以使用嵌套的 ListMap 对象,但您的代码很快就会变得不可读。最好创建实际对象。例如:

public class TranslatedGreeting 
  private String language;
  private String greeting;

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

  // add getters

然后在控制器中使用它:

@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;
  

生成的 JSON 将如下所示:

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

这种 JSON 结构也更容易为客户端解析,因为密钥固定在 languagegreeting

如果您真的想保留原始结构,请像这样声明自定义序列化程序:

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

这将输出:

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

【讨论】:

但它失去了 OP 所期望的紧凑 json 结构。同样,我刚刚分享了使用 POJO 时如何解决此问题。

以上是关于Spring Boot - 返回带有对象数组的 JSON的主要内容,如果未能解决你的问题,请参考以下文章

如何将嵌套的 JSON 对象转换为数组 Spring Boot?

在带有 Spring-boot 的 postgres 中使用整数数组

行映射器/转换器在spring boot中将对象数组列表转换为json

使用带有 LIKE 的 mysql 本机查询的 spring boot 搜索返回空

Spring-boot @RequestBody JSON 到带有日期反序列化示例的对象?

Spring Boot 似乎没有找到 Repository