Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / jaxb как добавить namespace не корневому элементу / 7 сообщений из 7, страница 1 из 1
22.12.2015, 08:34
    #39134096
Nicollo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
jaxb как добавить namespace не корневому элементу
Имеется задача по вызову веб сервиса. Мое приложение генерит следующий запрос:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/><soap:Body>
<typ:SendMessage xmlns:ns4="http://test.user.kz/UserInfo" xmlns:q1="http://test.user.kz/CustomerInfo" xmlns:typ="http://test.user.kz/MyChannel/v1/Types">
    <request>
        <requestInfo>
            <messageId>26e96b11-8f82-421e-829a</messageId>
        </requestInfo>
        <requestData>
            <data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="q1:PaymentPackageRequestType">
                <q1:methodName>testMethod</q1:methodName>
            </data>
        </requestData>
    </request>
</typ:SendMessage></soap:Body></soap:Envelope>


Как в тэге data указать xmlns:q1=" http://test.user.kz/CustomerInfo? данный namespace необходимо продублировать в теге data или перенести из typ:SendMessage. И сделать это средствами JAXB API.
...
Рейтинг: 0 / 0
22.12.2015, 08:45
    #39134106
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
jaxb как добавить namespace не корневому элементу
Nicollo,

Кривой сервер это всегда попоболь. Если, есть возможность, надо настучать разработчику сервера по голове, потому что ваш XML остаётся валидным не зависимо от того где находится объявление namespace-а.

Как, вариант, можно data замапить на JAXBElement, а не класс. Тогда через DOM можно попробовать добавить аттрибут вручную.
...
Рейтинг: 0 / 0
23.12.2015, 08:52
    #39135367
Nicollo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
jaxb как добавить namespace не корневому элементу
Как понял JAXB всегда в корневом элемента определяет простраство имен. Пришлось вручную добавить:
Код: 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.
Document document = null;
        try {
            document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
            Marshaller marshaller = JAXBContext.newInstance(SendMessage.class).createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            marshaller.setProperty("com.sun.xml.bind.characterEscapeHandler", new CharacterEscapeHandler() {
                @Override
                public void escape(char[] buf, int start, int len, boolean b, Writer out) throws IOException {
                    out.write(buf, start, len);
                }
            });
            QName name = new QName(NAMESPACE_URI, SendMessage.class.getSimpleName());
            JAXBElement<SendMessage> root = new JAXBElement<SendMessage>(name, SendMessage.class, from);
            StringWriter writer1 = new StringWriter();
            marshaller.marshal(root, writer1);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            Element node = dbf
                    .newDocumentBuilder()
                    .parse(new ByteArrayInputStream(writer1.toString().getBytes(StandardCharsets.ISO_8859_1)))
                    .getDocumentElement();
            Attr attr1 = document.createAttribute("xmlns:q1");
            attr1.setValue("http://test.user.kz/CustomerInfo");
            node.getElementsByTagName("data").item(0).getAttributes().setNamedItem(node.getOwnerDocument().importNode(attr1, true));
            return node;
        } catch (Exception e) {
            throw new Exception("Unable to transform POJO to XML SOAP message ", e);

        }
...
Рейтинг: 0 / 0
23.12.2015, 09:55
    #39135429
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
jaxb как добавить namespace не корневому элементу
Nicollo,

JAXB вообще много всякой хери делает. Например любит маршалить null значения в <tagname xsi:nil="true"/>, вместо того чтобы вообще никакой тэг не создавать. Мне пришлось через рефлексию его хачить, чтобы это исправить. Думаю надо чаще на XStream смотреть, если сервер не на Java.
...
Рейтинг: 0 / 0
23.12.2015, 12:14
    #39135711
no56892
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
jaxb как добавить namespace не корневому элементу
NicolloКак понял JAXB всегда в корневом элемента определяет простраство имен. Пришлось вручную добавить:
Код: 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.
Document document = null;
        try {
            document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
            Marshaller marshaller = JAXBContext.newInstance(SendMessage.class).createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            marshaller.setProperty("com.sun.xml.bind.characterEscapeHandler", new CharacterEscapeHandler() {
                @Override
                public void escape(char[] buf, int start, int len, boolean b, Writer out) throws IOException {
                    out.write(buf, start, len);
                }
            });
            QName name = new QName(NAMESPACE_URI, SendMessage.class.getSimpleName());
            JAXBElement<SendMessage> root = new JAXBElement<SendMessage>(name, SendMessage.class, from);
            StringWriter writer1 = new StringWriter();
            marshaller.marshal(root, writer1);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            Element node = dbf
                    .newDocumentBuilder()
                    .parse(new ByteArrayInputStream(writer1.toString().getBytes(StandardCharsets.ISO_8859_1)))
                    .getDocumentElement();
            Attr attr1 = document.createAttribute("xmlns:q1");
            attr1.setValue("http://test.user.kz/CustomerInfo");
            node.getElementsByTagName("data").item(0).getAttributes().setNamedItem(node.getOwnerDocument().importNode(attr1, true));
            return node;
        } catch (Exception e) {
            throw new Exception("Unable to transform POJO to XML SOAP message ", e);

        }


XSLT как раз для такого
...
Рейтинг: 0 / 0
23.12.2015, 12:41
    #39135794
Nicollo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
jaxb как добавить namespace не корневому элементу
BlazkowiczNicollo,

JAXB вообще много всякой хери делает. Например любит маршалить null значения в <tagname xsi:nil="true"/>, вместо того чтобы вообще никакой тэг не создавать. Мне пришлось через рефлексию его хачить, чтобы это исправить. Думаю надо чаще на XStream смотреть, если сервер не на Java.
У Вас NULL поле видимо было аннотировано @XmlElement(nillable = true). Если выставить false то элемент не создастся.
...
Рейтинг: 0 / 0
23.12.2015, 12:48
    #39135812
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
jaxb как добавить namespace не корневому элементу
NicolloУ Вас NULL поле видимо было аннотировано @XmlElement(nillable = true). Если выставить false то элемент не создастся.

Ага, вот только код у меня генерируется по публичной WSDL в невообразимо огромном количестве. Делать пост-обработку этого кода дело геморное. Приходится этот атрибут из маппинга подчищать в рантайме.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / jaxb как добавить namespace не корневому элементу / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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