Гость
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Spring RestTemplate. Описание XML модели для ResponseEntity / 19 сообщений из 19, страница 1 из 1
09.10.2020, 12:47
    #40006897
IgorD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
Добрый день!
Помогите, пожалуйста, описать модель в 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
09.10.2020, 13:20
    #40006911
Lelouch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
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
09.10.2020, 14:30
    #40006953
IgorD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
К сожалению не получилось

В режиме дебага 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
09.10.2020, 14:47
    #40006965
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
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
09.10.2020, 15:13
    #40006979
IgorD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
похоже что модель корректная
Получил следующее

Код: 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
09.10.2020, 15:37
    #40006996
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
Не понимаю какая связь между http-headers и Entity которую ты не смог получить.
...
Рейтинг: 0 / 0
09.10.2020, 15:39
    #40006997
IgorD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
mayton
Не понимаю какая связь между http-headers и Entity которую ты не смог получить.


ищу зацепки в этом непонятном деле :)
...
Рейтинг: 0 / 0
09.10.2020, 15:42
    #40006998
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
Давай весь код показывай. А то получается что ты как в том анекдоте. Потерял ключи но ищешь не там
где потерял а там где стоит фонарь.
...
Рейтинг: 0 / 0
09.10.2020, 15:56
    #40007002
IgorD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
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
09.10.2020, 16:00
    #40007005
IgorD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
------- 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
09.10.2020, 17:45
    #40007045
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
Ну вот здесь самое интересное мясо и лежит. Стань дебаггером сюда и проверь что 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
09.10.2020, 18:01
    #40007054
IgorD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
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
09.10.2020, 18:11
    #40007058
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
Ну и что это? А где эта строка?

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



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

Код: 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
11.10.2020, 13:55
    #40007428
Lelouch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
IgorD,

1) Версия java?
2) Доступна ли имплементация jaxb?
...
Рейтинг: 0 / 0
11.10.2020, 14:04
    #40007429
Lelouch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
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
12.10.2020, 10:46
    #40007611
IgorD
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
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
12.10.2020, 14:00
    #40007718
Lelouch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Spring RestTemplate. Описание XML модели для ResponseEntity
IgorD,

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


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