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 的帖子可能很有帮助。这篇文章有一个如何编写自定义serializer
和deserializer
的完整示例。
【讨论】:
那么,添加个人HashMap<String, String>
是填充List
的唯一方法吗?顺便说一句,您可能想要编辑 <List<Student>>
部分。
谢谢!不,其他方式是您可以实际使用 POJO。更新学生部分,因为我正在考虑举这个例子
能否添加一个 POJO 示例?
已添加示例,以及发布链接以防 JsonValue 注释不起作用,这有助于编写自定义序列化器和反序列化器。【参考方案2】:
虽然您可以使用嵌套的 List
和 Map
对象,但您的代码很快就会变得不可读。最好创建实际对象。例如:
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 结构也更容易为客户端解析,因为密钥固定在 language
和 greeting
。
如果您真的想保留原始结构,请像这样声明自定义序列化程序:
@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 搜索返回空