Web Services jax-ws:服务器端出现不支持的介质异常content-type

9nvpjoqh  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(161)

我的soap客户端正在进行成功的请求,并从soap服务器获得200 OK。但是,由于缺少内容类型头,应用程序出错。我试图在处理程序中添加内容类型头,但甚至没有调用(使用调试器,我可以看到该方法从未命中入站消息,但命中出站消息)
下面是处理程序代码:

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;

        }

这是我如何连接我的处理程序

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);

这是我为一个成功的调用返回的日志。注意响应头上的空内容类型,这是导致这个错误的原因。

---[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]

编辑

通过更多的调试,我能够通过intellij调试控制台在响应中手动更改content-type以包括“text/xml”,并且一切都按预期运行
我将下面的contentType更改为“text/xml”,它在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);
        }
1tuwyuhd

1tuwyuhd1#

您可以添加自定义com.sun.xml.internal.ws.api.pipe.TransportTubeFactory来访问HttpTransportPipe中的Codec.decode调用;请看我对这个问题的回答的最后一部分:UnsupportedMediaException -> how do you get the actual response?
在这个问题中,我们对“faulty”响应的主体更感兴趣,但是您可以使用Codec Package 器轻松地否决Content-Type
来自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);
    }

一些备注:

  • 我已经写了jaxws-rt的参考答案,根据你的错误信息,你使用的是JRE内部版本。虽然它应该是一样的。唯一的区别是包名。
  • 幸运的是,content-type为null,否则将得到一个更难绕过的ClientTransportException(无需从HttpTransportPipe复制大量代码)
  • 如果你能找到一种更简单的方法来代理你的HTTP流量并重写内容类型,那就更简单了。2例如,请看这里的答案:SOAP unsupported media exception text/plain Supported ones are: [text/xml]关于如何使用Apache httpd作为反向代理

相关问题