RestClient: как правильно разобрать ответ text/xmlJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 RestClient: как правильно разобрать ответ text/xml

Сообщение Anonymous »

Мне нужно использовать внешний REST API, который возвращает не json (application/json), а xml (

Код: Выделить всё

text/xml
, если быть точным, а не application/xml). Я использую новый RestClient, представленный в Spring Boot 3.2.
Это пример данных, которые возвращает внешний API:
< pre class="lang-xml Prettyprint-override">

Код: Выделить всё

Someone

Я не могу изменить тип ответа на основе заголовка Accept, внешний API возвращает только данные типа text/xml. Конечно, поскольку это внешний API, я не имею права голоса в отношении типа возвращаемого значения.
Я создал этот класс:

Код: Выделить всё

@Data
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement(name = "Player")
@XmlAccessorType(XmlAccessType.FIELD)
public class PlayerModel {
@XmlElement(name = "NAME")
private String name;
}
И я попробовал это:

Код: Выделить всё

RestClient restClient = RestClient.create();

PlayerModel result = restClient.get()
.uri(url)
.retrieve()
.body(PlayerModel.class);
Но это все привело к сбою, так как каждый раз, когда я вызывал внешний API, он говорил, что не понимает, как демаршалировать что-то типа text/xml.
Затем я прочитал весеннюю документацию о клиентах REST и преобразовании HTTP-сообщений. Там говорилось, что существует множество HttpMessageConverter, и что каждый из них имеет тип носителя по умолчанию, который он поддерживает. Я предполагаю, что все, что RestClient использует по умолчанию, не поддерживает по умолчанию тип text/xml, поэтому я решил использовать один из предложенных. Я был между MarshallingHttpMessageConverter и MappingJackson2XmlHttpMessageConverter.
С MarshallingHttpMessageConverter у меня возникли проблемы, так как я хотел использовать Unmarshaller, созданный на основе JAXBContext (далее будет код об этом), который создает Unmarshaller из jakarta.xml.bind.Unmarshaller. Однако при создании MarshallingHttpMessageConverter, если вы попытаетесь передать ему этот Unmarshaller (он принимает как Unmarshaller, так и Marshaller), произойдет сбой, поскольку он ожидает Unmarshaller от org.springframework.oxm.Unmarshaller . Не знаю, но, возможно, то, что мне нужно, близко к этому.
Поскольку это не совсем сработало, я использовал MappingJackson2XmlHttpMessageConverter, вот так:

Код: Выделить всё

RestClient restClient = RestClient.builder()
.messageConverters(converters -> {
MappingJackson2XmlHttpMessageConverter converter = new MappingJackson2XmlHttpMessageConverter();
converter.setSupportedMediaTypes(List.of(MediaType.APPLICATION_XML, MediaType.TEXT_XML));
converters.add(converter);
})
.build();
Теперь он не взрывается, но при проверке результата переменной PlayerModel имя имеет значение null, то есть оно его не перехватило (должно быть Кто-то , но имеет значение null).
Наконец, я решил перехватить его как строку вместо PlayerModel и использовать JAXB создал Unmarshaller для демаршалинга XML-содержимого строки в playerModel:

Код: Выделить всё

RestClient restClient = RestClient.builder()
.messageConverters(converters -> {
MappingJackson2XmlHttpMessageConverter converter = new MappingJackson2XmlHttpMessageConverter();
converter.setSupportedMediaTypes(List.of(MediaType.APPLICATION_XML, MediaType.TEXT_XML));
converters.add(converter);
})
.build();

String result = restClient.get()
.uri(url)
.retrieve()
.body(String.class);

PlayerModel playerModel;

try {
Unmarshaller unmarshaller = JAXBContext.newInstance(PlayerModel.class).createUnmarshaller();
playerModel = (PlayerModel) unmarshaller.unmarshal(new StringReader(result));
} catch (JAXBException e) {
throw new RuntimeException(e);
}

return playerModel;
Это работает, но мне нужен лучший способ сделать это. Я знаю, что он должен быть, но я уже потратил на это много времени. Возможно, с какой-нибудь конфигурацией Bean, а может быть, с другим HttpMessageConverter или другим Unmarshaller. Цель такова:

Код: Выделить всё

PlayerModel result = restClient.get()
.uri(url)
.retrieve()
.body(PlayerModel.class);
Я буду признателен за любую помощь. Спасибо :)))


Подробнее здесь: https://stackoverflow.com/questions/776 ... l-response
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»