CXF:将隐式 headers 添加到 CXF SOAP/REST Web 服务的 WSDL 和 WADL 响应
CXF: Add implicit headers to WSDL and WADL responses for a CXF SOAP/REST web service
我正在尝试向 CXF SOAP/REST Web 服务(由 Camel 管理)的 WSDL 和 WADL 响应添加隐式 headers。
(这些不一定是安全的headers....)
"implicit header" 我的意思是,点击服务的 WSDL/WADL URL 将表明客户端希望在请求中提供 header。
但我不想在 Web 服务的签名中明确指定 header。
我有一个 CXF 拦截器,它向每个 SOAP/REST 响应添加隐式 header。
因此,由于 WSDL/WADL 文档是作为对某些 GET 请求的响应发送的,我想以某种方式使用类似的拦截器将 header 数据添加到 WSDL/WADL 响应。我怎么能做出如此惊人的壮举?
这是为每个 SOAP/REST 响应添加隐式 header 的 CXF 拦截器:
public class MyInterceptor extends AbstractPhaseInterceptor<Message> {
public MyInterceptor()
{
super(Phase.RECEIVE);
}
@Override
public void handleMessage(Message message)
{
try
{
//soap
if (message instanceof SoapMessage)
{
List<Header> headers = ((SoapMessage)message).getHeaders();
Header dummyHeader = new Header(new QName("uri:org.apache.cxf", "dummy"), "decapitated", new JAXBDataBinding(String.class));
headers.add(dummyHeader);
}
//rest
else
{
Map<String, List> headers = (Map<String, List>) message.get(Message.PROTOCOL_HEADERS);
String dummyHeader = "decapitated";
headers.put("dummy", Collections.singletonList(dummyHeader));
}
}
catch (JAXBException e)
{
throw new Fault(e);
}
}
@Override
public void handleFault(Message messageParam)
{
}
}
CXF 2.7.4
在 CXF 中,WSDL 是通过链中称为 WSDLGetInterceptor
的拦截器生成的,它位于 READ
链中。
它的基本设计是
- 检查调用是否为 HTTP GET
- 准备输出消息到 return
- 访问 wsdl(来自 Java 或静态资源)
- 将 wsdl 写入输出消息
- 中断拦截器链以提供输出消息
处理此进程的最简单方法是抢占此拦截器的工作,方法是先注册您自己的实现。
删除标准 CXF 拦截器是默认总线上的一种 "hard thing to do"(最简单的方法是注册您自己的拦截器,将其放在链中的第一位,然后像这样删除其他拦截器 message.getInterceptorChain().remove(removeInterceptor);
但是在标准 WSDL 拦截器之前添加您自己的拦截器很容易:
public MyWSDLGetInterceptor() {
super(Phase.READ);
addBefore(WSDLGetInterceptor.class.getName());
}
MyWSDLGetInterceptor
会扩展标准 WSDLGetInterceptor
而你只会覆盖 :
public Document getDocument(Message message,
String base,
Map<String, String> params,
String ctxUri,
EndpointInfo endpointInfo) {
Document domDocument = super.getDocument(message, base, params, ctxUri, endpointInfo);
domDocument.getChildNodes(); // Whatever you need to add remove
return domDocument; // Once modified
}
您可以即时修改生成的 DOM 文档(添加/创建 DOM 节点)或通过 XSLT,无论哪种最适合您,您都可以回到处理标准 XML 通过标准 API.
CXF 2.7.x(其中 x 大于 4 且小于 10)
原理是一样的,只是拦截器的作用不同
- 它(在私有方法中)将 WSDL 作为 DOM 文档作为输出消息 属性
- 它清除所有拦截器的输出拦截器链(绝对必要的除外)
- 它在输出链
中注册了一个WSDLGetOutInterceptor
- 它停止IN链并进行到停止链
WSDLGetOutInterceptor
执行其序列化工作
所以有点难/不太干净。但是使用抢占基本拦截器的相同原则(之前注册自己),您可以覆盖 cleanUpOutInteceptors
来操作消息,就像在 2.7.4 中一样,通过 [=20 访问 WSDL =]
WADL
抱歉,我没有专业知识,但我想 CXF 对这两种架构都有相同的架构...
我正在尝试向 CXF SOAP/REST Web 服务(由 Camel 管理)的 WSDL 和 WADL 响应添加隐式 headers。
(这些不一定是安全的headers....)
"implicit header" 我的意思是,点击服务的 WSDL/WADL URL 将表明客户端希望在请求中提供 header。
但我不想在 Web 服务的签名中明确指定 header。
我有一个 CXF 拦截器,它向每个 SOAP/REST 响应添加隐式 header。
因此,由于 WSDL/WADL 文档是作为对某些 GET 请求的响应发送的,我想以某种方式使用类似的拦截器将 header 数据添加到 WSDL/WADL 响应。我怎么能做出如此惊人的壮举?
这是为每个 SOAP/REST 响应添加隐式 header 的 CXF 拦截器:
public class MyInterceptor extends AbstractPhaseInterceptor<Message> {
public MyInterceptor()
{
super(Phase.RECEIVE);
}
@Override
public void handleMessage(Message message)
{
try
{
//soap
if (message instanceof SoapMessage)
{
List<Header> headers = ((SoapMessage)message).getHeaders();
Header dummyHeader = new Header(new QName("uri:org.apache.cxf", "dummy"), "decapitated", new JAXBDataBinding(String.class));
headers.add(dummyHeader);
}
//rest
else
{
Map<String, List> headers = (Map<String, List>) message.get(Message.PROTOCOL_HEADERS);
String dummyHeader = "decapitated";
headers.put("dummy", Collections.singletonList(dummyHeader));
}
}
catch (JAXBException e)
{
throw new Fault(e);
}
}
@Override
public void handleFault(Message messageParam)
{
}
}
CXF 2.7.4
在 CXF 中,WSDL 是通过链中称为 WSDLGetInterceptor
的拦截器生成的,它位于 READ
链中。
它的基本设计是
- 检查调用是否为 HTTP GET
- 准备输出消息到 return
- 访问 wsdl(来自 Java 或静态资源)
- 将 wsdl 写入输出消息
- 中断拦截器链以提供输出消息
处理此进程的最简单方法是抢占此拦截器的工作,方法是先注册您自己的实现。
删除标准 CXF 拦截器是默认总线上的一种 "hard thing to do"(最简单的方法是注册您自己的拦截器,将其放在链中的第一位,然后像这样删除其他拦截器 message.getInterceptorChain().remove(removeInterceptor);
但是在标准 WSDL 拦截器之前添加您自己的拦截器很容易:
public MyWSDLGetInterceptor() {
super(Phase.READ);
addBefore(WSDLGetInterceptor.class.getName());
}
MyWSDLGetInterceptor
会扩展标准 WSDLGetInterceptor
而你只会覆盖 :
public Document getDocument(Message message,
String base,
Map<String, String> params,
String ctxUri,
EndpointInfo endpointInfo) {
Document domDocument = super.getDocument(message, base, params, ctxUri, endpointInfo);
domDocument.getChildNodes(); // Whatever you need to add remove
return domDocument; // Once modified
}
您可以即时修改生成的 DOM 文档(添加/创建 DOM 节点)或通过 XSLT,无论哪种最适合您,您都可以回到处理标准 XML 通过标准 API.
CXF 2.7.x(其中 x 大于 4 且小于 10)
原理是一样的,只是拦截器的作用不同
- 它(在私有方法中)将 WSDL 作为 DOM 文档作为输出消息 属性
- 它清除所有拦截器的输出拦截器链(绝对必要的除外)
- 它在输出链 中注册了一个
- 它停止IN链并进行到停止链
WSDLGetOutInterceptor
执行其序列化工作
WSDLGetOutInterceptor
所以有点难/不太干净。但是使用抢占基本拦截器的相同原则(之前注册自己),您可以覆盖 cleanUpOutInteceptors
来操作消息,就像在 2.7.4 中一样,通过 [=20 访问 WSDL =]
WADL
抱歉,我没有专业知识,但我想 CXF 对这两种架构都有相同的架构...