powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Spring RestTemplate. Описание XML модели для ResponseEntity
19 сообщений из 19, страница 1 из 1
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40006897
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!
Помогите, пожалуйста, описать модель в XML для ResponseEntity

Удаленный сервис возвращает такой ответ

Код: xml
1.
2.
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://test.org/">718aebfc</string>



К нему обращаюсь так

Код: java
1.
2.
3.
4.
5.
        ResponseEntity<SendSmsRespXML> response =
                restTemplate.exchange("http://xxx.xxx.xxx.xxx/SMSSend",
                        HttpMethod.POST,
                        entity,
                        SendSmsRespXML.class);



Класс SendSmsRespXML

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
@XmlRootElement(name="")
public class SendSmsRespXML {

    @XmlElement(name="string")
    String sendResult;

    public String getSendResult() {
        return sendResult;
    }

    public void setSendResult(String sendResult) {
        this.sendResult = sendResult;
    }

    @Override
    public String toString() {
        return "SendSmsRespXML{" +
                "sendResult='" + sendResult + '\'' +
                '}';
    }
}



Отрабатывает без ошибок, СМС приходит, но в response параметр sendResult=null, т.е. модель криво описана :(

Подскажите, где ошибка.
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40006911
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorD,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
@XmlRootElement(name="string", namespace = "http://test.org")
    public class SendSmsRespXML {

        @XmlValue
        private String result;

        public String getResult() {
            return result;
        }

        public void setResult(String result) {
            this.result = result;
        }

        @Override
        public String toString() {
            return "SendSmsRespXML{" +
                    "result='" + result + '\'' +
                    '}';
        }
    }



вот так попробуйте
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40006953
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К сожалению не получилось

В режиме дебага response имеет следующий вид

Код: java
1.
<200 OK,SendSmsRespXML{result='null'},{Cache-Control=[private, max-age=0], Content-Type=[text/xml; charset=utf-8], Server=[Microsoft-IIS/8.5], X-AspNet-Version=[4.0.30319], X-Powered-By=[ASP.NET], Date=[Fri, 09 Oct 2020 11:11:33 GMT], Content-Length=[121]}>
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40006965
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorD, тебе чтоб исправить эту ошибку никакие внешние сервисы вызывать не надо.

Сделай модульный тест где на вход приходит строка

Код: java
1.
<?xml version="1.0" encoding="utf-8"?><string xmlns="http://test.org/">718aebfc</string>



и на выходе ты должен получить объект SendSmsRespXML со всеми полями в составе.

По аналогии с https://stackoverflow.com/questions/23601681/how-to-use-xmlelement-and-xmlrootelement-for-marshalling-object-inside-an-obje
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40006979
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
похоже что модель корректная
Получил следующее

Код: xml
1.
2.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<string xmlns="http://test.org/">TestModel</string>




Может в headers нужно что-от добавить, описывающее, что на выходе XML?
У меня так
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
RestTemplate restTemplate = new RestTemplate();


        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("PRIVATE-TOKEN", "xyz");

        MultiValueMap<String, String> map =
                new LinkedMultiValueMap<String, String>();
        map.add("SmsNum",request.getPhone());
        map.add("smsText",request.getMessage());
       

        HttpEntity<MultiValueMap<String, String>> entity =
                new HttpEntity<MultiValueMap<String, String>>(map, headers);



        ResponseEntity<SendSmsRespXML> response =
                restTemplate.exchange("http://xxx.xxx.xxx.xxx/SMSSend",
                        HttpMethod.POST,
                        entity,
                        SendSmsRespXML.class);
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40006996
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не понимаю какая связь между http-headers и Entity которую ты не смог получить.
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40006997
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Не понимаю какая связь между http-headers и Entity которую ты не смог получить.


ищу зацепки в этом непонятном деле :)
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40006998
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давай весь код показывай. А то получается что ты как в том анекдоте. Потерял ключи но ищешь не там
где потерял а там где стоит фонарь.
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007002
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Controllers

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    @RequestMapping(value = "/sendsms", method = RequestMethod.POST, produces = "application/json;charset=utf-8")
    public ResponseEntity<?> sendSms(
            @RequestBody
            @Valid SendSmsReq request,
            //@RequestHeader(value = "Authorization",required = false) String token,
            HttpServletRequest httpRequest){

        SendSmsResp response = new SendSmsResp();

        try {
            response = commonAPI.sendSms(request);
        } catch (ApiException ae) {
            return new ResponseEntity<>(ae.getApiErrorsView(), HttpStatus.PRECONDITION_FAILED);
        } catch (Exception e) {
            e.printStackTrace();
            ApiErrorsView apiErrorsView = new ApiErrorsView(e);
            return new ResponseEntity<>(apiErrorsView, HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity<>(response, HttpStatus.OK);


    }



-- ------- SendSmsResp

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
package com.rest.Data.Models.Common;

import org.springframework.stereotype.Component;


@Component
public class SendSmsResp {
    String SmsId;

    public String getSmsId() {
        return SmsId;
    }

    public void setSmsId(String smsId) {
        SmsId = smsId;
    }
}



----------- commonAPI.sendSms

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
    
    public SendSmsResp sendSms(SendSmsReq request) throws Exception {

         RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("PRIVATE-TOKEN", "xyz");

        MultiValueMap<String, String> map =
                new LinkedMultiValueMap<String, String>();
        map.add("SmsNum",request.getPhone());
        map.add("smsText",request.getMessage());
        
        HttpEntity<MultiValueMap<String, String>> entity =
                new HttpEntity<MultiValueMap<String, String>>(map, headers);

        ResponseEntity<SendSmsRespXML> response =
                restTemplate.exchange("http://xxx.xxx.xxx.xxx/SMSSend",
                        HttpMethod.POST,
                        entity,
                        SendSmsRespXML.class);

        SendSmsResp response0 = sendSmsResp;
        response0.setSmsId(response.toString());
        return response0;
    }
}
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007005
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
------- SendSmsRespXML

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
package com.rest.Data.Models.Common;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlValue;


@XmlRootElement(name="string", namespace = "http://test.org/")
@XmlAccessorType(XmlAccessType.FIELD)
public class SendSmsRespXML {

    @XmlValue
    private String result;

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    @Override
    public String toString() {
        return "SendSmsRespXML{" +
                "result='" + result + '\'' +
                '}';
    }
}
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007045
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот здесь самое интересное мясо и лежит. Стань дебаггером сюда и проверь что input entity действительно содержит тело
ответ от веба в текстовом виде. И после выхода из этого блока объект response наполнен.

Код: java
1.
2.
3.
4.
5.
        ResponseEntity<SendSmsRespXML> response =
                restTemplate.exchange("http://xxx.xxx.xxx.xxx/SMSSend",
                        HttpMethod.POST,
                        entity,
                        SendSmsRespXML.class);
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007054
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
entity
Код: java
1.
<{SmsNum=[3333333333], smsText=[test message]},{Content-Type=[application/x-www-form-urlencoded], PRIVATE-TOKEN=[xyz]}>



response

Код: java
1.
<200 OK,SendSmsRespXML{result='null'},{Cache-Control=[private, max-age=0], Content-Type=[text/xml; charset=utf-8], Server=[Microsoft-IIS/8.5], X-AspNet-Version=[4.0.30319], X-Powered-By=[ASP.NET], Date=[Fri, 09 Oct 2020 14:59:31 GMT], Content-Length=[121]}>
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007058
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну и что это? А где эта строка?

Код: java
1.
<string xmlns="http://test.org/">718aebfc</string>



Ты можешь просто ее показать как пруф того что она реально приходит? Дебаггером. Логгером. Или как угодно.
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007119
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
стесняюсь сказать, не знаю как .... сижу, разбираюсь
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007155
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сделал так

Код: java
1.
2.
3.
4.
5.
ResponseEntity<String> response =
                restTemplate.exchange("http://xxx.xxx.xxx.xxx/SMSSend",
                        HttpMethod.POST,
                        entity,
                        String.class);



response.getBody() принимает такое значение

Код: java
1.
2.
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://test.org/">7229babb</string>



сервер точно возвращает, то что нужно
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007428
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorD,

1) Версия java?
2) Доступна ли имплементация jaxb?
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007429
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorD
сделал так

Код: java
1.
2.
3.
4.
5.
ResponseEntity<String> response =
                restTemplate.exchange("http://xxx.xxx.xxx.xxx/SMSSend",
                        HttpMethod.POST,
                        entity,
                        String.class);



response.getBody() принимает такое значение

Код: java
1.
2.
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://test.org/">7229babb</string>



сервер точно возвращает, то что нужно


JAXB парсер точно читает то, что возвращает сервер:
https://monosnap.com/file/qRODy0n0QSdgxuDXjOwYXuNnDwNOYd

У вас случайно jackson-dataformat-xml нет в classpath?

Судя по коду RestTemplate "предпочитает" Jackson xml:
Код: java
1.
2.
3.
4.
5.
6.
if (jackson2XmlPresent) {
			this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
		}
		else if (jaxb2Present) {
			this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
		}
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007611
IgorD
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lelouch,
Сейчас остановился на таком варианте, время поджимало. Но решение вопроса осталось интересным... Подозреваю, что RestTemplate "не знает" что у него на выходе от сервера заходит XML... Возможно нужно это как-то объявить?
Версия Java - 1.8

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
    /*----------------------------------------sendSms-----------------------------------------------------------*/
    public SendSmsResp sendSms(SendSmsReq request) throws Exception {

        RestTemplate restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("PRIVATE-TOKEN", "xyz");

        MultiValueMap<String, String> map =
                new LinkedMultiValueMap<String, String>();
        map.add("SmsNum",request.getPhone());
        map.add("smsText",request.getMessage());

        HttpEntity<MultiValueMap<String, String>> entity =
                new HttpEntity<MultiValueMap<String, String>>(map, headers);

        ResponseEntity<String> responseXML =
                restTemplate.exchange("http://xxx.xxx.xxxx.xxxx/SMSSend",
                        HttpMethod.POST,
                        entity,
                        String.class);

        //final SendSmsRespXML insertedPost = restTemplate.postForObject("http://xxx.xxx.xxxx.xxxx/SMSSend", entity, SendSmsRespXML.class);

        String stringXML =responseXML.getBody();

        SendSmsResp response = sendSmsResp;

        HttpStatus statusCode = responseXML.getStatusCode();

        if (statusCode == HttpStatus.OK) {
            JAXBContext jaxbContext = JAXBContext.newInstance(SendSmsRespXML.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            StringReader reader = new StringReader(stringXML);
            SendSmsRespXML resp= (SendSmsRespXML) jaxbUnmarshaller.unmarshal(reader);
            response.setSmsId(resp.getString());
        }else{
            throw new Exception(responseXML.toString());
        }

        return response;
    }
}
...
Рейтинг: 0 / 0
Spring RestTemplate. Описание XML модели для ResponseEntity
    #40007718
Lelouch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorD,

авторПодозреваю, что RestTemplate "не знает" что у него на выходе от сервера заходит XML...
Это он как раз знает.
RestTemplate делегирует разбор результата набору HttpMessageConverter'ов. Каждый конвертер проверяет, может ли он десерилизовать результат (метод canRead). Например AbstractXmlHttpMessageConverter проверяет содержимое Content-Type - должно быть application/xml или text/xml). У вас в "логах" видно что приходит text/xml.
Я склоняюсь к тому, что у вас в classpath есть jackson-dataformat-xml, из-за чего используется не Jaxb2RootElementHttpMessageConverter, а MappingJackson2XmlHttpMessageConverter, который в свою очередь требует других аннотаций для корректной десерилизации
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Spring RestTemplate. Описание XML модели для ResponseEntity
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]