2

my soap client is making successful request and getting 200 OK from soap server. However, the application is erroring due to missing content-type header. I tried to add content-type header in handler but that is not even invoked (using debugger, I can see that method is never hit for inbound message but for outbound it is hit)

Here is the handler code:

public class ClientHandler implements SOAPHandler<SOAPMessageContext> {
        public boolean handleMessage(SOAPMessageContext context) {
            if ((Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)) {
                    System.out.println(" here: in outbound call");
            }


                if (!(Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)) {
                    Map<String, List<String>> headers = (Map<String, List<String>>)context.get(MessageContext.HTTP_RESPONSE_HEADERS);

                    List<String> value = new ArrayList<String>();
                    value.add("text/xml");

                    if (headers != null) {
                        headers.put("content-type", value);
                    } else {
                        Map<String, List<String>> brandNewHeaders = new HashMap<String, List<String>>();
                        brandNewHeaders.put("content-type", value);
                        context.put(MessageContext.HTTP_RESPONSE_HEADERS, brandNewHeaders);
                    }
                }

            return true;

        }

Here is how I attach my handler

WSGService service = new WSGService();
        appPort =  service.getWSGHttpPort();
        final Binding binding = ((BindingProvider) provisionPort).getBinding();
        BindingProvider bp = (BindingProvider)provisionPort;
        bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, provisionurl);
        List<Handler> handlerList = new ArrayList<>();
        handlerList.add(new ClientHandler());
        binding.setHandlerChain(handlerList);

Here is the log I get back for a successful call. NOTE empty content-type on response header, which is causing this error.

---[HTTP request - https://foobar/url]---
Accept: [text/xml, multipart/related]
Content-Type: [text/xml; charset=utf-8]
SOAPAction: ["/FOOBARWSG"]
User-Agent: [JAX-WS RI 2.2.4-b01]
<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body>**BODY**</S:Body></S:Envelope>--------------------
---[HTTP response - https://foobar/url - 200]---
null: [HTTP/1.0 200 OK]
Access-Control-Allow-Headers: [Content-Type, Accept, Accept-Encoding, Content-Encoding, X-Client-UID, Authorization, X-Associated-Id]
Access-Control-Allow-Methods: [GET, POST, PUT, DELETE]
Access-Control-Allow-Origin: [*]
Access-Control-Expose-Headers: [WWW-Authenticate]
Connection: [close]
Content-Length: [2915]
content-type: []
Date: [Tue, 31 Jan 2017 06:24:05 GMT]
Server: [JBOSS Application Server]
X-WsgSource: [DUMMY,15,2017-01-31 06:24:05]
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns></SOAP-ENV:Body></SOAP-ENV:Envelope>--------------------
22:24:07,605 ERROR ErrorPageFilter:180 - Forwarding to error page from request [/dummy/customerType/null] due to exception [Unsupported Content-Type:  Supported ones are: [text/xml]]
com.sun.xml.internal.ws.server.UnsupportedMediaException: Unsupported Content-Type:  Supported ones are: [text/xml]

EDIT:

with more debugging, I was able to manually change content-type to include "text/xml" in response through intellij debug console and everything behaved as expected

I changed contentType below to "text/xml" which had empty value in it in the HttpTrasportPipe.class

this.checkStatusCode(responseStream, con);
        Packet reply = request.createClientResponse((Message)null);
        reply.wasTransportSecure = con.isSecure();
        if(responseStream != null) {
            String contentType = con.getContentType();
            if(contentType != null && contentType.contains("text/html") && this.binding instanceof SOAPBinding) {
                throw new ClientTransportException(ClientMessages.localizableHTTP_STATUS_CODE(Integer.valueOf(con.statusCode), con.statusMessage));
            }

            this.codec.decode(responseStream, contentType, reply);
        }
brain storm
  • 30,124
  • 69
  • 225
  • 393
  • perhaps I'm mistaken, but the request from your client seems valid, the problem is the response from the server, which does not have content -type and it contains invalid SOAP XML (see missing soap header tags, and body start tag). The error is not in the client then, it's on the server. – JChrist Jan 31 '17 at 06:58
  • yes, it is on server side which I am aware of. I am trying to add content-type header to response object I get back from server. but before my handler, exception is thrown – brain storm Jan 31 '17 at 07:00
  • 1
    ooh, so you're kinda trying to _fix_ incoming invalid soap? having to communicate through SOAP is troublesome itself, having to do magic like yours is *deep*! Good luck :) – JChrist Jan 31 '17 at 07:02

1 Answers1

0

You can add a custom com.sun.xml.internal.ws.api.pipe.TransportTubeFactory to access the Codec.decode call in HttpTransportPipe; see the last part of my answer on this question: UnsupportedMediaException -> how do you get the actual response?

In that question we were more interested in the body of the 'faulty' response, but you can use the Codec wrapper just as easily to overrule the Content-Type:

Snippet from my CodecWrapper:

    @Override
    public void decode(InputStream in, String contentType, Packet response) throws IOException {
        // TODO: here you can access / change any of the parameters before sending it to the actual SOAP Codec
        wrapped.decode(in, contentType, response);
    }

Some remarks:

  • i've written the referenced answer for jaxws-rt, and according to your error message you're using the JRE internal version. It should work the same though. The only difference is the package names.
  • you're lucky the content-type is null, otherwise you would get a ClientTransportException that is much harder to circumvent (without copying a lot of code from HttpTransportPipe)
  • if you can find an easier way to proxy your HTTP traffic and re-write the Content-Type that way, that would be neater. See for example the accepted answer here: SOAP unsupported media exception text/plain Supported ones are: [text/xml] on how to use Apache httpd as a reverse proxy
slindenau
  • 1,091
  • 2
  • 11
  • 18