Search code examples
web-servicessoapwsdlcxfhttp-status-code-400

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


I'm consuming a webservice through a WSDL. I generated Java classes using Apache CXF wsdl2java.

For my soap messages >4kb, I get the below error. Messages <4kb has no problem getting response whatsoever. I tried disabling CHUNKING as follows:

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

I tried adding Content-Length to the HTTP header explicitly so that it disables chunking if its so.

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

Please help me through this. I cannot figure out why.

Stacktrace:

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

This is how I call the service in 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);

My handler method is given below:

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

Could you please let me know what other code you would want to see to understand it better?


Solution

  • You can disable chunking on JBoss using below code. Add this code right after creating port object.

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

    You may need the following jar files in your classpath:

    needed jar files