Spring Boot 3 - невозможно маршалировать/демаршалировать приложение/XML в основном в HTTP-запросах ⇐ JAVA
Spring Boot 3 - невозможно маршалировать/демаршалировать приложение/XML в основном в HTTP-запросах
Я переношу проект с Spring Boot 2.7.0 на версию 3.0.5, и в старой версии все работало, теперь мои интеграционные тесты не проходят. Используя Webclient, я не могу разобрать тело ответа на свой dto. Также, используя MockMvc, я не могу демаршаллировать данные из имитируемой конечной точки, которая: создает = MediaType.APPLICATION_XML_VALUE.
В первом случае мой вызов выглядит так:
WebClient webClient = WebClient.builder().baseUrl(transactionRegistrationUrl.toString()) .exchangeStrategies( ExchangeStrategies.builder() .codecs(конфигуратор -> { configurer.defaultCodecs().jaxb2Decoder(новый Jaxb2XmlDecoder()); configurer.defaultCodecs().jaxb2Encoder(новый Jaxb2XmlEncoder()); } ) .строить() ) .строить(); вернуть webClient.post() .contentType(MediaType.APPLICATION_FORM_URLENCODED) .accept(MediaType.APPLICATION_XML) .bodyValue(requestData) .exchangeToMono(ответ -> { defaultRestErrorHandler.handle (ответ); // проверяем, нет ли ошибок 4xx, 5xx и т. д. вернуть ответ.bodyToMono(PaymentRegistrationResponseDTO.class); }) .блокировать(); Поэтому здесь следует разархивировать содержимое XML в PaymentRegistrationResponseDTO. Для конечной точки я использую okhttp3.mockwebserver.MockWebServer
mockServer.enqueue(новый MockResponse() .setBody(xml-файл ниже) .addHeader("Тип контента", MediaType.APPLICATION_XML_VALUE)); Поэтому при вызове он вернет ответ application/xml и строку XML, которую необходимо преобразовать:
Из этого: В ОЖИДАНИИ https://некоторый URL 3343 42342 e55881d10ec9c93cbf63246f1d41e54001facc8eb0a06b10d На это:
@XmlRootElement( имя = "транзакция" ) @XmlAccessorType(XmlAccessType.ПОЛЕ) публичный класс PaymentRegistrationResponseDTO расширяет HashSelfValidating реализует Serializable { @XmlTransient Private static Final String UNSUCCESSFUL_PAYMENT_REGISTRATION_MESSAGE = "Неудачная регистрация платежа. Статус подтверждения: %s, причина: %s"; @XmlElement( имя = "идентификатор заказа" ) частная строка orderId; @XmlElement( имя = "ИД_удаленного" ) частная строка RemoteId; частный строковый хеш; частный статус PaymentRegistrationStatus; @XmlElement( имя = "перенаправление" ) частная строка redirectUrl; личное подтверждение подтверждения платежа; частная строковая причина; частный PaymentRegistrationStatus PaymentStatus; + конструкторы и пустой конструктор Я добавил кодеки, но это не помогает.
Исключение, которое я получаю:
org.springframework.web.reactive.function.UnsupportedMediaTypeException: тип контента «application/xml» не поддерживается для bodyType=pl.com.best.bmadapter.registration.response.PaymentRegistrationResponseDTO в org.springframework.web.reactive.function.BodyExtractors.lambda$readWithMessageReaders$12(BodyExtractors.java:206) Подавлено: трассировка стека была улучшена Reactor, дополнительную информацию см. ниже: Ошибка наблюдалась на следующих сайтах: *__checkpoint ⇢ Тело сообщения POST http://localhost:60677 [DefaultClientResponse] (..) Подавлено: java.lang.Exception: #block завершен с ошибкой в реакторе.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99) Во втором случае я делаю:
MvcResult result = mvc.perform(post("/transaction/bm/status") .contentType(MediaType.APPLICATION_FORM_URLENCODED) .accept(MediaType.APPLICATION_XML) .params(Карта с параметрами) ).и вернуться(); Это почтовый вызов конечной точки, который создает = MediaType.APPLICATION_XML_VALUE. Он создает хороший dto, но не может преобразовать его в XML.
Здесь я получил: org.springframework.http.converter.HttpMessageNotWritableException: нет конвертера для с предустановленным типом контента «null» Итак, я добавил эту зависимость:
com.fasterxml.jackson.dataformat jackson-dataformat-xml 2.14.2 И теперь это работает, однако полностью пропускает такие аннотации, как @XmlRootElement, @XmlElement и т. д. Так что ответ по-прежнему плохой.
Я попробовал множество комбинаций зависимостей, чтобы это заработало, и теперь у меня есть вот эти:
com.sun.xml.bind jaxb-impl 2.3.1 jakarta.xml.bind jakarta.xml.bind-api 4.0.1 jakarta.xml.ws jakarta.xml.ws-api 4.0.0 com.fasterxml.jackson.dataformat jackson-dataformat-xml 2.14.2 jakarta.ws.rs jakarta.ws.rs-api и т. д. А это странно:
com.sun.xml.bind jaxb-impl 2.3.1 Это старая зависимость, которая мне не нужна. Но когда я удалю его или обновлю до версии >= 3.0.0 Я тоже получу ошибку:
jakarta.xml.bind.UnmarshalException: неожиданный элемент (uri:"", local:"transactionList"). Ожидаемые элементы (нет) Даже если у меня в pom есть jakarta.bind.xml, он все равно использует старые зависимости для демаршалинга?
Другие вещи, которые я пытался разобрать вручную таким образом:
JAXBContext jaxbContext = JAXBContext.newInstance(ITNRequestDTO.class); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); return (ITNRequestDTO) unmarshaller.unmarshal (новый StringReader (decodedXml)); Но это работает только со старыми зависимостями javax.xml.bind. Когда я использую Jakarta.xml.bind я получаю то же исключение:
jakarta.xml.bind.UnmarshalException: неожиданный элемент (uri:"", local:"transactionList"). Ожидаемые элементы (нет) Во всяком случае, я пытался добавить новые зависимости и удалить старые. Проверил весь Интернет в поисках ответа, но то, что я пробовал, не сработало. Как будто у меня сразу все проблемы с маршаллингом.
Я переношу проект с Spring Boot 2.7.0 на версию 3.0.5, и в старой версии все работало, теперь мои интеграционные тесты не проходят. Используя Webclient, я не могу разобрать тело ответа на свой dto. Также, используя MockMvc, я не могу демаршаллировать данные из имитируемой конечной точки, которая: создает = MediaType.APPLICATION_XML_VALUE.
В первом случае мой вызов выглядит так:
WebClient webClient = WebClient.builder().baseUrl(transactionRegistrationUrl.toString()) .exchangeStrategies( ExchangeStrategies.builder() .codecs(конфигуратор -> { configurer.defaultCodecs().jaxb2Decoder(новый Jaxb2XmlDecoder()); configurer.defaultCodecs().jaxb2Encoder(новый Jaxb2XmlEncoder()); } ) .строить() ) .строить(); вернуть webClient.post() .contentType(MediaType.APPLICATION_FORM_URLENCODED) .accept(MediaType.APPLICATION_XML) .bodyValue(requestData) .exchangeToMono(ответ -> { defaultRestErrorHandler.handle (ответ); // проверяем, нет ли ошибок 4xx, 5xx и т. д. вернуть ответ.bodyToMono(PaymentRegistrationResponseDTO.class); }) .блокировать(); Поэтому здесь следует разархивировать содержимое XML в PaymentRegistrationResponseDTO. Для конечной точки я использую okhttp3.mockwebserver.MockWebServer
mockServer.enqueue(новый MockResponse() .setBody(xml-файл ниже) .addHeader("Тип контента", MediaType.APPLICATION_XML_VALUE)); Поэтому при вызове он вернет ответ application/xml и строку XML, которую необходимо преобразовать:
Из этого: В ОЖИДАНИИ https://некоторый URL 3343 42342 e55881d10ec9c93cbf63246f1d41e54001facc8eb0a06b10d На это:
@XmlRootElement( имя = "транзакция" ) @XmlAccessorType(XmlAccessType.ПОЛЕ) публичный класс PaymentRegistrationResponseDTO расширяет HashSelfValidating реализует Serializable { @XmlTransient Private static Final String UNSUCCESSFUL_PAYMENT_REGISTRATION_MESSAGE = "Неудачная регистрация платежа. Статус подтверждения: %s, причина: %s"; @XmlElement( имя = "идентификатор заказа" ) частная строка orderId; @XmlElement( имя = "ИД_удаленного" ) частная строка RemoteId; частный строковый хеш; частный статус PaymentRegistrationStatus; @XmlElement( имя = "перенаправление" ) частная строка redirectUrl; личное подтверждение подтверждения платежа; частная строковая причина; частный PaymentRegistrationStatus PaymentStatus; + конструкторы и пустой конструктор Я добавил кодеки, но это не помогает.
Исключение, которое я получаю:
org.springframework.web.reactive.function.UnsupportedMediaTypeException: тип контента «application/xml» не поддерживается для bodyType=pl.com.best.bmadapter.registration.response.PaymentRegistrationResponseDTO в org.springframework.web.reactive.function.BodyExtractors.lambda$readWithMessageReaders$12(BodyExtractors.java:206) Подавлено: трассировка стека была улучшена Reactor, дополнительную информацию см. ниже: Ошибка наблюдалась на следующих сайтах: *__checkpoint ⇢ Тело сообщения POST http://localhost:60677 [DefaultClientResponse] (..) Подавлено: java.lang.Exception: #block завершен с ошибкой в реакторе.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99) Во втором случае я делаю:
MvcResult result = mvc.perform(post("/transaction/bm/status") .contentType(MediaType.APPLICATION_FORM_URLENCODED) .accept(MediaType.APPLICATION_XML) .params(Карта с параметрами) ).и вернуться(); Это почтовый вызов конечной точки, который создает = MediaType.APPLICATION_XML_VALUE. Он создает хороший dto, но не может преобразовать его в XML.
Здесь я получил: org.springframework.http.converter.HttpMessageNotWritableException: нет конвертера для с предустановленным типом контента «null» Итак, я добавил эту зависимость:
com.fasterxml.jackson.dataformat jackson-dataformat-xml 2.14.2 И теперь это работает, однако полностью пропускает такие аннотации, как @XmlRootElement, @XmlElement и т. д. Так что ответ по-прежнему плохой.
Я попробовал множество комбинаций зависимостей, чтобы это заработало, и теперь у меня есть вот эти:
com.sun.xml.bind jaxb-impl 2.3.1 jakarta.xml.bind jakarta.xml.bind-api 4.0.1 jakarta.xml.ws jakarta.xml.ws-api 4.0.0 com.fasterxml.jackson.dataformat jackson-dataformat-xml 2.14.2 jakarta.ws.rs jakarta.ws.rs-api и т. д. А это странно:
com.sun.xml.bind jaxb-impl 2.3.1 Это старая зависимость, которая мне не нужна. Но когда я удалю его или обновлю до версии >= 3.0.0 Я тоже получу ошибку:
jakarta.xml.bind.UnmarshalException: неожиданный элемент (uri:"", local:"transactionList"). Ожидаемые элементы (нет) Даже если у меня в pom есть jakarta.bind.xml, он все равно использует старые зависимости для демаршалинга?
Другие вещи, которые я пытался разобрать вручную таким образом:
JAXBContext jaxbContext = JAXBContext.newInstance(ITNRequestDTO.class); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); return (ITNRequestDTO) unmarshaller.unmarshal (новый StringReader (decodedXml)); Но это работает только со старыми зависимостями javax.xml.bind. Когда я использую Jakarta.xml.bind я получаю то же исключение:
jakarta.xml.bind.UnmarshalException: неожиданный элемент (uri:"", local:"transactionList"). Ожидаемые элементы (нет) Во всяком случае, я пытался добавить новые зависимости и удалить старые. Проверил весь Интернет в поисках ответа, но то, что я пробовал, не сработало. Как будто у меня сразу все проблемы с маршаллингом.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
JAXB: невозможно демаршалировать JAXBElement>, вместо этого получить ElementNSImpl
Anonymous » » в форуме JAVA - 0 Ответы
- 13 Просмотры
-
Последнее сообщение Anonymous
-
-
-
JAXB: невозможно демаршалировать JAXBElement>, вместо этого получить ElementNSImpl
Anonymous » » в форуме JAVA - 0 Ответы
- 66 Просмотры
-
Последнее сообщение Anonymous
-