处理 Spring Boot WebServiceTemplate 中的 SOAP 错误

Cor*_*chi 6 soap spring-boot

我是 SOAP 新手,尝试使用 Spring Boot 运行示例 SOAP 客户端

使用 WebServiceTemplate 时如何处理 SOAP 故障、异常或错误

 public class CountryClient extends WebServiceGatewaySupport {

  private static final Logger log = LoggerFactory.getLogger(CountryClient.class);

  public GetCountryResponse getCountry(String country) {

    GetCountryRequest request = new GetCountryRequest();
    request.setName(country);

    log.info("Requesting location for " + country);

    GetCountryResponse response = (GetCountryResponse) getWebServiceTemplate()
        .marshalSendAndReceive("http://localhost:8080/ws/countries", request,
            new SoapActionCallback(
                "http://spring.io/guides/gs-producing-web-service/GetCountryRequest"));

    return response;
  }

}
Run Code Online (Sandbox Code Playgroud)

小智 11

一种方法是编写实现 Spring WS 的 ClientInterceptor 接口的自定义拦截器。您应该重写handleFault 方法以使用自定义逻辑处理SOAP 错误。

public class MySoapClientInterceptor implements ClientInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(MySoapClientInterceptor.class);

    @Override
    public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {

        return true;
    }

    @Override
    public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {

        return true;
    }

    @Override
    public boolean handleFault(MessageContext messageContext) throws WebServiceClientException {

        LOGGER.info("intercepted a fault...");
        SoapBody soapBody = getSoapBody(messageContext);
        SoapFault soapFault = soapBody.getFault();
        LOGGER.error(soapFault.getFaultStringOrReason());
        throw new RuntimeException(String.format("Error occured while invoking SOAP service - %s ", soapFault.getFaultStringOrReason()));
    }

    @Override
    public void afterCompletion(MessageContext messageContext, Exception ex) throws WebServiceClientException {

    }

    private SoapBody getSoapBody(MessageContext messageContext) {
        SoapMessage soapMessage = (SoapMessage) messageContext.getResponse();
        SoapEnvelope soapEnvelope = soapMessage.getEnvelope();
        return soapEnvelope.getBody();
    }
}    
Run Code Online (Sandbox Code Playgroud)

然后,您需要将自定义拦截器类注册为 SOAP 客户端配置类中的拦截器。在您的案例中,您的 Configuration 类中 CountryClient 的 bean 定义处。

@Configuration
public class SoapClientConfig {

    @Value("${soap.server.url}")
    public String soap_server_url;

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("com.example");
        return marshaller;
    }

    @Bean
    public SoapConnector soapConnector(Jaxb2Marshaller marshaller) {
        SoapConnector client = new SoapConnector();
        client.setDefaultUri(soap_server_url);
        client.setMarshaller(marshaller);
        client.setUnmarshaller(marshaller);
        ClientInterceptor[] clientInterceptors = {new MySoapClientInterceptor()};
        client.setInterceptors(clientInterceptors);
        return client;
    }

}    
Run Code Online (Sandbox Code Playgroud)