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

Java CXF:为CXF SOAP/REST web服务的WSDL和WADL响应添加隐式头,java,web-services,rest,soap,cxf,Java,Web Services,Rest,Soap,Cxf,我试图为CXFSOAP/RESTWeb服务(由Camel管理)的WSDL和WADL响应添加隐式头 (这些不一定是安全标头…) 所谓“隐式头”,我的意思是,点击服务的WSDL/WADL URL将表明客户机应该在请求中提供头 但是我不想在web服务的签名中显式地指定头 我有一个CXF拦截器,它向每个SOAP/REST响应添加一个隐式头 因此,由于WSDL/WADL文档是作为对某个GET请求的响应发送的,因此我考虑以某种方式使用类似的拦截器将头数据添加到WSDL/WADL响应中。我怎么能完成这么了不起

我试图为CXFSOAP/RESTWeb服务(由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)
    {
    }
}
公共类MyInterceptor扩展了AbstractPhaseInterceptor{
公共MyInterceptor()
{
超级(相位接收);
}
@凌驾
公共无效handleMessage(消息消息)
{   
尝试
{
//肥皂
if(SoapMessage的消息实例)
{               
列表标题=((SoapMessage)消息).getHeaders();
Header dummyHeader=newheader(新的QName(“uri:org.apache.cxf”,“dummy”),“无头”,新的JAXBDataBinding(String.class));
headers.add(dummyHeader);
}
//休息
其他的
{
映射头=(Map)message.get(message.PROTOCOL_头);
字符串dummyHeader=“斩首”;
headers.put(“dummy”,Collections.singletonList(dummyHeader));
}
}
捕获(JAXBEException e)
{
抛出新的故障(e);
}
}
@凌驾
公共无效handleFault(消息参数)
{
}
}
CXF 2.7.4 在CXF中,WSDL是通过名为
WSDLGetInterceptor
的In链中的拦截器生成的,该拦截器位于
READ
链中

它的基本设计是

  • 检查调用是否为HTTP GET
  • 准备要返回的输出消息
  • 访问wsdl(从Java或静态资源)
  • 将wsdl写入输出消息
  • 中断拦截器链以提供输出消息
  • 对这个过程进行操作的最简单的方法是抢先这个拦截器完成它的工作,或者在之前注册您自己的实现

    在默认总线上删除标准的CXF拦截器是一件“很难做的事情”(最简单的方法是注册您自己的拦截器,将其放在链的第一位,并使其删除其他拦截器,如so
    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
    }
    
    公共文档getDocument(消息、,
    弦基,
    映射参数,
    字符串ctxUri,
    EndpointInfo(EndpointInfo){
    Document domDocument=super.getDocument(消息、基、参数、ctxUri、端点信息);
    domDocument.getChildNodes();//需要添加或删除的内容
    返回domDocument;//一旦修改
    }
    
    您可以动态修改生成的DOM文档(添加/创建DOM节点)或通过XSLT进行修改,只要最适合您,您就可以通过标准API处理标准XML了

    CXF 2.7.x(其中x在某个地方大于4且小于10) 原理相同,但拦截器的工作方式不同

  • 它(在私有方法中)将WSDL作为DOM文档作为输出消息属性
  • 它清除所有拦截器的输出拦截器链(绝对必要的拦截器除外)
  • 它在输出链中注册一个
    wsdlgetoutiterceptor
  • 它停止IN链并继续到停止链
  • wsdlgetoutiterceptor
    执行其序列化工作
  • 因此,它有点难/不太干净。但是使用相同的原则,即先占用基本拦截器(在之前注册您自己),您可以覆盖
    cleanuputingeceptor
    来操纵消息,就像在2.7.4中一样,通过
    outMessage.get(DOCUMENT\u HOLDER)

    小河
    对不起,我没有专业知识,但我想CXF对这两个方面都有相同的体系结构…

    你的意思是:你想修改通过对yourService.WSDL的GET调用返回的WSDL,以便在适当的位置添加额外的元素吗?是的。在这个项目中,我会根据web服务方法签名自动创建WSDL(不是WSDL到Java)。但是我希望避免显式地将头参数添加到这些方法中,而只是显示(在WSDL契约中)对于此服务的客户端来说,SOAP请求中应该包含特定的头。这绝对是了不起的!有三个问题-对于前两个问题,至少在比您在这里使用的更新的CXF版本中是这样的:1.
    WSDLGetInterceptor
    构造函数没有参数,默认情况下放在
    READ
    链上。好的,我知道了st使用无参数构造函数。2.
    getDocument(…)
    现在是私有的,因此我无法覆盖它。另外,它的签名在2.7.10左右发生了更改,然后又发生了更改(很好,因为它是私有的)3.你会如何处理?3.你会如何处理WADL等价物?编辑以解决2.7.10的变化Hanks GPI,这是一个有用的答案,为我指明了正确的方向。