Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > javax правильно построить иерархию элементов


Автор: EgoBrain 31.1.2017, 03:20
Добрый день!
Проблема такого характера: при подключении дочернего элемента SOAPElement к родительскому SOAPElement у дочернего создается свойство xmlns="", в моем случае данный эффект является не приемлемым. Как от этого избавится?

Код

...
SOAPFactory factory = SOAPFactory.newInstance();
SOAPElement securityElem = factory.createElement("Security", null, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement tokenElem = factory.createElement("UsernameToken");

...

securityElem.addChildElement(tokenElem); //Теперь у элемента tokenElem появилось свойство xmlns=""


Результат работы программы:
Код

<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <UsernameToken xmlns=""/>
</Security>


Требуемый результат:
Код

<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <UsernameToken/>
</Security>


Очень прошу помочь  smile 

Автор: TiKKi 31.1.2017, 08:30
Я так понимаю, вам нужна https://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/#. Попробуйте применить к элементу метод:
Код

import org.apache.xml.security.c14n.Canonicalizer;

Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS).canonicalizeSubtree(securityElem);

Автор: EgoBrain 31.1.2017, 08:40
Цитата(TiKKi @ 31.1.2017,  16:30)
Я так понимаю, вам нужна https://www.w3.org/TR/2002/REC-xml-exc-c14n-20020718/#. Попробуйте применить к элементу метод:
Код

import org.apache.xml.security.c14n.Canonicalizer;

Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS).canonicalizeSubtree(securityElem);

Спасибо за ответ!
Получаю ошибку
Цитата

Exception in handler: com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException: Unknown canonicalizer. No handler installed for URI http://www.w3.org/2001/10/xml-exc-c14n#

Автор: TiKKi 31.1.2017, 09:23
Скорей всего не проинициализировали библиотеку
Код

org.apache.xml.security.Init.init();

Автор: EgoBrain 31.1.2017, 09:34
Цитата(TiKKi @ 31.1.2017,  17:23)
Скорей всего не проинициализировали библиотеку
Код

org.apache.xml.security.Init.init();

Действительно нужно было сделать инициализация чтобы она не значила.
Но канониколизация к сожалению не возымела действия.
Причем пробовал производить её над разными элементами, и над всеми элементами, составляющими документ, над самим tokenElem и над его предками.

Добавлено через 1 минуту и 41 секунду
Может быть есть способ каким то образом "вручную" отредактировать сформированный SOAPElement или составленный из них SOAPHeader?

Автор: TiKKi 31.1.2017, 09:59
Вроде работает
Код

package test.rt.eu.nr;

import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.xml.security.c14n.Canonicalizer;
import org.junit.Test;

public class XmlCanonTest {

    @Test
    public void name() throws Exception {

        org.apache.xml.security.Init.init();

        SOAPFactory factory = SOAPFactory.newInstance();
        SOAPElement securityElem = factory.createElement("Security");
        securityElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
        SOAPElement tokenElem = factory.createElement("UsernameToken");
        tokenElem.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
        securityElem.addChildElement(tokenElem);

        byte[] canonicalizeSubtree = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS)
                .canonicalizeSubtree(securityElem, "", false);

        System.out.println(new String(canonicalizeSubtree, StandardCharsets.UTF_8));

        try {
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            StringWriter stringWriter = new StringWriter();
            transformer.transform(new DOMSource(securityElem), new StreamResult(stringWriter));
            System.out.println(stringWriter.toString());
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }
}


Цитата

Может быть есть способ каким то образом "вручную" отредактировать сформированный SOAPElement или составленный из них SOAPHeader?

Делали как-то такое, использовали XPathAPI из Apache Xalan.

Автор: EgoBrain 31.1.2017, 10:18
Цитата(TiKKi @ 31.1.2017,  17:59)
Вроде работает

Ок, получил каноникализированный элемент в виде строки
Цитата

StringWriter stringWriter

Цитата

byte[] canonicalizeSubtree

Как сделать так, чтобы мой элемент SOAPElement tokenElem тоже изменился в соответствии с проведенными манипуляциями?
Код

String uri = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
SOAPElement securityElem = factory.createElement("Security", prefix, uri);

SOAPElement tokenElem = factory.createElement("UsernameToken");
SOAPElement usrname = factory.createElement("Username");
usrname.setValue("123");
SOAPElement pwd = factory.createElement("Password");
QName attributeName = new QName("Type");
pwd.addAttribute(attributeName, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
pwd.setValue("123");

tokenElem.addChildElement(usrname);
tokenElem.addChildElement(pwd);
securityElem.addChildElement(tokenElem);

com.sun.org.apache.xml.internal.security.Init.init();
byte[] canonicalizeSubtree = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS)
                        .canonicalizeSubtree(securityElem); //Результат каноникализации был помещен в byte[], элемент tokenElem и securityElem остался без изменений

SOAPHeader header = envelope.addHeader();
header.addChildElement(messageID);
header.addChildElement(securityElem);

Автор: EgoBrain 1.2.2017, 02:02
Цитата(EgoBrain @ 31.1.2017,  17:34)
Может быть есть способ каким то образом "вручную" отредактировать сформированный SOAPElement или составленный из них SOAPHeader?

Интересный вопрос, но уже для отдельной темы имхо.

А моя задача была решена следующим образом
Цитата

If you want the element to be in the same namespace as its parent element, you must explicitly create it in that namespace by supplying the URI to the createElement() call. If you create a no-namespace element (as you have done), then the serializer inserts a namespace undeclaration xmlns="" to indicate that that the element is not in the same namespace as its parent.
http://stackoverflow.com/users/415448/michael-kay


Код

String uri = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
SOAPElement securityElem = factory.createElement("Security", prefix, uri);
SOAPElement tokenElem = factory.createElement("UsernameToken", prefix, uri);
SOAPElement usrname = factory.createElement("Username");
usrname.setValue("123");
SOAPElement pwd = factory.createElement("Password");
QName attributeName = new QName("Type");
pwd.addAttribute(attributeName, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
pwd.setValue("123");

tokenElem.addChildElement(usrname);
tokenElem.addChildElement(pwd);
securityElem.addChildElement(tokenElem);


Код

<Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <UsernameToken>
                <Username xmlns="">123</Username>
                <Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText" xmlns="">123</Password>
            </UsernameToken>
</Security>

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)