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

时间:2015-04-13 16:35:08

标签: java web-services rest soap cxf

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

(这些不一定是安全标题....)

隐含标题"我的意思是,点击服务的WSDL / WADL URL将表明客户希望在请求中提供标题。

但我不想在Web服务的签名中明确指定标题。

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

因此,由于WSDL / WADL文档是作为对某些GET请求的响应而发送的,所以我想以某种方式使用类似的拦截器将头数据添加到WSDL / WADL响应中。我怎么能进行这样一个奇妙的壮举?

以下是为每个SOAP / REST响应添加隐式标头的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)
    {
    }
}

1 个答案:

答案 0 :(得分:7)

CXF 2.7.4

在CXF中,WSDL是通过名为WSDLGetInterceptor的in链中的Interceptor生成的,它位于READ链中。

它的基本设计是

  1. 检查呼叫是否为HTTP GET
  2. 准备输出消息以返回
  3. 访问wsdl(来自Java或来自静态资源)
  4. 将wsdl写入输出消息
  5. 中断拦截器链以提供输出消息
  6. 采取行动的最简单方法是抢先拦截这个拦截器,无论是之前注册自己的实现。

    删除标准的CXF拦截器是一件很难做的事情&#34;在一个默认的总线上(最简单的方法是注册你自己的拦截器,把它放在链中的第一个,并让它删除其他拦截器,如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 Document作为out消息属性
    2. 它清除所有拦截器的输出拦截器链(绝对必要除外)
    3. 在输出链中注册WSDLGetOutInterceptor
    4. 停止IN链并进入停止链
    5. WSDLGetOutInterceptor执行序列化作业
    6. 所以它有点难/干净。但是使用相同的预占基础拦截器的原则(之前注册自己),你可以覆盖cleanUpOutInteceptors来操纵消息,就像在2.7.4情况下一样,通过{{1来访问WSDL }}

      WADL

      抱歉,我没有专业知识,但我猜CXF对两者都有相同的架构......