CXF:将带有名称空间的元素从消息添加到SOAP标头

时间:2016-01-17 19:42:22

标签: cxf soapheader

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

是否可以使用出站拦截器以及哪个阶段可用的命名空间前缀?或者还有其他方法可以这样做吗?

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

1 个答案:

答案 0 :(得分:0)

我创建了拦截器,我获取了消息(作为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) {
        //...
    }
}

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