Как развязать ответ SOAP с помощью JAXB, если декларация пространства имен находится в конверте SOAP? - программирование
Подтвердить что ты не робот

Как развязать ответ SOAP с помощью JAXB, если декларация пространства имен находится в конверте SOAP?

JAXB может только отменить маркер XML, если мыльный конверт уже удален. Тем не менее, ответ SOAP, который я пытаюсь развернуть, имеет декларацию пространства имен в конверте мыла. Если я удаляю мыльный конверт, декларация пространства имен также будет удалена. Таким образом, префикс тегов будет ссылаться на none. Это приводит к ошибке JAXB. Как я могу отменить маркер ответа SOAP с помощью JAXB, если пространство имен объявлено в конверте SOAP?

Аналогичный образец XML, который мне нужен для отмены маршрутизации, приведен ниже:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://example.com/">
    <soapenv:Body>
        <ns:getNumberResponse>
            <number>123456789</number>
        </ns:getNumberResponse>
    </soapenv:Body>
</soapenv:Envelope>

Это то, что произойдет, если я удалю мыльный конверт:

<ns:getNumberResponse>
    <number>123456789</number>
</ns:getNumberResponse>

Если я удалил мыльный конверт, объявление пространства имен также исчезнет. JAXB не сможет размонтировать вышеуказанный xml, потому что отсутствует определение пространства имен для префикса "ns". Таким образом, он вернет сообщение об ошибке "The prefix "ns" for element "ns:getNumberResponse" is not bound.". Как это исправить?

Обратите внимание, что я использую JDK 1.5. Я не уверен, есть ли способ решить эту проблему в JDK 1.6. Я смог использовать JAXB, потому что я загрузил необходимые банки для использования JAXB.

4b9b3361

Ответ 1

Вы можете использовать синтаксический анализатор StAX для синтаксического анализа сообщения SOAP, а затем продвинуть элемент XMLStreamReader к элементу getNumberResponse и использовать метод unmarshal, который принимает параметр класса. Парсер StAX включен в Java SE 6, но вам нужно загрузить его для Java SE 5. Woodstox - популярный парсер STAX.

ответ

package forum11465653;

public class Response {

    private long number;

    public long getNumber() {
        return number;
    }

    public void setNumber(long number) {
        this.number = number;
    }

}

Demo

An XMLStreamReader имеет NamespaceContext. NamespaceContext знает все активные объявления пространства имен для текущего уровня. Ваша реализация JAXB (JSR-222) сможет использовать эту информацию для получения необходимой информации.

package forum11465653;

import java.io.FileReader;
import javax.xml.bind.*;
import javax.xml.stream.*;

public class Demo {

    public static void main(String[] args) throws Exception{
        XMLInputFactory xif = XMLInputFactory.newFactory();
        XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("src/forum11465653/input.xml"));
        xsr.nextTag(); // Advance to Envelope tag
        xsr.nextTag(); // Advance to Body tag
        xsr.nextTag(); // Advance to getNumberResponse tag
        System.out.println(xsr.getNamespaceContext().getNamespaceURI("ns"));

        JAXBContext jc = JAXBContext.newInstance(Response.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        JAXBElement<Response> je = unmarshaller.unmarshal(xsr, Response.class);
        System.out.println(je.getName());
        System.out.println(je.getValue());
    }

}

Выход

http://example.com/
{http://example.com/}getNumberResponse
[email protected]

Ответ 2

Вы можете разобрать все SOAP-сообщение, используя парсер DOM, который сможет разрешать все пространства имен во время разбора. Затем извлеките требуемый элемент из полученного дерева DOM и передайте его в unmarshaller.

DomDemo

package forum11465653;

import java.io.File;
import javax.xml.bind.*;
import javax.xml.parsers.*;
import javax.xml.transform.dom.DOMSource;
import org.w3c.dom.*;

public class DomDemo {

    public static void main(String[] args) throws Exception{
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document d = db.parse(new File("src/forum11465653/input.xml"));
        Node getNumberResponseElt = d.getElementsByTagNameNS("http://example.com/", "getNumberResponse").item(0);

        JAXBContext jc = JAXBContext.newInstance(Response.class);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        JAXBElement<Response> je = unmarshaller.unmarshal(new DOMSource(getNumberResponseElt), Response.class);
        System.out.println(je.getName());
        System.out.println(je.getValue());
    }

}

Выход

{http://example.com/}getNumberResponse
[email protected]