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 链中。

它的基本设计是

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

处理此进程的最简单方法是抢占此拦截器的工作,方法是先注册您自己的实现。

删除标准 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)

原理是一样的,只是拦截器的作用不同

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

所以有点难/不太干净。但是使用抢占基本拦截器的相同原则(之前注册自己),您可以覆盖 cleanUpOutInteceptors 来操作消息,就像在 2.7.4 中一样,通过 [=20 访问 WSDL =]

WADL

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