Spring引导REST API返回列表/数组格式问题

时间:2016-04-12 18:00:49

标签: rest spring-mvc spring-boot

我正在开发基于Spring boot的Web服务API。我需要为GET响应返回一个事物列表(ProductData)。

这就是响应的样子

<ProductDataList>
  <ProductData>
     <ProductData>...</ProductData>
     <ProductData>...</ProductData>
     <ProductData>...</ProductData>
  </ProductData>
</ProductDataList>

但我不需要额外的<ProductData>标记。 我需要回复如下。

  <ProductDataList>
    <ProductData>...</ProductData>
    <ProductData>...</ProductData>
    <ProductData>...</ProductData>
  </ProductDataList>

知道为什么要生成额外的标签吗?

我的WebMvcConfig文件中有以下内容。

  @Bean
public MappingJackson2XmlHttpMessageConverter xmlConverter() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    builder.propertyNamingStrategy(PropertyNamingStrategy.
            PascalCaseStrategy.PASCAL_CASE_TO_CAMEL_CASE);
    builder.serializationInclusion(JsonInclude.Include.NON_EMPTY);
    builder.failOnUnknownProperties(false);
    MappingJackson2XmlHttpMessageConverter xmlConverter =
            new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build());
    return xmlConverter;
}

在我的控制器中我有

@RequestMapping(value = "/productdata")
@ResponseBody
public ProductDataList getProductData(@RequestParam final String[] ids) {        
    ArrayList<ProductData> products = productDataService.getProductData(ids);

    ProductData[] pdArray = new ProductData[products.size()];
    products.toArray(pdArray);
    ProductDataList productDataList = new ProductDataList();
    productDataList.setProductData(pdArray);

    return productDataList;
}

这是我的ProductDataList类。

public class ProductDataList{

     ProductData[] productData;

     public ProductData[] getProductData() {
           return productData;
     }

     public void setProductData(ProductData[] productData) {
           this.productData = productData;
     }
}

修改1。

当我返回ArrayList<ProductData>时,响应是这样的。

<ArrayList>
  <item>...</item>
  <item>...</item>
  <item>...</item>
</ArrayList>

编辑2。 添加注释JsonTypeInfo后,我取得了一些进展,但并不完全符合我的要求。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY)
public class ProductData {}

<ProductDataList>
     <item _type="ProductData">...</item>
     <item _type="ProductData">...</item>
     <item _type="ProductData">...</item>
<ProductDataList>

2 个答案:

答案 0 :(得分:1)

对象不是那种方式构建的。它正如你所要求的那样:

<ProductDataList>   <!-- the ProductDataList object -->
  <ProductData>     <!-- the property containing the array -->
    <ProductData>...</ProductData>  <!-- each ProductData object -->
    <ProductData>...</ProductData>
    <ProductData>...</ProductData>
  </ProductData>
</ProductDataList>

这是为了确保ProductDataList对象上的其他属性在标记内部也有一个点,例如

<ProductDataList>
  <MyArray>...</MyArray>
  <MyProperty></MyProperty>
</ProductDataList>

为了解决这个问题,你不妨尝试删除对象中间人。

@RequestMapping(value = "/productdata")
@ResponseBody
public ArrayList<ProductData> getProductDataList(@RequestParam final String[] ids) {
    return productDataService.getProductData(ids);
}

如果它可以工作(我似乎记得JAXB无法解析ArrayLists),你的ObjectMapper会给你......

<ArrayList>
  <ProductData>...</ProductData>
  <ProductData>...</ProductData>
  <ProductData>...</ProductData>
</ArrayList>

...而不是您希望的根标记。但是如果它可以工作,那么只需创建一个扩展ArrayList但不做任何事情的类,然后返回它。

public class ProductDataList<E> extends ArrayList<E>{ ... }

然后......

@RequestMapping(value = "/productdata")
@ResponseBody
public ProductDataList<ProductData> getProductDataList(@RequestParam final String[] ids) {
    return (ProductDataList) productDataService.getProductData(ids);
}

快乐狩猎。

  • 基隆

答案 1 :(得分:0)

经过一番努力,我得以解决这个问题。关键是在对象@JacksonXmlElementWrapper(useWrapping = false)

中有@JacksonXmlRootElement(localName = "ProductDataList") public class ProductDataList { @JacksonXmlProperty(localName = "ProductData") @JacksonXmlElementWrapper(useWrapping = false) ProductData[] productDataArray = null; public ProductData[] getProductDataArray() { return productDataArray; } public void setProductDataArray(ProductData[] productDataArray) { this.productDataArray = productDataArray; } }
<ProductDataList>
    <ProductData>...</ProductData>
    <ProductData>...</ProductData>
    <ProductData>...</ProductData>
</ProductDataList>

现在响应看起来就像我想要的那样。

surface = pygame.display.get_surface() #get the surface of the current active display
x,y = size = surface.get_width(), surface.get_height()#create an array of surface.width and surface.height