Весенняя загрузка REST API Возвращение проблемы форматирования списка/массива

76
6

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

Вот как выглядит ответ

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

спросил(а) 2021-01-19T18:15:00+03:00 3 месяца, 2 недели назад
1
Решение
97

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

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

Хорошей охоты.

    Кирон

ответил(а) 2021-01-19T18:15:00+03:00 3 месяца, 2 недели назад
45

После некоторых усилий я смог решить эту проблему. @JacksonXmlElementWrapper(useWrapping = false) чтобы в @JacksonXmlElementWrapper(useWrapping = false) был @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>

ответил(а) 2021-01-19T18:15:00+03:00 3 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема