Search code examples
cxfjboss7.xhttp-status-code-200

JBoss 6 EAP - override HTTP response status code in a SOAP service that sends empty response back from 202 to 200


We have a SOAP web service that we are migrating from JBoss EAP 5.1 to 6.4.7 and one of the webservices returns absolutely nothing but 200 (in JBoss 5). When we migrated to 6 it still works and returns nothing but returns a 202 instead and that is going to break clients. We have no control over clients. I tried a SOAPHandler at the close method but it does nothing as it is not even called as my guess is that since there is no SOAP message going back there is nothing that triggers the handler.

I also tried to access the context directly in the web method and modif but it did nothing.

MessageContext ctx = wsContext.getMessageContext(); HttpServletResponse response = (HttpServletResponse) ctx.get(MessageContext.SERVLET_RESPONSE); response.setStatus(HttpServletResponse.SC_OK);

I couldn't find anything in the manual.

Any direction is very much appreciated.

Here is how the port and its implementation look like:

Here is how the port and its implementation head look like:

@WebService(name = "ForecastServicePortType", targetNamespace = "http://www.company.com/forecastservice/wsdl")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@XmlSeeAlso({
    ObjectFactory.class
})
public interface ForecastServicePortType {


    /**
     *  
     * @param parameters
     * @throws RemoteException 
     */
    @WebMethod(action = "http://www.company.com/forecast/sendForecast")
    public void  sendForecast(
        @WebParam(name = "SendForecast", targetNamespace = "http://www.company.com/forecastservice", partName = "parameters")
        SendForecastType parameters) throws RemoteException;

}



@WebService(name = "ForecastServicePortTypeImpl", serviceName = "ForecastServicePortType", endpointInterface = "com.company.forecastservice.wsdl.ForecastServicePortType", wsdlLocation = "/WEB-INF/wsdl/ForecastServicePortType.wsdl")
@HandlerChain(file = "/META-INF/handlers.xml")
public class ForecastServicePortTypeImpl implements ForecastServicePortType {
...

}

Solution

  • In case anybody will find this useful. Here is the solution;

    Apache CXF by default uses async requests and even if the annotation @OneWay is missing it still behaves as it if was there.

    So in order to disable that an interceptor needs to be created like below:

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.apache.cxf.binding.soap.SoapMessage;
    import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
    import org.apache.cxf.interceptor.Fault;
    import org.apache.cxf.phase.Phase;
    
    import java.util.Arrays;
    
    public class DisableOneWayInterceptor extends AbstractSoapInterceptor {
        private static final Log LOG = LogFactory.getLog(DisableOneWayInterceptor.class);
    
        public DisableOneWayInterceptor(){
            super(Phase.PRE_LOGICAL);
            addBefore(Arrays.asList(org.apache.cxf.interceptor.OneWayProcessorInterceptor.class.getName()));
        }
    
        @Override
        public void handleMessage(SoapMessage soapMessage) throws Fault {
            if(LOG.isDebugEnabled())
            LOG.debug("OneWay behavior disabled");
    
            soapMessage.getExchange().setOneWay(false);
        }
    }
    

    And called in WebService class (annotated with @WebService) as below:

    @org.apache.cxf.interceptor.InInterceptors (interceptors = {"com.mycompany.interceptors.DisableOneWayInterceptor" })