5
<soapenv:Fault xmlns:m="http://schemas.xmlsoap.org/soap/envelope/">
     <faultcode>m:Server</faultcode>
     <faultstring>someFaultString</faultstring>
     <detail>
        <NS1:confirmIdentityErrorInfo xmlns:NS1="example.com">
           <faultInfo>
              <faultType>Business Exception</faultType>
              <faultCode>100</faultCode>
              <message>some message</message>
              <faultState>fault state</faultState>
           </faultInfo>
        </NS1:confirmIdentityErrorInfo>
     </detail>
  </soapenv:Fault>

I would need to generate the fault object as above. I am able to generate 'confirmIdentityErrorInfo' but not able to add child elements. I tried this option, but I couldn't generated nested object structure.

public class WebServiceConfig extends WsConfigurerAdapter {

 @Bean
    public SoapFaultMappingExceptionResolver exceptionResolver(){
        SoapFaultMappingExceptionResolver exceptionResolver = new DetailSoapFaultDefinitionExceptionResolver();

        SoapFaultDefinition faultDefinition = new SoapFaultDefinition();
        faultDefinition.setFaultCode(SoapFaultDefinition.SERVER);
        exceptionResolver.setDefaultFault(faultDefinition);

        Properties errorMappings = new Properties();
        errorMappings.setProperty(Exception.class.getName(), SoapFaultDefinition.SERVER.toString());
        errorMappings.setProperty(BusinessException.class.getName(), SoapFaultDefinition.SERVER.toString());
        exceptionResolver.setExceptionMappings(errorMappings);
        exceptionResolver.setOrder(1);
        return exceptionResolver;
    }

}


protected void customizeFault(Object endpoint, Exception ex, SoapFault fault) {
    if (ex instanceof BusinessException) {
        SoapFaultDetail detail = fault.addFaultDetail();
        try
        {
            QName entryName = new QName("namespace", "confirmIdentityErrorInfo", "NS1");
            detail.addFaultDetailElement(entryName);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }

}

But I am not sure how to add child elements to QName. Can someone help me how to product the fault detail as shown above?

2 Answers2

3

This is the solution.

fault.addFaultDetail();
   this.marshaller.marshal(((AJAXB2MarshalledBusinessException)ex).getMyJAXB2MarshallableComplexMessage(), fault.getFaultDetail().getResult());

More detailed in this link:

Vladimir
  • 525
  • 5
  • 15
  • The link above is no longer valid, but here's an article describing exactly that solution: https://maarten.mulders.it/2018/07/custom-soap-faults-using-spring-ws/ – Timi Jun 18 '19 at 08:05
2
public class DetailSoapFaultDefinitionExceptionResolver extends SoapFaultMappingExceptionResolver {
  private static final ObjectFactory FACTORY = new ObjectFactory();
  private final Marshaller marshaller;

  public DetailSoapFaultDefinitionExceptionResolver() throws JAXBException {
    JAXBContext jaxbContext = JAXBContext.newInstance("your.schema");
    this.marshaller = jaxbContext.createMarshaller();
  }

  @Override
  protected void customizeFault(Object endpoint, Exception e, SoapFault fault) {

    YourFault xsdFault = new YourFault();
    xsdFault.setCode("UNKNOWN_FAILURE");
    xsdFault.setDescription(e.getMessage());

    SoapFaultDetail faultDetail = fault.addFaultDetail();
    try {
      marshaller.marshal(FACTORY.createSubscriptionManagementFault(xsdFault), faultDetail.getResult());
    } catch (JAXBException e1) {
      log.error("Could not marshall SubscriptionManagementFault", e);
    }

  }

Here is detailed explanation https://maarten.mulders.it/2018/07/custom-soap-faults-using-spring-ws/