title: Spring boot apache CXF capture soap errors and return http error code
body: <p>I am using spring boot with Apache CXF.   The starter im using is the spring boot <code>cxf-spring-boot-starter-jaxws</code>.  I followed the guides from apaches cxf own website. <code>http://cxf.apache.org/docs/springboot.html</code>.</p>
  
  <p>I am also using Java11.</p>
  
  <p>The problem I'm having is that soap requests into the application that error always return 200 headers regardless if there was an error or not. </p>
  
  <p>The web service endpoint I'm hitting is a void method but I would still like to return a 500 code in the http header if it doesn't work. </p>
  
  <p>The strategy I have in mind is to create an interceptor that will intercept soap requests that error and modify the final response with a http header code.  So the body would be null for void methods but the header is 400 or 500.</p>
  
  <p><strong>My soap service configuration looks like this</strong></p>
  
  <pre><code>@Configuration
  @Slf4j
  public class WebServiceConfiguration {
  
      @Autowired
      private Bus bus;
  
      @Bean
      public Endpoint endpoint() {
          EndpointImpl endpoint = new EndpointImpl(bus, new SoapEventEndpoint());
          endpoint.publish("/EventEndpoint");
          endpoint.setWsdlLocation("ReceiveEvent.wsdl");
  
          // this interceptor works
          endpoint.getInInterceptors().add(soapInterceptor());
  
          // these two fault interceptors do not work!
          endpoint.getInFaultInterceptors().add(soapFaultInterceptor());
          endpoint.getOutFaultInterceptors().add(soapFaultInterceptor());
  
          return endpoint;
      }
  
      @Bean
      public AbstractSoapInterceptor soapFaultInterceptor(){
          return new SoapFaultInterceptor( Phase.PRE_STREAM);
      }
  
      @Bean
      public AbstractSoapInterceptor soapInterceptor(){
          return new SoapInterceptor( Phase.PRE_STREAM);
      }
  }
  </code></pre>
  
  <p><strong>Interceptors</strong></p>
  
  <pre><code>@Slf4j
  public class SoapFaultInterceptor extends AbstractSoapInterceptor {
  
      public SoapFaultInterceptor(String phase) {
          super(phase);
      }
  
      @Override
      public void handleMessage(SoapMessage message) throws Fault {
          log.info("THIS NEVER GETS CALLED!!  Execpting errors to invoke this method");
      }
  }
  
  @Slf4j
  public class SoapInterceptor extends AbstractSoapInterceptor {
  
  
      public SoapInterceptor(String p){
          super(p);
      }
  
      @Override
      public void handleMessage(SoapMessage message) throws Fault {
          log.info("THIS WORKS");
      }
  }
  </code></pre>
  
  <p><strong>WSDL to Java Generated event endpoint</strong></p>
  
  <pre><code>@WebService(targetNamespace = "xyz", name = "ReceiveEventEndpoint")
  @XmlSeeAlso({ObjectFactory.class})
  @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
  public interface ReceiveEventEndpoint {
  
      @WebMethod(operationName = "ReceiveEvent", action = "xyz")
      @Oneway
      public void receiveEvent(
          @WebParam(partName = "in", name = "ReceiveEventRequest", targetNamespace = "xyz")
          ReceiveEventRequest in
      );
  }
  </code></pre>
  
  <p><strong>1)  When I invalidate with the XML and send the request.  Only the  <code>SoapInterceptor</code> intercepts it?   The <code>SoapFaultInterceptor</code> doesnt? Any suggestions?</strong></p>
  
  <pre><code>Interceptor for {http://xyz/}SoapEventEndpointService#{http:/xyz}ReceiveEvent has thrown exception, unwinding now
  
  org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element (uri:"http://xyz", local:"EventId1"). Expected elements are &lt;{http://xyz}LocalAssessmentId&gt;,&lt;{http://xyz}LOTId&gt;,&lt;{http://xyz}EventId&gt;,&lt;{http://xyz}Benefit&gt; 
      at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:938) ~[cxf-rt-databinding-jaxb-3.3.1.jar:3.3.1]
      at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:744) ~[cxf-rt-databinding-jaxb-3.3.1.jar:3.3.1]
      at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:172) ~[cxf-rt-databinding-jaxb-3.3.1.jar:3.3.1]
      at org.apache.cxf.wsdl.interceptors.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:194) ~[cxf-rt-wsdl-3.3.1.jar:3.3.1]
      at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[cxf-core-3.3.1.jar:3.3.1]
      at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[cxf-core-3.3.1.jar:3.3.1]
      at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267) ~[cxf-rt-transports-http-3.3.1.jar:3.3.1]
      at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[cxf-rt-transports-http-3.3.1.jar:3.3.1]
      at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[cxf-rt-transports-http-3.3.1.jar:3.3.1]
      at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[cxf-rt-transports-http-3.3.1.jar:3.3.1]
      at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:216) ~[cxf-rt-transports-http-3.3.1.jar:3.3.1]
      at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301) ~[cxf-rt-transports-http-3.3.1.jar:3.3.1]
      at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:220) ~[cxf-rt-transports-http-3.3.1.jar:3.3.1]
      at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:276) ~[cxf-rt-transports-http-3.3.1.jar:3.3.1]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
      at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.5.RELEASE.jar:5.1.5.RELEASE]
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
      at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
      at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.16.jar:9.0.16]
      at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
  Caused by: javax.xml.bind.UnmarshalException: null
      at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:483) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:417) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:394) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at org.apache.cxf.jaxb.JAXBEncoderDecoder.doUnmarshal(JAXBEncoderDecoder.java:887) ~[cxf-rt-databinding-jaxb-3.3.1.jar:3.3.1]
      at org.apache.cxf.jaxb.JAXBEncoderDecoder.access$200(JAXBEncoderDecoder.java:103) ~[cxf-rt-databinding-jaxb-3.3.1.jar:3.3.1]
      at org.apache.cxf.jaxb.JAXBEncoderDecoder$3.run(JAXBEncoderDecoder.java:926) ~[cxf-rt-databinding-jaxb-3.3.1.jar:3.3.1]
      at java.base/java.security.AccessController.doPrivileged(Native Method) ~[na:na]
      at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:924) ~[cxf-rt-databinding-jaxb-3.3.1.jar:3.3.1]
      ... 51 common frames omitted
  Caused by: com.sun.istack.SAXParseException2: unexpected element (uri:"xyz", local:"EventId1"). Expected elements are &lt;{http://xyz}LocalAssessmentId&gt;,&lt;{http://xyz}LOTId&gt;,&lt;{http://xyz}EventId&gt;,&lt;{http://xyz}Benefit&gt;
      at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:744) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:262) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:257) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:124) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.Loader.childElement(Loader.java:105) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.StructureLoader.childElement(StructureLoader.java:268) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:574) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:556) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleStartElement(StAXStreamConnector.java:246) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:180) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:415) ~[jaxb-runtime-2.3.1.jar:2.3.1]
      ... 57 common frames omitted
  Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://uxyz", local:"EventId1"). Expected elements are &lt;{http://xyz}LocalAssessmentId&gt;,&lt;{http://xyz}LOTId&gt;,&lt;{http://xyz}EventId&gt;,&lt;{http://uxyz}Benefit&gt;
      ... 68 common frames omitted
  
  2019-03-27 15:44:15.245 DEBUG 22552 --- [nio-8080-exec-4] o.a.c.t.http.AbstractHTTPDestination     : Finished servicing http request on thread: Thread[http-nio-8080-exec-4,5,main]
  2019-03-27 15:44:15.245 DEBUG 22552 --- [nio-8080-exec-4] o.a.c.t.servlet.ServletController        : Finished servicing http request on thread: Thread[http-nio-8080-exec-4,5,main]
  </code></pre>
  
  <p>**2) How do I add an interceptor (or fault listener) or some other method to update the http header after errors are intercepted?</p>