spring-boot json root name

时间:2016-04-20 14:01:12

标签: json spring-boot

我使用spring-boot 1.3.3并尝试弄清楚如何在JSON序列化上拥有根名称。例如,我想......

{ stores: [
  {
    id: 1,
    name: "Store1"
  },
  {
    id: 2,
    name: "Store2"
  }]
}

但我得到了

[
  {
    id: 1,
    name: "Store1"
  },
  {
    id: 2,
    name: "Store2"
  }
]

我一直在查看@JsonRootName并自定义Jackson2ObjectMapperBuilder配置,但无济于事。在grails中,这对于Json Views来说非常简单,我也试图看看它是如何直接转换为spring-boot的,但仍然无法理解它。

我意识到这与this问题相似,但我觉得在Spring(boot)的上下文中,它可能会以不同的方式应用,并且想知道如何。

4 个答案:

答案 0 :(得分:9)

解决方案1:Jackson JsonRootName

  

我一直在关注@JsonRootName并自定义Jackson2ObjectMapperBuilder配置,但无济于事。

@JsonRootName和Jackson2ObjectMapperBuilder有什么错误?

这适用于我的spring boot(1.3.3)实现:

杰克逊配置Bean

@Configuration
public class JacksonConfig {

    @Bean
    public Jackson2ObjectMapperBuilder jacksonBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.featuresToEnable(SerializationFeature.WRAP_ROOT_VALUE); // enables wrapping for root elements
       return builder;
    }
}

参考:Spring Documentation - Customizing the Jackson ObjectMapper

将@JsonRootElement添加到您的回复实体

@JsonRootName(value = "lot")
public class LotDTO { ... }
HTTP-GET / lot / 1

Json结果

{
  "lot": {
    "id": 1,
    "attributes": "...",
    }
}

至少这适用于一个对象的响应。

我还没想出如何自定义集合中的根名称。 @感知'答案可能会有所帮助How to rename root key in JSON serialization with Jackson

修改

解决方案2:没有Jackson配置

因为我无法弄清楚如何使用jackson自定义集合中的json根名称,所以我调整了@Vaibhav的答案(参见2):

自定义Java注释

@Retention(value = RetentionPolicy.RUNTIME)
public @interface CustomJsonRootName {
    String singular(); // element root name for a single object
    String plural(); // element root name for collections
}

向DTO添加注释

@CustomJsonRootName(plural = "articles", singular = "article")
public class ArticleDTO { // Attributes, Getter and Setter }

在Spring Controller中返回一个Map

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Map<String, List<ArticleDTO>>> findAll() {
  List<ArticleDTO> articles = articleService.findAll();

  if (articles.isEmpty()) {
      return new ResponseEntity<>(HttpStatus.NO_CONTENT);
  }
  Map result = new HashMap();
  result.put(ArticleDTO.class.getAnnotation(CustomJsonRootName.class).plural(), articles);
  return new ResponseEntity<>(result, HttpStatus.OK);
 }

答案 1 :(得分:5)

Spring boot使用jackson作为json工具,所以这样可以正常工作

@JsonTypeName("stores")                                                                                         
@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT ,use = JsonTypeInfo.Id.NAME)
public class stores{ 
.
.
.
 }

答案 2 :(得分:1)

我找到了一种非常简单的方法。而不是返回

ArrayList<Object>

你的对象到前端,只需返回一个

HashMap<String, ArrayList<Object>>

并按以下方式初始化对象列表和相应的HashMap:

List<Object> objectList = new ArrayList<>();

...用你的对象填充你的objectList,然后:

HashMap<String, ArrayList<Object>> returnMap = new HashMap<>();
returnMap.put("lot", objectList);
return returnMap;

你的控制器方法的头部看起来像这样:

@ResponseBody
@RequestMapping(value = "/link", method = RequestMethod.POST)
public HashMap<String, List<Object>> processQuestions(@RequestBody List<incomingObject> controllerMethod) {

这将产生所需的JSON,无需通过注释或其他任何进一步的定义。

答案 3 :(得分:0)

我认为最简单的方法是返回Map <String, Object>。 只需将密钥作为“存储”,将对象作为存储对象。

ex-

Map<String, Object> response = new LinkedHashMap<String, Object>();


response.put("stores", stores)