Cannot remove namespace of SOAP response using SAXFilter

偶尔善良 提交于 2019-12-07 19:31:52

问题


I am trying to parse the following SOAP response, as it is not a valid response I am trying to remove its namespace using the following filter but it runs into an error.

Response

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
        <SearchFlightsResponse xmlns="ElsyArres.API">
            <SoapMessage>
                <Username>TEST</Username>
                <Password>TESTs</Password>
                <LanguageCode>EN</LanguageCode>
                <ErrorMessage />
                <ErrorCode>0</ErrorCode>
                <AppVersion>8.0.3</AppVersion>
                <Request>
                    <Departure>FDH</Departure>
                    <Destination>HAM</Destination>
                    <DepartureDate>2014-08-08</DepartureDate>
                    <ReturnDate />
                    <NumADT>1</NumADT>
                    <NumINF>0</NumINF>
                    <NumCHD>0</NumCHD>
                    <CurrencyCode>EUR</CurrencyCode>
                    <CarrierList />
                    <FareClasses />
                    <Providers />
                    <WaitForResult>true</WaitForResult>
                    <NearbyDepartures>true</NearbyDepartures>
                    <NearbyDestinations>true</NearbyDestinations>
                    <RROnly>false</RROnly>
                    <MetaSearch>true</MetaSearch>
                </Request>
                <Response>
                    <SearchFlightId>140514114543-02-43064-52</SearchFlightId>
                    <Roundtrip>false</Roundtrip>
                    <CurrencyCode>EUR</CurrencyCode>
                    <Flights>
                        <Flight>
                            <Outbound>
                                <CarName>Inter Sky</CarName>
                                <CarCode>3L</CarCode>
                                <DepName>Friedrichshafen</DepName>
                                <DepCode>FDH</DepCode>
                                <DestName>Hamburg</DestName>
                                <DestCode>HAM</DestCode>
                                <Duration>01:45</Duration>
                                <FlightNo>3L370</FlightNo>
                                <DepDateTime>2014-08-08T06:10:00</DepDateTime>
                                <ArrDateTime>2014-08-08T07:55:00</ArrDateTime>
                                <Legs>
                                    <Leg>
                                        <Sequence>0</Sequence>
                                        <FlightNo>3L370</FlightNo>
                                        <DepCode>FDH</DepCode>
                                        <DepName>Friedrichshafen</DepName>
                                        <DestCode>HAM</DestCode>
                                        <DestName>Hamburg</DestName>
                                        <DepTime>06:10</DepTime>
                                        <ArrTime>07:55</ArrTime>
                                        <CarCode>3L</CarCode>
                                        <CarName>Inter Sky</CarName>
                                        <FareClass>Economy</FareClass>
                                        <ArrDateTime>2014-08-08T07:55:00</ArrDateTime>
                                        <DepDateTime>2014-08-08T06:10:00</DepDateTime>
                                    </Leg>
                                </Legs>
                                <Taxes>0</Taxes>
                                <FareADT>6500</FareADT>
                                <FareCHD>0</FareCHD>
                                <FareINF>0</FareINF>
                                <MiscFees>6400</MiscFees>
                                <Idx>307963</Idx>
                                <FareClass>Economy</FareClass>
                                <FareType>Web</FareType>
                                <FareId>3L0</FareId>
                            </Outbound>
                            <BagFee>0</BagFee>
                            <CcFee>600</CcFee>
                            <HandlingFee>500</HandlingFee>
                            <TotalFare>12900</TotalFare>
                            <FlightId>140514114543-02-21212-2</FlightId>
                            <Link2Book>http://sample.com</Link2Book>
                            <Provider>ElsyArres</Provider>
                        </Flight>
                        <Flight>
                            <Outbound>
                                <CarName>Inter Sky</CarName>
                                <CarCode>3L</CarCode>
                                <DepName>Friedrichshafen</DepName>
                                <DepCode>FDH</DepCode>
                                <DestName>Hamburg</DestName>
                                <DestCode>HAM</DestCode>
                                <Duration>01:45</Duration>
                                <FlightNo>3L376</FlightNo>
                                <DepDateTime>2014-08-08T18:00:00</DepDateTime>
                                <ArrDateTime>2014-08-08T19:45:00</ArrDateTime>
                                <Legs>
                                    <Leg>
                                        <Sequence>0</Sequence>
                                        <FlightNo>3L376</FlightNo>
                                        <DepCode>FDH</DepCode>
                                        <DepName>Friedrichshafen</DepName>
                                        <DestCode>HAM</DestCode>
                                        <DestName>Hamburg</DestName>
                                        <DepTime>18:00</DepTime>
                                        <ArrTime>19:45</ArrTime>
                                        <CarCode>3L</CarCode>
                                        <CarName>Inter Sky</CarName>
                                        <FareClass>Economy</FareClass>
                                        <ArrDateTime>2014-08-08T19:45:00</ArrDateTime>
                                        <DepDateTime>2014-08-08T18:00:00</DepDateTime>
                                    </Leg>
                                </Legs>
                                <Taxes>0</Taxes>
                                <FareADT>10500</FareADT>
                                <FareCHD>0</FareCHD>
                                <FareINF>0</FareINF>
                                <MiscFees>6400</MiscFees>
                                <Idx>307964</Idx>
                                <FareClass>Economy</FareClass>
                                <FareType>Web</FareType>
                                <FareId>3L0</FareId>
                            </Outbound>
                            <BagFee>0</BagFee>
                            <CcFee>600</CcFee>
                            <HandlingFee>500</HandlingFee>
                            <TotalFare>16900</TotalFare>
                            <FlightId>140514114543-02-21212-3</FlightId>
                            <Link2Book>http://sample.com</Link2Book>
                            <Provider>ElsyArres</Provider>
                        </Flight>
                    </Flights>
                </Response>
            </SoapMessage>
        </SearchFlightsResponse>
    </soap:Body>
</soap:Envelope>

Code

message.writeTo(System.out); //show message details

URL endpoint = new URL("http://testv80.elsyarres.net/service.asmx");
SOAPMessage response = connection.call(message, endpoint);

connection.close();

SOAPMessage sm = response;
System.err.println("sm is:" + sm);
System.out.println("Response:");
ByteArrayOutputStream out = new ByteArrayOutputStream();
sm.writeTo(out);

System.out.println(out.toString());  //ValidSoap message
NamespaceFilter outFilter = new NamespaceFilter(null, false);
Reader in = new StringReader(out.toString());  //reading character stream
InputSource is = new InputSource(in);
SAXSource source = new SAXSource(outFilter,is); 

Line 202 >>>

this.results = (SearchFlightsResponse) JAXB.unmarshal(source, SearchFlightsResponse.class);
System.err.println(">" + results.getSoapMessage().getUsername());
JAXBContext context = JAXBContext.newInstance(SearchFlightsResponse.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
m.marshal(results, System.out);

This is the filter implementation that I've found here

NamespaceFilter

public class NamespaceFilter extends XMLFilterImpl {

    private String usedNamespaceUri;
    private boolean addNamespace;

    //State variable
    private boolean addedNamespace = false;

    public NamespaceFilter(String namespaceUri,
            boolean addNamespace) {
        super();

        if (addNamespace)
            this.usedNamespaceUri = namespaceUri;
        else 
            this.usedNamespaceUri = "";
        this.addNamespace = addNamespace;
    }



    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        if (addNamespace) {
            startControlledPrefixMapping();
        }
    }



    @Override
    public void startElement(String arg0, String arg1, String arg2,
            Attributes arg3) throws SAXException {

        super.startElement(this.usedNamespaceUri, arg1, arg2, arg3);
    }

    @Override
    public void endElement(String arg0, String arg1, String arg2)
            throws SAXException {

        super.endElement(this.usedNamespaceUri, arg1, arg2);
    }

    @Override
    public void startPrefixMapping(String prefix, String url)
            throws SAXException {


        if (addNamespace) {
            this.startControlledPrefixMapping();
        } else {
            //Remove the namespace, i.e. don´t call startPrefixMapping for parent!
        }

    }

    private void startControlledPrefixMapping() throws SAXException {

        if (this.addNamespace && !this.addedNamespace) {
            //We should add namespace since it is set and has not yet been done.
            super.startPrefixMapping("", this.usedNamespaceUri);

            //Make sure we dont do it twice
            this.addedNamespace = true;
        }
    }

}

Error

java.lang.NullPointerException: No parent for filter
    at org.xml.sax.helpers.XMLFilterImpl.setupParse(XMLFilterImpl.java:714)
    at org.xml.sax.helpers.XMLFilterImpl.parse(XMLFilterImpl.java:356)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:203)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:181)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:232)
    at javax.xml.bind.JAXB.unmarshal(JAXB.java:259)
    at com.test.retrieveFlights(test.java:202)
at com.test.App.main(App.java:17)

回答1:


A JAXB (JSR-222) implementation should not have any problems with that SOAP response as is. This question was in response to an answer you got on a related question, but that answer was incorrect.

  • JAXB unmarshalling returns 'URI is not absolute' error

The SOAPMessage instance is a DOM representation of the SOAP message. You simply need to navigate down to the child element you have mapped to and unmarshal that. Below is what we came up with for one of your related questions:

  • Can not unmarshall the SOAP response


来源:https://stackoverflow.com/questions/24228672/cannot-remove-namespace-of-soap-response-using-saxfilter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!