我正在开发春季网络服务。我需要在请求和响应消息中添加一些自定义元素。它应该如下所示:
<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>
我可以通过修改WSDL文件在请求<tid:SplsTID>
下附加<soapenv:Header>
。看起来像这样:
<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>
问题是,我想从请求中读取<tid:SplsTID>
部分,并希望将其附加到响应的soap标题部分,这是没有发生的。我正在使用基于注释的终点。什么是读取soap标头的代码,并在响应中附加相同的内容。
目前我的终点课程是:
@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;
}
}
如果需要更多详细信息,请与我们联系。任何帮助将不胜感激。
答案 0 :(得分:12)
最后,我成功地从请求中读取了soap标头并附加到响应中。这就是我的终点方法现在的样子:
@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;
}
答案 1 :(得分:3)
这可能只是你需要的答案的一半,但我认为你可以通过从messagecontext获取(Saaj)SoapMessage来阅读soapheaders,如下所示:
@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
一样。我用它来从soap消息中获取附件。您可以使用AbstractSoapMessage
的其他子类,因为getSoapHeder
方法在该类中。
[编辑] BTW:也许您可以使用拦截器,因为那里提供了请求/响应。有些默认示例,请查看org.springframework.ws.soap.server.endpoint.interceptor包。 [/编辑]
答案 2 :(得分:0)
如果使用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;
}