在服务器端从 HTTP/1.0 升级到 HTTP/1.1,SOAP 消息 >4kb 抛出“400:错误请求”错误

Upgrade from HTTP/1.0 to HTTP/1.1 at server side, SOAP messages >4kb throws '400: Bad Request' Error

我正在通过 WSDL 使用 Web 服务。我使用 Apache CXF wsdl2java 生成了 Java 类。

对于 >4kb 的 soap 消息,我收到以下错误。 <4kb 的消息在获得响应方面没有任何问题。我尝试如下禁用 CHUNKING:

soapMessageContext.put(HTTPConstants.CHUNKED, Boolean.FALSE);

我尝试将 Content-Length 显式添加到 HTTP header 以便它禁用分块。

Map<String, List<String>> httpHeaders = new HashMap<String,List<String>>();
            httpHeaders.put("Content-Length", Collections.singletonList(filelength));
            Map<String, Object> reqContext = ((BindingProvider) port).getRequestContext();
            reqContext.put(MessageContext.HTTP_REQUEST_HEADERS, httpHeaders);
            repairOrderResponse = port.submitRepairOrder(security,
                    repairorders);

请帮我解决这个问题。我不知道为什么。

堆栈跟踪:

javax.xml.ws.WebServiceException: Could not send Message.
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:146)
    at com.sun.proxy.$Proxy80.submitRepairOrder(Unknown Source)
    at com.ssss.ssjdecommonws.webservices.SSJDECommonService.submitOrder(SSJDECommonService.java:640)
    at com.ssss.ssjdecommonws.webservices.SSJDECommonService.getRepairOrderResult(SSJDECommonService.java:529)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
    at org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:269)
    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:227)
    at org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:216)
    at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:542)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:524)
    at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:126)
    at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:208)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55)
    at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:50)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149)
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:559)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340)
    at org.apache.coyote.http11.Http11NioProcessor.process(Http11NioProcessor.java:353)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:911)
    at org.apache.tomcat.util.net.NioEndpoint$ChannelProcessor.run(NioEndpoint.java:920)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '400: Bad Request' when communicating with <MY_ENDPOINT_COMES_HERE>
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1549)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1504)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1310)
        at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
        at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:628)
        at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
        at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:565)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)
        at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)
        at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
        at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
        ... 34 more

这就是我在 submitOrder() 中调用服务的方式

    SubmitRepairOrderService sService = new SubmitRepairOrderService(u, SERVICE_NAME);
    SubmitRepairOrderType port = sService.getSubmitRepairOrderPort();
    List<Handler> new_handlerChain = new ArrayList<Handler>();
    fdda = new MessageHandler(props);
    new_handlerChain.add(fdda);
    ((BindingProvider) port).getBinding().setHandlerChain(new_handlerChain);
    security = null;
    repairOrderResponse = port.submitRepairOrder(security,repairorders);

我的处理方法如下:

public boolean handleMessage(SOAPMessageContext messageContext) {
try {
    SOAPHeader header = null;
    boolean outMessageIndicator = (Boolean) messageContext
                    .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
    if (outMessageIndicator) {
    SOAPEnvelope envelope = messageContext.getMessage().getSOAPPart().getEnvelope();

    if (envelope.getHeader() != null) {
                    header = envelope.getHeader();
    }
    SOAPElement security = header.addChildElement("Security","oas","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
    SOAPElement usernameToken = security.addChildElement("UsernameToken", "oas");
    usernameToken.addAttribute(new QName("xmlns:wsu"),
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

SOAPElement username = usernameToken.addChildElement("Username", "oas");
                username.addTextNode(userId);
SOAPElement password = usernameToken.addChildElement("Password", "oas");
                password.setAttribute("Type",
                        "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
                password.addTextNode(passcode);
}

        } catch (Exception ex) {
            throw new WebServiceException(ex);
        }
        return true;
    }

能否请您告诉我您还希望看到哪些其他代码以更好地理解它?

您可以使用以下代码在 JBoss 上禁用分块。 在创建 port 对象后立即添加此代码。

SubmitRepairOrderType port = sService.getSubmitRepairOrderPort();

HTTPClientPolicy hTTPClientPolicy = new HTTPClientPolicy();
hTTPClientPolicy.setAllowChunking(false);
     
Client client =  org.apache.cxf.jaxws.JaxWsClientProxy.getClient( port );
HTTPConduit http = ( HTTPConduit ) client.getConduit();
   
http.setClient(hTTPClientPolicy);

您的类路径中可能需要以下 jar 文件: