首页 > 解决方案 > 使用 SpringBoot 添加自定义 SoapHeader

问题描述

使用 SoapUI,我可以发送带有自定义 SOAP 标头的请求,如下所示:

<soap:Header>
    <To xmlns="http://www.w3.org/2005/08/addressing">ws://xxx.com/PP/QM/GPMService/Vx</To>
   <Action xmlns="http://www.w3.org/2005/08/addressing">http://xmldefs.xxx.com/PP/QM/GPMService/Vx/AbcService/GetServiceInfoRequest</Action>
    <MessageID xmlns="http://www.w3.org/2005/08/addressing">ITEST-2018-04-16-0001</MessageID>
    <Stage xmlns="http://xmldefs.xxx.com/Technical/Addressing/V1">ProdX</Stage>
</soap:Header>

并得到合理的回应。我无法在我的 SpringBoot 应用程序中实现这一点。我有一个扩展 WebServiceGatewaySupport 的服务:

@Service
public class AbcService extends WebServiceGatewaySupport{
    private AbcConfiguration abcConfiguration;

    @Autowired
    public void setAbcConfiguration(final AbcConfiguration abcConfiguration) {
        this.abcConfiguration = abcConfiguration;
    }

    public GetServiceInfoResponse GetServiceInfo() {
        final String actionStr = "GetServiceInfo";
        final ObjectFactory factory = new ObjectFactory();

        GetServiceInfo getServiceInfo = factory.createGetServiceInfo();
        JAXBElement<GetServiceInfo> gsiRequest = factory.createGetServiceInfo(getServiceInfo);
        WebServiceTemplate wst = this.getWebServiceTemplate();
        @SuppressWarnings("unchecked")
        JAXBElement<GetServiceInfoResponse> gsiResponse = (JAXBElement<GetServiceInfoResponse>)wst
            .marshalSendAndReceive("https://ws-gateway-cert.xxx.com/services/", gsiRequest, new WebServiceMessageCallback() {
                    @Override
                    public void doWithMessage(WebServiceMessage message) {
                        try {
                            SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();
                            SoapHeaderElement toElem = soapHeader.addHeaderElement(new QName("http://www.w3.org/2005/08/addressing", "To"));
                            toElem.setText("ws://xxx.com/PP/QM/GPMService/Vx");
                            ...
                        } catch (Exception e) {
                            logger.error("Error during marshalling of the SOAP headers", e);
                        }
                    }
            });

        return gsiResponse.getValue();
    }
}

我究竟做错了什么?谁能告诉我我该怎么做?


好的。到目前为止,我得到了它的工作,并且 SOAP XML 看起来符合要求并在 SoapUI 中运行请求(从我的 SpringBoot 应用程序生成)我得到了要求的结果。

    public GetServiceInfoResponse GetServiceInfo() {
    final String actionStr = "GetServiceInfo";
    final ObjectFactory factory = new ObjectFactory();

    GetServiceInfo getServiceInfo = factory.createGetServiceInfo();
    JAXBElement<GetServiceInfo> gsiRequest = factory.createGetServiceInfo(getServiceInfo);
    WebServiceTemplate wst = this.getWebServiceTemplate();
    @SuppressWarnings("unchecked")
    JAXBElement<GetServiceInfoResponse> gsiResponse = (JAXBElement<GetServiceInfoResponse>)wst
        .marshalSendAndReceive(kpmConfiguration.getEndpoint(), gsiRequest, new WebServiceMessageCallback() {
                @Override
                public void doWithMessage(WebServiceMessage message) {
                    System.out.println(message.toString());
                    try {
                        // get the header from the SOAP message
                        final SoapHeader soapHeader = ((SoapMessage) message).getSoapHeader();
                        final SaajSoapMessage ssMessage = (SaajSoapMessage)message;
                        final SOAPEnvelope envelope = ssMessage.getSaajMessage().getSOAPPart().getEnvelope();
                System.out.println("envelope.getPrefix(): " + envelope.getPrefix());
                        envelope.removeNamespaceDeclaration("SOAP-ENV");
                        envelope.setPrefix(NAMESPACE_PREFIX_SOAP);

                System.out.println("envelope.getPrefix(): " + envelope.getPrefix());
                        envelope.getBody().setPrefix(NAMESPACE_PREFIX_SOAP);
                        envelope.getHeader().setPrefix(NAMESPACE_PREFIX_SOAP);
                        envelope.addNamespaceDeclaration(NAMESPACE_PREFIX_SOAP, NAMESPACE_PREFIX_SOAP_DEF);
                        envelope.addNamespaceDeclaration(NAMESPACE_PREFIX_V2, NAMESPACE_PREFIX_V2_DEF);
                        envelope.addNamespaceDeclaration(NAMESPACE_PREFIX_WSSE, NAMESPACE_PREFIX_WSSE_DEF);

                        final SoapHeaderElement toElem = soapHeader.addHeaderElement(new QName(NAMESPACE_PREFIX_ADDRESSING, "To"));
                        toElem.setText(TO_VALUE);

                        final SoapHeaderElement actionElem = soapHeader.addHeaderElement(new QName(NAMESPACE_PREFIX_ADDRESSING, "Action"));
                        actionElem.setText(NAMESPACE_PREFIX_V2_DEF + "/AbcService/" + actionStr + "Request");

                        final SoapHeaderElement messageIdElem = soapHeader.addHeaderElement(new QName(NAMESPACE_PREFIX_ADDRESSING, "MessageID"));
                        messageIdElem.setText(MESSAGE_ID_VALUE + UUID.randomUUID());

                        final SoapHeaderElement stageElem = soapHeader.addHeaderElement(new QName(NAMESPACE_PREFIX_VWA, "Stage"));
                        stageElem.setText("Production");

                        final NodeList nl = ssMessage.getSaajMessage().getSOAPPart().getEnvelope().getBody().getChildNodes();

                        ssMessage.getSaajMessage().getSOAPPart().getEnvelope().getBody().removeChild(nl.item(0));
                        final SOAPElement se = ssMessage.getSaajMessage().getSOAPPart().getEnvelope().getBody().addBodyElement(new QName(actionStr));
                        se.setPrefix(NAMESPACE_PREFIX_V2);
                        final SOAPElement userAuthElem = se.addChildElement(new QName("UserAuthentification"));
                        final SOAPElement userIdElem = userAuthElem.addChildElement("UserId");
                        userIdElem.setTextContent(kpmConfiguration.getCredentials().getUsername());
                    System.out.println(userIdElem.getTextContent());
                    Transformer transformer = TransformerFactory.newInstance().newTransformer();
                    transformer.transform(ssMessage.getPayloadSource(), soapHeader.getResult());
                    } catch (Exception e) {
                        logger.error("Error during marshalling of the SOAP headers", e);
                    }
                }
            });
    return gsiResponse.getValue();
}

但是,当我从 SpringBoot 应用程序提交请求时,我总是会遇到异常:

java.net.SocketException: Unexpected end of file from server

我在代码中遗漏了什么吗?

标签: spring-bootsoapheaderunexpectendoffile

解决方案


请参阅已编辑问题中上述原始问题的答案。关于java.net.SocketException: Unexpected end of file from server它似乎来自通过 Eclipse 的 TCP/IP 监视器重定向请求。将请求直接发送到服务器时,我得到了一个有意义的响应:

INFO_001 方法成功执行

:-)


推荐阅读