CXF:为CXF SOAP/REST web服务的WSDL和WADL响应添加隐式标头



我正在尝试为CXF SOAP/REST web服务(由Camel管理)的WSDL和WADL响应添加隐式标头。

(这些不一定是安全标头……)

所谓"隐式标头",我的意思是,点击服务的WSDL/WADL URL将表明客户端需要在请求中提供标头。

但我不想在web服务的签名中明确指定头。

我有一个CXF拦截器,它为每个SOAP/REST响应添加了一个隐式标头。

因此,由于WSDL/WDL文档是作为对某个GET请求的响应发送的,所以我想以某种方式使用类似的拦截器将头数据添加到WSDL/WADL响应中。我怎么能完成如此了不起的壮举?

以下是CXF拦截器,它为每个SOAP/REST响应添加了一个隐式标头:

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是通过位于READ链中的名为WSDLGetInterceptor的内链中的拦截器生成的。

它的基本设计是

  1. 检查调用是否为HTTP GET
  2. 准备要返回的输出消息
  3. 访问wsdl(从Java或静态资源)
  4. 将wsdl写入输出消息
  5. 中断拦截器链以提供输出消息

对这个过程采取行动的最简单方法是抢占这个拦截器的工作,或者之前注册自己的实现。

在默认总线上删除标准CXF拦截器是一件"很难做到的事"(最简单的方法是注册自己的拦截器,将其放在链中的第一位,并使其删除其他拦截器,如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修改,无论什么最适合您,都可以通过标准的API处理标准的XML。

CXF 2.7.x(其中x在某个位置>4且<10)

主体是相同的,但拦截器的工作方式不同。

  1. 它(在私有方法中)将WSDL作为DOM文档作为输出消息属性
  2. 它清除所有拦截器的输出拦截器链(绝对必要的除外)
  3. 它在输出链中注册一个WSDLGetOutInterceptor
  4. 它停止IN链并进入停止链
  5. WSDLGetOutInterceptor完成其序列化工作

所以它有点难/不太干净。但是,使用抢占基本拦截器的相同原理(之前刚刚注册),您可以覆盖cleanUpOutInteceptors来操作消息,就像在2.7.4中一样,通过outMessage.get(DOCUMENT_HOLDER)访问WSDL

WADL

对不起,我没有专业知识,但我想CXF对两者都有相同的体系结构。。。

最新更新