SoT
SoT

Reputation: 1213

JAXB how to get QName based on java object

We are using maven plugin to generate a large number of Java pojos and ObjectFactory, similar to:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "ProtectedABC", propOrder = {
    "aBC"
})
public class ABC {

    @XmlElement(required = true)
    protected String aBC;

   
    public String getABC() {
        return aBC;
    }

    
    public void setABC(String value) {
        this.aBC= value;
    }

}

and

@XmlRegistry
public class ObjectFactory {

    private final static QName ABC = new QName("http://www", "request1");
    private final static QName DEF = new QName("http://www", "response1");
    private final static QName XYZ = new QName("http://www", "result1");
    /*
     * A LOT OF QNAMES HERE
     */
    private final static QName END = new QName("http://www", "end");
  
    //OTHER GENERATED METHODS
}

I have a method that take a java object (value) and I need to convert it to JaxbElement

  public DataBuffer encodeValue(Object value, DataBufferFactory bufferFactory, ResolvableType valueType, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
    boolean release = true;
    DataBuffer buffer = bufferFactory.allocateBuffer(1024);
    try {
      OutputStream outputStream = buffer.asOutputStream();
      Class<?> clazz = ClassUtils.getUserClass(value);
      
      JAXBContext jaxbContext = JaxbUtils.createJaxbContext();
      Marshaller marshaller = initMarshaller(jaxbContext);
      JAXBIntrospector jaxbIntrospector = jaxbContext.createJAXBIntrospector();

      //HERE I TRY TO GET QNAME BASED ON POJO:
      //BASED ON THIS POST: https://stackoverflow.com/questions/5035716/obtain-java-class-name-from-qname
      QName elementName = jaxbIntrospector.getElementName(value);

      JAXBElement<Object> jaxbElement = new JAXBElement(elementName , clazz, value);
      marshaller.marshal(jaxbElement, outputStream);
      release = false;
      return buffer;
    } catch (Exception ex) {
      throw new EncodingException("Could not marshal " + value.getClass() + " to XML", ex);
    }
  }

The problem is QName elementName = jaxbIntrospector.getElementName(value); return null so I cannot create JAXBElement. I don't want to check type/class of value like if(value instance of ABC) {} since I have a huge number of pojos. Please tell me is it possible to get/obtain QName based on a java object (do not know exactly its type)?

NOTE: I have found a method ((JAXBContextImpl) jaxbContext).getTypeName(TypeReference) that take a TypeReference and return QName, but I do'nt know how to construct TypeReference, too.

PLEASE HELP

Upvotes: 0

Views: 903

Answers (1)

Ph&#250; Phan
Ph&#250; Phan

Reputation: 1

I dont think you should create JAXElement from scratch with new JAXBElement(elementName , clazz, value)

In ObjectFactory, we can create JAXElement directly via method starting with createSomething() - and the newly-created JAXElement will have QName for itself. So my approach is:

  1. Get the name of class for the value object that should be converted -> by ClassUtils in spring core or something like that
  2. Add create before the name we already get in step1
  3. Initialize an instance of ObjectFactory and invoke method createSomething(value) with Reflection lib (of course dont forget catch exception in case there is no supported method in ObjectFactory!)

Hope it help and if possible, please give me a look of your schema files (xsd or wsdl, etc) or your classes which are generated from schema files, so that I can elaborate on those for detailed lines of code.

Upvotes: -1

Related Questions