0

How can I get the name (including namespace prefix) of root element in message (1st element in SOAP body) and add this information to SOAP header.

Is it possible to do so with outbound interceptor and in which phase is the namespace prefix available? Or is there other way how to do so?

EDIT: I am able to get the element with its namespace prefix via message.getContent(OutputStream.class) but I don't want to modify row XML. Is there way how can I get namespace (e.g. from JAXB object in message) and set its namespace prefix? Then I can use the element name and my prefix in header.

Fenix
  • 2,271
  • 1
  • 16
  • 24

1 Answers1

0

I created interceptor where I get message (as JAXB object) and then I use reflection to get its root element (because it is not root element) from ObjectFactory. Then I get its namespace and name and I use it for SOAP header and I set namespace prefix for the namespace. My handleMessage method in interceptor is like the following:

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) {
        //...
    }
}

Better solution is welcome...

Fenix
  • 2,271
  • 1
  • 16
  • 24