spring - Spring WS - 寻找请求标头/有效负载和响应标头/有效负载示例
问题描述
我需要使用 Spring Framework 开发 Web 服务。场景是这样的:
我的程序将向服务发送 SOAP 请求(标头 + 有效负载),并期望从服务返回响应(标头 + 有效负载)。有效负载和标头都很重要,并且程序需要。
问题是我在 Spring WS 中找不到任何示例,其中标头和有效负载都是作为请求的一部分发送的,而标头和有效负载是从响应中提取的。
我正在使用WebServiceGatewaySupport
andWebServiceTemplate
发送请求和获取响应。
WebServiceTemplate
提供2种发送请求的方法:
marshalSendAndReceive
sendAndReceive
问题marshalSendAndReceive
是尽管我可以发送请求标头,但我不会取回响应标头。
问题sendAndReceive
是我将无法发送请求标头,尽管我将能够提取响应标头。
目前唯一可用的解决方案是使用拦截器,但似乎这不是处理标头的正确方法,因为标头在到达调用函数之前被拦截。为了让调用函数访问响应头,我们需要将拦截器设置为有状态,这是不可取的。
我将非常感谢任何可以为我提供如何正确实现这一目标的示例的人的指导和帮助。
使用 sendAndReceive 时,请在下面找到我的代码:
public class ClientAccountInformation extends WebServiceGatewaySupport {
public ClientAccountInformation() {
}
public FIGetAcctsInfoCallBackRs sendRequest(GetAcctInfoRq request, HeaderRq headerRq) {
WebServiceTemplate webServiceTemplate = getWebServiceTemplate();
try {
ResponseAndHeader responseAndHeader = webServiceTemplate.sendAndReceive(Constants.WEBSERVICE_URL,
new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) throws IOException {
try {
Jaxb2Marshaller marshallerRq = new Jaxb2Marshaller();
marshallerRq.setContextPath("com.abc.domain..getacctinfo");
marshallerRq.afterPropertiesSet();
MarshallingUtils.marshal(marshallerRq, request, message);
SoapHeader soapHeader = ((SoapMessage)message).getSoapHeader();
JAXBContext context = JAXBContext.newInstance(HeaderRq.class);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(HeaderRq, soapHeader.getResult());
} catch (Exception e) {
e.printStackTrace();
}
}
},
new WebServiceMessageExtractor<ResponseAndHeader>() {
public ResponseAndHeader extractData(WebServiceMessage message) throws IOException {
SoapHeader header = ((SoapMessage)message).getSoapHeader();
Iterator<SoapHeaderElement> it = header.examineHeaderElements(new QName("urn:test", "HeaderRs"));
return new ResponseAndHeader(
it.hasNext() ? (HeaderRs)jaxb2Marshaller().unmarshal(it.next().getSource())
: null,
(GetAcctInfoRs) MarshallingUtils.unmarshal(jaxb2Marshaller(), message));
}
});
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Jaxb2Marshaller jaxb2Marshaller() {
Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
jaxb2Marshaller.setContextPath("com.abc.domain.getacctinfo");
return jaxb2Marshaller;
}
}
上面的代码总是为响应头返回 null。
解决方案
我已经解决了这个问题。我可以将 SOAP 标头发送到服务并从响应中提取响应标头。不需要拦截器。
主要帮助来自 Andreas Veithen 的博客文章。谢谢。
public class ClientSamaAccountInformation extends WebServiceGatewaySupport {
public ClientSamaAccountInformation() {
}
public FIGetAcctsInfoCallBackRs sendRequest(FIGetAcctsInfoCallBackRq request, MsgHdrRq msgHdrRq) {
WebServiceTemplate webServiceTemplate = getWebServiceTemplate();
try {
ResponseAndHeader responseAndHeader = webServiceTemplate.sendAndReceive(Constants.WEBSERVICE_URL,
new WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) throws IOException {
try {
Jaxb2Marshaller marshallerRq = new Jaxb2Marshaller();
marshallerRq.setContextPath("com.abc.domain..getacctinfo");
marshallerRq.afterPropertiesSet();
MarshallingUtils.marshal(marshallerRq, request, message);
SoapHeader soapHeader = ((SoapMessage)message).getSoapHeader();
JAXBContext context = JAXBContext.newInstance(MsgHdrRq.class);
Marshaller marshaller = context.createMarshaller();
marshaller.marshal(msgHdrRq, soapHeader.getResult());
} catch (Exception e) {
e.printStackTrace();
}
}
},
new WebServiceMessageExtractor<ResponseAndHeader>() {
public ResponseAndHeader extractData(WebServiceMessage message) throws IOException {
//Extract response payload
FIGetAcctsInfoCallBackRs response = null;
try {
Jaxb2Marshaller marshallerRs = new Jaxb2Marshaller();
marshallerRs.setContextPath("com.abc.domain..getacctinfo");
marshallerRs.afterPropertiesSet();
response = (FIGetAcctsInfoCallBackRs) MarshallingUtils.unmarshal(marshallerRs, message);
} catch (Exception e) {
e.printStackTrace();
}
//Extract response header
MsgHdrRs msgHdrRs = null;
try {
JAXBContext context = JAXBContext.newInstance(MsgHdrRs.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
SoapHeader header = ((SoapMessage)message).getSoapHeader();
Iterator<SoapHeaderElement> it = header.examineHeaderElements(new QName("http://www.abc.def.com/common/Header", "MsgHdrRs"));
while(it.hasNext()) {
msgHdrRs = (MsgHdrRs) unmarshaller.unmarshal(it.next().getSource());
System.out.println(msgHdrRs);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
推荐阅读
- angular - 如何将参数传递给canActivate的构造函数?
- java - 春天。访问 Thymeleaf 中的配置变量。
- javascript - 查找表 TD 值
- javascript - 如何在共享点 Web 部件中添加内联 JS/HTML 代码
- reactjs - 如何在热模式下使用 webpack
- firebase - 单个照片路径进入多个 HashMap 元素
- java - Regex java用于提取第一个字母字符的正则表达式
- postgresql - PostgreSQL:第一次日期累积分数
- google-apps-script - 从 Google 电子表格访问 Google 脚本中的存储值
- google-nearby - 附近发送的文件打不开