如何从请求中读取 SOAP 标头信息并将其添加到 Spring Web 服务中的响应中

发布于 2024-12-21 12:32:04 字数 3578 浏览 0 评论 0原文

我正在研究 Spring Web 服务。我需要在请求和响应消息中添加一些自定义元素。它应该如下所示:

<soapenv:Envelope>
   <soapenv:Header>
      <tid:SplsTID>
         <tid:Trantype>123</tid:Trantype>
         <tid:Tranver>234</tid:Tranver>
      </tid:SplsTID>
   </soapenv:Header>
   <soapenv:Body>
      <get:GetOrderNumberRequest LoggingLevel="REGULAR" MonitorFlag="Y">
         <get:Header>
            <get:TransactionId>111</get:TransactionId>
            <get:SourceSystemId>SOMS</get:SourceSystemId>
            <get:DateTime>2011-11-11T11:11:11</get:DateTime>
         </get:Header>
         <get:Body>
            <get:StaplesOrderNumber RangeFlag="N" ReleaseFlag="N">
               <get:OrderNumber Count="1" End="11" Start="9"/>
            </get:StaplesOrderNumber>
         </get:Body>
      </get:GetOrderNumberRequest>
   </soapenv:Body>
</soapenv:Envelope>

我能够在 下附加 code> 通过修改 WSDL 文件来请求。看起来像这样:

<wsdl:message name="GetOrderNumberRequest">
        <wsdl:part element="tns:GetOrderNumberRequest" name="GetOrderNumberRequest">
        </wsdl:part>
        <wsdl:part element="sch1:SplsTID" name="SplsTID">
        </wsdl:part>
    </wsdl:message>
    <wsdl:message name="GetOrderNumberResponse">
        <wsdl:part element="tns:GetOrderNumberResponse" name="GetOrderNumberResponse">
        </wsdl:part>
        <wsdl:part element="sch1:SplsTID" name="SplsTID">
        </wsdl:part>
    </wsdl:message>
    <wsdl:portType name="ONAS">
        <wsdl:operation name="GetOrderNumber">
            <wsdl:input message="tns:GetOrderNumberRequest" name="GetOrderNumberRequest">
            </wsdl:input>
            <wsdl:output message="tns:GetOrderNumberResponse" name="GetOrderNumberResponse">
            </wsdl:output>
        </wsdl:operation>
    </wsdl:portType>

问题是,我想读取请求中的 部分,并希望将其附加到响应的肥皂头部分下,但这没有发生。我正在使用基于注释的端点。将读取肥皂头并将其附加到响应中的代码是什么。

目前我的终点课程是:

@Endpoint
public class OrderNumberServiceEndPoint {
    public static final String NAMESPACE_URI = "http://schemas.staples.com/onas/getOrderNumber";

    /**
     * The local name of the expected request.
     */
    public static final String REQUEST_LOCAL_NAME = "GetOrderNumberRequest";

    /**
     * The local name of the created response.
     */
    public static final String RESPONSE_LOCAL_NAME = "GetOrderNumberResponse";

    private GetOrderNumberService getOrderNumberService;

    public void setGetOrderNumberService(
            GetOrderNumberService getOrderNumberService) {
        this.getOrderNumberService = getOrderNumberService;
    }

    @PayloadRoot(localPart = REQUEST_LOCAL_NAME, namespace = NAMESPACE_URI)
    public GetOrderNumberResponse processOrderNumberRequest(
            GetOrderNumberRequest request) throws Exception {
        GetOrderNumberResponse response = null;
        try{
        response = getOrderNumberService.executeRequest(request);
        }catch(CannotCreateTransactionException e){
            logger.error(ErrorConstants.ERROR_E17);
            throw new ServiceException(ErrorConstants.ERROR_E17);
        }
        return response;
    }

}

如果需要更多详细信息,请告诉我。任何帮助将不胜感激。

I am working on spring web services. I need to add some custom elements in the request and response message.which should look like this:

<soapenv:Envelope>
   <soapenv:Header>
      <tid:SplsTID>
         <tid:Trantype>123</tid:Trantype>
         <tid:Tranver>234</tid:Tranver>
      </tid:SplsTID>
   </soapenv:Header>
   <soapenv:Body>
      <get:GetOrderNumberRequest LoggingLevel="REGULAR" MonitorFlag="Y">
         <get:Header>
            <get:TransactionId>111</get:TransactionId>
            <get:SourceSystemId>SOMS</get:SourceSystemId>
            <get:DateTime>2011-11-11T11:11:11</get:DateTime>
         </get:Header>
         <get:Body>
            <get:StaplesOrderNumber RangeFlag="N" ReleaseFlag="N">
               <get:OrderNumber Count="1" End="11" Start="9"/>
            </get:StaplesOrderNumber>
         </get:Body>
      </get:GetOrderNumberRequest>
   </soapenv:Body>
</soapenv:Envelope>

i am able to append <tid:SplsTID> under <soapenv:Header> in request by modifying the WSDL file. which looks like this:

<wsdl:message name="GetOrderNumberRequest">
        <wsdl:part element="tns:GetOrderNumberRequest" name="GetOrderNumberRequest">
        </wsdl:part>
        <wsdl:part element="sch1:SplsTID" name="SplsTID">
        </wsdl:part>
    </wsdl:message>
    <wsdl:message name="GetOrderNumberResponse">
        <wsdl:part element="tns:GetOrderNumberResponse" name="GetOrderNumberResponse">
        </wsdl:part>
        <wsdl:part element="sch1:SplsTID" name="SplsTID">
        </wsdl:part>
    </wsdl:message>
    <wsdl:portType name="ONAS">
        <wsdl:operation name="GetOrderNumber">
            <wsdl:input message="tns:GetOrderNumberRequest" name="GetOrderNumberRequest">
            </wsdl:input>
            <wsdl:output message="tns:GetOrderNumberResponse" name="GetOrderNumberResponse">
            </wsdl:output>
        </wsdl:operation>
    </wsdl:portType>

The problem is, i want to read <tid:SplsTID> part from the request and wanted to append it under soap header part of the response, which is not happening. i am using annotation based end point. what is the code which will read the soap header and will append the same in the response.

currently my end point class is:

@Endpoint
public class OrderNumberServiceEndPoint {
    public static final String NAMESPACE_URI = "http://schemas.staples.com/onas/getOrderNumber";

    /**
     * The local name of the expected request.
     */
    public static final String REQUEST_LOCAL_NAME = "GetOrderNumberRequest";

    /**
     * The local name of the created response.
     */
    public static final String RESPONSE_LOCAL_NAME = "GetOrderNumberResponse";

    private GetOrderNumberService getOrderNumberService;

    public void setGetOrderNumberService(
            GetOrderNumberService getOrderNumberService) {
        this.getOrderNumberService = getOrderNumberService;
    }

    @PayloadRoot(localPart = REQUEST_LOCAL_NAME, namespace = NAMESPACE_URI)
    public GetOrderNumberResponse processOrderNumberRequest(
            GetOrderNumberRequest request) throws Exception {
        GetOrderNumberResponse response = null;
        try{
        response = getOrderNumberService.executeRequest(request);
        }catch(CannotCreateTransactionException e){
            logger.error(ErrorConstants.ERROR_E17);
            throw new ServiceException(ErrorConstants.ERROR_E17);
        }
        return response;
    }

}

Let me know if more details are required. Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

七色彩虹 2024-12-28 12:32:04

最后我成功地从请求中读取肥皂头并附加到响应中。这就是我的终点方法现在的样子:

 @PayloadRoot(localPart = REQUEST_LOCAL_NAME, namespace = NAMESPACE_URI)
    @ResponsePayload
    public GetOrderNumberResponse processOrderNumberRequest(
            @RequestPayload GetOrderNumberRequest request,
            MessageContext messageContext) throws Exception {
        logger.info("Request Received");
        // read SOAP Header from request and append in response
        SaajSoapMessage soapRequest = (SaajSoapMessage) messageContext
                .getRequest();
        SoapHeader reqheader = soapRequest.getSoapHeader();
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext
                .getResponse();
        SoapHeader respheader = soapResponse.getSoapHeader();
        TransformerFactory transformerFactory = TransformerFactory
                .newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        Iterator<SoapHeaderElement> itr = reqheader.examineAllHeaderElements();
        while (itr.hasNext()) {
            SoapHeaderElement ele = itr.next();
            transformer.transform(ele.getSource(), respheader.getResult());
        }
        // process the request PayLoad
        GetOrderNumberResponse response = null;
        try {
            response = getOrderNumberService.executeRequest(request);
        } catch (CannotCreateTransactionException e) {
            logger.error(ErrorConstants.ERROR_E17);
            throw new ServiceException(ErrorConstants.ERROR_E17);
        }
        logger.info("Response Sent");
        return response;
    }

Finally i succeeded in reading the soap header from request and append into response. This is how my end point method looks like now:

 @PayloadRoot(localPart = REQUEST_LOCAL_NAME, namespace = NAMESPACE_URI)
    @ResponsePayload
    public GetOrderNumberResponse processOrderNumberRequest(
            @RequestPayload GetOrderNumberRequest request,
            MessageContext messageContext) throws Exception {
        logger.info("Request Received");
        // read SOAP Header from request and append in response
        SaajSoapMessage soapRequest = (SaajSoapMessage) messageContext
                .getRequest();
        SoapHeader reqheader = soapRequest.getSoapHeader();
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext
                .getResponse();
        SoapHeader respheader = soapResponse.getSoapHeader();
        TransformerFactory transformerFactory = TransformerFactory
                .newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        Iterator<SoapHeaderElement> itr = reqheader.examineAllHeaderElements();
        while (itr.hasNext()) {
            SoapHeaderElement ele = itr.next();
            transformer.transform(ele.getSource(), respheader.getResult());
        }
        // process the request PayLoad
        GetOrderNumberResponse response = null;
        try {
            response = getOrderNumberService.executeRequest(request);
        } catch (CannotCreateTransactionException e) {
            logger.error(ErrorConstants.ERROR_E17);
            throw new ServiceException(ErrorConstants.ERROR_E17);
        }
        logger.info("Response Sent");
        return response;
    }
掩于岁月 2024-12-28 12:32:04

这可能只是您需要的答案的一半,但我认为您可以通过从消息上下文获取 (Saaj)SoapMessage 来读取肥皂头,如下所示:

@PayloadRoot(
    localPart = "GetHiredCandidatesRequest", 
    namespace = DEFAULT_NAMESPACE
)
@ResponsePayload
public GetHiredCandidatesResponse getKandidaat (
    @RequestPayload GetHiredCandidatesRequest getCandidate,
    MessageContext messageContext) {

    SaajSoapMessage request = (SaajSoapMessage) messageContext.getRequest();
    SoapHeader header = request.getSoapHeader();

    GetHiredCandidatesResponse response = objectFactory.createGetHiredCandidatesResponse();
    response.getCandidate().addAll(
        candidateService.getHiredCandidates(
            getCandidate.getFrom(), 
            getCandidate.getTo()
        )
    );

    return response;
}

从版本 2 开始,您可以自动“添加”一些对象到您的方法的签名中,就像我添加的那样这里的MessageContext。例如,我用它来从肥皂消息中获取附件。您也可以使用 AbstractSoapMessage 的其他子类,因为 getSoapHeder 方法位于该类中。

[编辑]
顺便说一句:也许您也可以使用拦截器,因为那里提供了请求/响应。查看 org.springframework.ws.soap.server.endpoint.interceptor 包中的一些默认示例。
[/编辑]

This is probably only half the answer you need but I think you can read the soapheaders by getting the (Saaj)SoapMessage from the messagecontext, like this:

@PayloadRoot(
    localPart = "GetHiredCandidatesRequest", 
    namespace = DEFAULT_NAMESPACE
)
@ResponsePayload
public GetHiredCandidatesResponse getKandidaat (
    @RequestPayload GetHiredCandidatesRequest getCandidate,
    MessageContext messageContext) {

    SaajSoapMessage request = (SaajSoapMessage) messageContext.getRequest();
    SoapHeader header = request.getSoapHeader();

    GetHiredCandidatesResponse response = objectFactory.createGetHiredCandidatesResponse();
    response.getCandidate().addAll(
        candidateService.getHiredCandidates(
            getCandidate.getFrom(), 
            getCandidate.getTo()
        )
    );

    return response;
}

Since version 2 you can automatically 'add' some objects to your method's signature, like I add the MessageContext here. I have used this to get the attachments from a soap message for instance. You can probably use other subclasses of AbstractSoapMessage as well since the the getSoapHeder method is in that class.

[edit]
BTW: Perhaps you can use Interceptors as well since the request / response is provided there. Take a look at the org.springframework.ws.soap.server.endpoint.interceptor package for some default examples.
[/edit]

梦在夏天 2024-12-28 12:32:04

如果您使用 jaxb marshaller,会容易得多。如果主体和标头具有不同的命名空间,则此操作有效。

import org.springframework.ws.soap.server.endpoint.annotation.SoapHeader;//@SoapHeader

@PayloadRoot(namespace = "http://body.namespace", localPart = "getRequest")
@ResponsePayload
public JAXBElement<GetResponse> getSomething(@RequestPayload JAXBElement<GetRequest> request
        //SOAPHeader is element name from header.xsd: <xsd:element name="SOAPHeader" type="tns:HeaderType"/>
        ,@SoapHeader(value = "{http://namespace.x.com/Header/}SOAPHeader") SoapHeaderElement headerElem
        ,MessageContext messageContext) {

    try {
        JAXBContext context = JAXBContext.newInstance(HeaderType.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();

        //get soapheader from request
        DOMSource headerSource = (DOMSource) headerElem.getSource();
        //unmarshall to HeaderType object, headerSource.getNode() because header has different namespace from body namespace
        //HeaderType is an xml annotated class
        HeaderType headerRequest = ((JAXBElement<HeaderType>) unmarshaller.unmarshal(headerSource.getNode(), HeaderType.class)).getValue();

        //get soapheader from response
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
        org.springframework.ws.soap.SoapHeader soapResponseHeader = soapResponse.getSoapHeader();

        //marshall headerRequest to response soapheader
        Marshaller marshaller = context.createMarshaller();
        marshaller.marshal(headerRequest, soapResponseHeader.getResult());
    } catch (JAXBException e) {
        e.printStackTrace();
    }

    //create response body message
    ObjectFactory objectFactory = new ObjectFactory();
    JAXBElement<GetResponse> response = objectFactory.createGetResponse(new GetResponse());
    response.getValue().setErrorMessage("ok");

    return response;
}

Much easier if you using jaxb marshaller. And this working if body and header has different namespace.

import org.springframework.ws.soap.server.endpoint.annotation.SoapHeader;//@SoapHeader

@PayloadRoot(namespace = "http://body.namespace", localPart = "getRequest")
@ResponsePayload
public JAXBElement<GetResponse> getSomething(@RequestPayload JAXBElement<GetRequest> request
        //SOAPHeader is element name from header.xsd: <xsd:element name="SOAPHeader" type="tns:HeaderType"/>
        ,@SoapHeader(value = "{http://namespace.x.com/Header/}SOAPHeader") SoapHeaderElement headerElem
        ,MessageContext messageContext) {

    try {
        JAXBContext context = JAXBContext.newInstance(HeaderType.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();

        //get soapheader from request
        DOMSource headerSource = (DOMSource) headerElem.getSource();
        //unmarshall to HeaderType object, headerSource.getNode() because header has different namespace from body namespace
        //HeaderType is an xml annotated class
        HeaderType headerRequest = ((JAXBElement<HeaderType>) unmarshaller.unmarshal(headerSource.getNode(), HeaderType.class)).getValue();

        //get soapheader from response
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
        org.springframework.ws.soap.SoapHeader soapResponseHeader = soapResponse.getSoapHeader();

        //marshall headerRequest to response soapheader
        Marshaller marshaller = context.createMarshaller();
        marshaller.marshal(headerRequest, soapResponseHeader.getResult());
    } catch (JAXBException e) {
        e.printStackTrace();
    }

    //create response body message
    ObjectFactory objectFactory = new ObjectFactory();
    JAXBElement<GetResponse> response = objectFactory.createGetResponse(new GetResponse());
    response.getValue().setErrorMessage("ok");

    return response;
}
内心激荡 2024-12-28 12:32:04

我正在使用 SoapUI 设置标头并尝试在我的 Spring Boot Soap Web 服务中检索它们。
上述方法对我没有帮助。但我能够将它们作为 MimeHeaders 检索。

//You can simply inject MessageContext. It is Spring's MessageContext, so do not use Xml or Jakarta MessageContext. Only use Spring MessageContext
    @PayloadRoot(namespace="http://anyuriyouwant.com", localPart="getEmployeeRequest")
@ResponsePayload public JAXBElement<Employee> getEmpDetails(@RequestPayload JAXBElement<String>empCode, MessageContext messageContext){
        SaajSoapMessage request=(SaajSoapMessage) messageContext.getRequest();
        MimeHeaders headers=request.getSaajMessage().getMimeHeaders();
        String appId=headers.getHeader("your-header-name")[0];
        System.out.println("App Id from headers: "+appId);
    }

I was setting my headers using SoapUI and trying to retrieve them in my Spring Boot Soap Web Service.
Above mentioned ways did not help me. But I was able to retrieve them as MimeHeaders.

//You can simply inject MessageContext. It is Spring's MessageContext, so do not use Xml or Jakarta MessageContext. Only use Spring MessageContext
    @PayloadRoot(namespace="http://anyuriyouwant.com", localPart="getEmployeeRequest")
@ResponsePayload public JAXBElement<Employee> getEmpDetails(@RequestPayload JAXBElement<String>empCode, MessageContext messageContext){
        SaajSoapMessage request=(SaajSoapMessage) messageContext.getRequest();
        MimeHeaders headers=request.getSaajMessage().getMimeHeaders();
        String appId=headers.getHeader("your-header-name")[0];
        System.out.println("App Id from headers: "+appId);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文