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...