有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java SoapFaultClientException:找不到标头

一个SOAPWeb服务,它接受以下格式的请求-

<?xml version = "1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope"
                   xmlns:ns="http://...." xmlns:ns1="http://...." xmlns:ns2="http://...."
                   xmlns:ns3="http://....">
    <SOAP-ENV:Header>
        <ns:EMContext>
            <messageId>1</messageId>
            <refToMessageId>ABC123</refToMessageId>
            <session>
                <sessionId>3</sessionId>
                <sessionSequenceNumber>2021-02-24T00:00:00.000+5:00</sessionSequenceNumber>
            </session>
            <invokerRef>CRS</invokerRef>
        </ns:EMContext>
    </SOAP-ENV:Header>
    <SOAP-ENV:Body>
        <ns1:getEmployee>
            <ns:empId>111</ns:empId>
        </ns1:getEmployee>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

当试图使用JAXB2向其发出SOAP请求时,它给出了org.springframework.ws.soap.client.SoapFaultClientException: EMContext Header is missing

我在用

pring-boot-starter

spring-boot-starter-web-services

org.jvnet.jaxb2.maven2 : maven-jaxb2-plugin : 0.14.0

客户-

public class MyClient extends WebServiceGatewaySupport {


    public GetEmployeeResponse getEmployee(String url, Object request){

        GetEmployeeResponse res = (GetEmployeeResponse) getWebServiceTemplate().marshalSendAndReceive(url, request);
        return res;
    }
}

配置-

@Configuration
public class EmpConfig {

    @Bean
    public Jaxb2Marshaller marshaller(){
        Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
        jaxb2Marshaller.setContextPath("com.crsardar.java.soap.client.request");
        return jaxb2Marshaller;
    }

    @Bean
    public MyClient getClient(Jaxb2Marshaller jaxb2Marshaller){
        MyClient myClient = new MyClient();
        myClient.setDefaultUri("http://localhost:8080/ws");
        myClient.setMarshaller(jaxb2Marshaller);
        myClient.setUnmarshaller(jaxb2Marshaller);
        return myClient;
    }
}

应用程序-

@SpringBootApplication
public class App {

    public static void main(String[] args) {

        SpringApplication.run(App.class, args);
    }

    @Bean
    CommandLineRunner lookup(MyClient myClient){

        return args -> {

            GetEmployeeRequest getEmployeeRequest = new GetEmployeeRequest();
            getEmployeeRequest.setId(1);
            GetEmployeeResponse employee = myClient.getEmployee("http://localhost:8080/ws", getEmployeeRequest);
            System.out.println("Response = " + employee.getEmployeeDetails().getName());
        };
    }
}

如何将EMContext头添加到SOAP请求


共 (1) 个答案

  1. # 1 楼答案

    服务器正在抱怨,因为您的Web服务客户端没有在SOAP消息中发送EMContextSOAP头

    不幸的是,目前SpringWeb服务缺乏对以类似于使用JAXB处理SOAP主体信息的方式包含SOAP头的支持

    作为一种变通方法,您可以使用WebServiceMessageCallback。从docs开始:

    To accommodate the setting of SOAP headers and other settings on the message, the WebServiceMessageCallback interface gives you access to the message after it has been created, but before it is sent.

    在您的情况下,您可以使用以下内容:

    public class MyClient extends WebServiceGatewaySupport {
    
    
      public GetEmployeeResponse getEmployee(String url, Object request){
    
        // Obtain the required information
        String messageId = "1";
        String refToMessageId = "ABC123";
        String sessionId = "3";
        String sessionSequenceNumber = "2021-02-24T00:00:00.000+5:00";
        String invokerRef = "CRS";
    
        GetEmployeeResponse res = (GetEmployeeResponse) this.getWebServiceTemplate().marshalSendAndReceive(url, request, new WebServiceMessageCallback() {
    
          @Override
          public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
            // Include the SOAP header content for EMContext
            try {
              SoapMessage soapMessage = (SoapMessage)message;
              SoapHeader header = soapMessage.getSoapHeader();
              StringSource headerSource = new StringSource(
                "<EMContext xmlns:ns=\"http://....\">" +
                  "<messageId>" + messageId + "</messageId>" +
                  "<refToMessageId>" + refToMessageId + "</refToMessageId>" +
                  "<session>" +
                    "<sessionId>" + sessionId + "</sessionId>" +
                    "<sessionSequenceNumber>" + sessionSequenceNumber + "</sessionSequenceNumber>" +
                  "</session>" +
                  "<invokerRef>" + invokerRef + "</invokerRef>" +
                "</EMContext>"
              );
    
              Transformer transformer = TransformerFactory.newInstance().newTransformer();
              transformer.transform(headerSource, header.getResult());
            } catch (Exception e) {
              // handle the exception as appropriate
              e.printStackTrace();
            }
          }
        });
        return res;
      }
    }
    

    类似的问题也在SO上发布。例如,考虑复习thisthis other