Reputation: 1230
I´m modeling my project and I want to know if is possible to reduce the repetition of code in my unmarshal process.
I have two classes
public class Person {
private String name;
private String telephone
// getter and setter
}
public class Company {
private String name;
private String telephone
// getter and setter
}
My xml have this source.
<file>
<person>
<name>Test</name>
<telephone>190</telephone>
</person>
<company>
<name>Test2</name>
<telephone>181</telephone>
</company>
</file>
So I want to know what should I do to make a superclass being reconized by the others and by Jaxb.
Thanks
Upvotes: 0
Views: 596
Reputation: 114
You could accomplish this with annotation @XmlSeeAlso.
@XmlSeeAlso({Person.class,Company.class})
public class Contact {
private String name;
private String telephone
//getters and setters
}
public class Person extends Contact {
}
public class Company extends Contact{
}
you could then
JAXBContext.newInstance(Contact.class)
and it would allow for both classes to be handled by same code
Okay so below is what I did. I took your xml file(changed File to something diff as in this case FileTest2, excuse the horrible names), created the classes in composition style, and tested to make sure the unmarshal would work. I then marshaled it again to make sure I got the correct xml structure back, see below code.
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Person {
private String name;
private String telephone;
public Person() {
super();
}
public Person(String name, String telephone){
this();
setName(name);
setTelephone(telephone);
}
public String getName(){
return name;
}
public String getTelephone(){
return telephone;
}
public void setName(String name){
this.name=name;
}
public void setTelephone(String telephone){
this.telephone=telephone;
}
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Company {
private String name;
private String telephone;
public Company() {
super();
}
public Company(String name, String telephone){
this();
setName(name);
setTelephone(telephone);
}
public String getName(){
return name;
}
public String getTelephone(){
return telephone;
}
public void setName(String name){
this.name=name;
}
public void setTelephone(String telephone){
this.telephone=telephone;
}
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class FileTest2 {
private Person person;
private Company company;
public FileTest2() {
super();
}
public FileTest2(Person person, Company company){
this();
setPerson(person);
setCompany(company);
}
public Person getPerson() {
return this.person;
}
public void setPerson(Person person) {
this.person = person;
}
public Company getCompany() {
return this.company;
}
public void setCompany(Company company) {
this.company = company;
}
}
@Test
public void testUnMarshal() throws Exception {
File xmlFile = null;
try {
xmlFile = getXmlFile();
} catch (Exception e) {
}
if (xmlFile == null) {
fail("file not found");
}
FileTest2 filetest = (FileTest2) JaxbUtil.unmarshal(
xmlFile, filetest.class,
FileTest2.class, Person.class, Company.class);
if (filetest==null){
fail("unmarshal failed");
}
assertEquals("Company name was not correctly handled","Test2",filetest.getCompany().getName());
assertEquals("Company telephone was not correclty handled","181", filetest.getCompany().getTelephone());
assertEquals("Person name was not correctly handled","Test",filetest.getPerson().getName());
assertEquals("Person telephone was not correclty handled","190", filetest.getPerson().getTelephone());
}
@Test
public void testMarshal() throws Exception {
Person person = new Person("bob", "23");
Company company = new Company("accountTemps", "99");
FileTest2 filetest = new FileTest2(person, company);
FileWriter fileWriter = new FileWriter("marshaledFileResults.xml");
JaxbUtil.marshal(filetest, fileWriter, true, filetest.class,
FileTest2.class, Person.class, Company.class);
}
the testMarshal produced the following
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<fileTest2>
<person>
<name>bob</name>
<telephone>23</telephone>
</person>
<company>
<name>accountTemps</name>
<telephone>99</telephone>
</company>
</fileTest2>
So, what I think you want to know is how do you stop from having to repeat all that boilerplate needed for marshal and unmarshal. I accomplish this through my JaxbUtil class. I have all the boilerplate in there and I simply need to call the overloaded method I need for marshal or unmarshal passing in the classes to be bound and all the ugly boilerplate stuff stays away from my actual code.
Also for anyone that wanted to user custom adapters for multiple classes with similar class structures you could use generics in your custom adapter that extends XmlAdapter and use annotation @XmlJavaTypeAdapter so Jaxb uses your generic adapter for those classes.
Upvotes: 1