【问题标题】:CXF: add element with namespace from message to SOAP headerCXF:将具有命名空间的元素从消息添加到 SOAP 标头
【发布时间】:2016-01-19 00:54:31
【问题描述】:

如何获取消息中根元素(SOAP 正文中的第一个元素)的名称(包括命名空间前缀)并将此信息添加到 SOAP 标头。

是否可以使用出站拦截器这样做?命名空间前缀在哪个阶段可用?还是有其他方法可以做到这一点?

编辑: 我可以通过 message.getContent(OutputStream.class) 获取带有名称空间前缀的元素,但我不想修改行 XML。有没有办法如何获取命名空间(例如,从消息中的 JAXB 对象)并设置其命名空间前缀?然后我可以在标题中使用元素名称和前缀。

【问题讨论】:

    标签: cxf soapheader


    【解决方案1】:

    我创建了获取消息的拦截器(作为 JAXB 对象),然后我使用反射从 ObjectFactory 获取其根元素(因为它不是根元素)。然后我得到它的命名空间和名称,并将它用于 SOAP 标头,并为命名空间设置命名空间前缀。我在拦截器中的handleMessage方法如下:

    public void handleMessage(SoapMessage message) throws Fault {
    
        String rootElementNamespace = null;
        String rootElementName = null;
    
        Set<Class<?>> formats = message.getContentFormats();
        List<?> messageContent = message.getContent(List.class);
        Object responseMessage = null;
        for (Object o : messageContent){
            if (o != null && o.getClass().getAnnotation(XmlType.class) != null){
                responseMessage = o;
                break;
            }
        }
        if(responseMessage == null){
            return;
        }
        Class<? extends Object> messageContentClass = messageContent.get(0).getClass();
        String packageOfMessageContentClass = messageContent.get(0).getClass().getPackage().getName();
        try {
            Class<?> objectFactory = Class.forName(packageOfMessageContentClass + ".ObjectFactory");
            Method[] objectFactoryMethods = objectFactory.getMethods();
            Method createMessageMethod = null;
            for (Method m : objectFactoryMethods){
                if (m.getParameterTypes().length == 1 && m.getParameterTypes()[0].equals(messageContentClass)){
                    createMessageMethod = m;
                    break;
                }
            }
            if(createMessageMethod == null){
                return;
            }
            XmlElementDecl xmlTypeAnnotation = createMessageMethod.getAnnotation(XmlElementDecl.class);
            rootElementNamespace = xmlTypeAnnotation.namespace();
            rootElementName = xmlTypeAnnotation.name();
    
        } catch (ClassNotFoundException e) {
            //...
        }
    
        Map<String, String> hmap = new HashMap<String, String>();
        hmap.put(this.ROOT_PREFIX, rootElementNamespace);
        message.put("soap.env.ns.map", hmap);
        message.put("disable.outputstream.optimization", true);
    
        try {
            Header header = getMyHeader(this.ROOT_PREFIX + ":" + rootElementName); //method creates header with required info
            message.getHeaders().add(header);
        } catch (JAXBException | DatatypeConfigurationException e) {
            //...
        }
    }
    

    欢迎提供更好的解决方案...

    【讨论】:

      猜你喜欢
      • 2017-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-28
      • 2019-11-17
      • 2017-11-27
      • 1970-01-01
      相关资源
      最近更新 更多