[RISOLTO] Java - Jackson XML Deserializing con generics

di il
1 risposte

[RISOLTO] Java - Jackson XML Deserializing con generics

Ciao,

ho necessità di deserializzare questi 2 XML:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xml_result>
   <result code="0"/>
   <query queryname="Persons">
       <row>
           <name>charles</name>
           <userid>1</userid>
       </row>
       <row>
           <name>arthur</name>
           <userid>2</userid>
       </row>
   </query>
</xml_result>
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xml_result>
   <result code="0"/>
   <query queryname="Users">
       <row>
           <id>1</id>
           <username>charles</username>
       </row>
       <row>
           <id>2</id>
           <username>arthur</username>
       </row>
   </query>
</xml_result>

Gli XML si differiscono solo nel:

  • valore dell'attributo queryname (che identifica il nome della query, nell'esempio Persons e Users)
  • contenuto dell'elemento row (nell'esempio name e userid per la query Persons, id e username per la query Users)

Ho quindi creato:

  • una classe generica, che mappa tutti gli elementi comuni (result e query) e mappando l'elemento query.row con un List<T>
  • una classe Person, che mappa il contenuto di query.row per la query Person
  • una classe User, che mappa il contenuto di query.row per la query User
import java.util.List;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

public class XmlGeneric<T extends IXmlRow> {
   public static class Result {
       @JacksonXmlProperty(isAttribute = true)
       private Integer code;
       public Integer getCode() {return code;}
   }
   
   public static class Query<T> {            
       @JacksonXmlProperty(isAttribute = true)
       private String queryname;
       public String getQueryName() {return queryname;}
       
       @JacksonXmlProperty(localName = "row")
       @JacksonXmlElementWrapper(useWrapping = false)
       private List<T> rows;
       public List<T> getRow() {return rows;};
   }
   
   private Result result;
   public Result getResult() {return result;}
   
   private Query<T> query;
   public Query<T> getQuery() {return query;}
}
public class Person implements IXmlRow {
   private String name;
   private String userid;
   
   public String getName() {return name;}
   public String getUserid() {return userid;}
}
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
public class User implements IXmlRow {
   private String id;
   @JacksonXmlProperty(localName = "username")
   private String username;
   
   public String getId() {return id;}
   public String getUserName() {return username;}
}

A questo punto, per eseguire la deserializzazione con Jackson, mi servirebbe un'istruzione del tipo:

XmlMapper xmlMapper = new XmlMapper();
XmlGeneric<Person> xmlPerson = xmlMapper.readValue(xmlData,XmlGeneric<Person>.class);

Ma ottengo un errore dal compilatore in merito all'istruzione “XmlGeneric<Person>.class”.

La soluzione che ho trovato è stata quella di creare un'altra classe XmlPerson che estende XmlGeneric<Person>, eseguendo poi la deserializzazione con XmlPerson

public class XmlPerson extends XmlGeneric<Person> {
}
XmlPerson xmlPerson = xmlMapper.readValue(xmlData,XmlPerson.class);

Il mio problema risiede nel fatto che mi servirebbe deserializzare l'xml in un oggetto “comune” per applicare delle logiche comuni. Ad esempio

XmlGeneric<IXmlRow> xmlGeneric1 = xmlMapper.readValue(xmlData,XmlGeneric<Person>.class);
XmlGeneric<IXmlRow> xmlGeneric2 = xmlMapper.readValue(xmlData,XmlGeneric<User>.class);

Ho modo quindi di passare al metodo readValue il .class di una classe generic?

Grazie in anticipo.

MM

1 Risposte

Devi accedere o registrarti per scrivere nel forum
1 risposte