2016-04-12 2 views
0

Я разрабатываю API веб-сервисов на основе Spring Boot. Мне нужно вернуть список вещей (ProductData) для ответа GET.Spring boot REST API Возврат списка форматирования списка/массива

Это то, что ответ выглядит

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

Edit 1.

Когда я вернусь ArrayList<ProductData> ответ был такой.

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

Edit 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

Почему вы не просто вернули «ArrayList »? –

+0

@AliDehghani на самом деле я попробовал. См. Редактирование. – ravindrab

ответ

0

После некоторых усилий мне удалось получить это решить. Главное, чтобы иметь @JacksonXmlElementWrapper(useWrapping = false) в объекте, как указано in this answer

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

Объекты не построены таким образом. Это делает именно так, как вы спрашиваете:

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

Удачной охоты.

  • Кирон
+0

Когда возвращается ArrayList , я вижу список ... вместо ... элементов. См. Редактирование. – ravindrab

+0

Может быть, попробуйте сделать «public class ProductDataList extends ArrayList {/ * blah * /}" - возможно, введенный объект класса сделает класс ObjectMapper XML вместо имени «item». Если нет, похоже, вам может понадобиться добавить какой-то пользовательский ObjectMapper для этого нового объекта ProductDataList. – KieronAlsmith

Смежные вопросы