JAXB - change property name without changing variable name in class - java

So I have code like this:
#XmlRootElement(name = "person")
#XmlType(propOrder = {"name", "secondName"})
public class Person {
private String name;
private String secondName;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setSecondName(String secondName) {
this.secondName = secondName;
}
public String getSecondName() {
return secondName;
}
}
And when I want to create XML file it makes me:
<person>
<name>John</name>
<secondName>Smith</secondName>
</person>
Is it any way to make in xml file <second-name> instead of <secondName> without changing in class on private String second-name?

Problem solved. I should just do this:
#XmlElement(name="second-name")
public String getSecondName() {
return secondName;
}

Related

Selective marshalling object

I need to execute a selective marshalling object. For example:
There is a class Contact:
#XmlRootElement(name = "contact")
public class Contact {
private String name;
private String number;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Marshalling the object:
public static void main(String[] args) throws JAXBException {
Contact contact = new Contact();
contact.setAddress("5 Av.");
contact.setName("John");
contact.setNumber("5555555");
JAXBContext context = JAXBContext.newInstance(Contact.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(contact, System.out);
}
As a result we have:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<contact>
<address>5 street</address>
<name>John</name>
<number>5555555</number>
</contact>
Is there any simple way to perform a selective marshalling? For example, only the address to get at the output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<contact>
<address>5 street</address>
</contact>
Thanks!
When unspecified, the default is as-if the following annotation is on the class:
#XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
That means that all public member will be used by JAXB, i.e. all your getter methods.
You can either keep that default and suppress the getter methods you don't want, or you can change the default and explicitly mark the getter methods you do want processed.
To suppress a getter method, annotate with #XmlTransient:
Prevents the mapping of a JavaBean property/type to XML representation.
To change default, annotate with #XmlAccessorType(XmlAccessType.NONE):
None of the fields or properties is bound to XML unless they are specifically annotated with some of the JAXB annotations.
Then explicitly annotate desired getter methods with #XmlElement:
Maps a JavaBean property to a XML element derived from property name.
Using #XmlTransient
#XmlRootElement(name = "contact")
class Contact {
private String name;
private String number;
private String address;
#XmlTransient
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlTransient
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Using #XmlAccessorType(XmlAccessType.NONE)
#XmlRootElement(name = "contact")
#XmlAccessorType(XmlAccessType.NONE)
class Contact {
private String name;
private String number;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
#XmlElement
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Output (from both)
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<contact>
<address>5 Av.</address>
</contact>

JAXB - Adding same attributes to different elements

I carefully studied the discussion "JAXB Adding attributes..." and would like to move a little further.
For example, there is a following class:
#XmlRootElement(name = "company")
#XmlType(propOrder = {"id", "name", "address"})
public class Company {
private String id;
private String name;
private String address;
#XmlElement(name = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElement(name = "address")
public String getAddress() {
return name;
}
public void setAddress(String address) {
this.address = address;
}
}
After marshaling an object we have:
<company>
<id>1</id>
<name>Abc</name>
<address>Mountain View, United States</address>
</company>
Is there an elegant solution, - for example using annotations #XmlPaths, #XmlPath, #XmlElements, #XmlElement, - to receive as a result:
<company>
<id>1</id>
<name lang="en">Abc</name>
<address lang="en">Mountain View, United States</address>
</company>
How about creating a custom String with the lang attribute and use that instead of string
for example :
public class LangString {
#XmlValue
protected String value;
#XmlAttribute(name = "lang")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
#XmlSchemaType(name = "language")
protected String lang;
//GETTERS & SETTERS
}
Your code :
#XmlRootElement(name = "company")
#XmlType(propOrder = {"id", "name", "address"})
public class Company {
private String id;
private LangString name;
private LangString address;
#XmlElement(name = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#XmlElement(name = "name")
public LangString getName() {
return name;
}
public void setName(LangString name) {
this.name = name;
}
#XmlElement(name = "address")
public LangString getAddress() {
return name;
}
public void setAddress(LangString address) {
this.address = address;
}
}
The code above was generated from an xsd schema for my application that had elements with the lang attribute thus the #XmlSchemaType.
Hope it helps

Unable to unmarshal an object inside another object

I have got an xml file:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns1:Data xmlns:ns1="http://vv.com/namespace">
<Addr>Address 1</Addr1>
<Locality>San Francisco</Locality>
<Country>Japan</Country>
<CountryCode>JP</CountryCode>
</ns1:Data>
</soapenv:Body>
</soapenv:Envelope>
AddressDto.java
#XmlRootElement(name = "Data", namespace = "http://vv.com/namespace")
public class AddressDto implements Serializable
{
private String street;
private String city;
private CountryDto country;
public AddressDto()
{
super();
}
#XmlElement(name = "Addr")
public String getStreet1()
{
return street;
}
public void setStreet1(final String street1)
{
this.street = street1;
}
#XmlElement(name = "Locality")
public String getCity()
{
return city;
}
public void setCity(final String city)
{
this.city = city;
}
public CountryDto getCountry()
{
return country;
}
public void setCountry(final CountryDto country)
{
this.country = country;
}
}
CountryDto file:
public class CountryDto implements Serializable
{
private String name;
private String code;
public CountryDto()
{
super();
}
#XmlElement(name = "CountryCode")
public String getCode()
{
return code;
}
public void setCode(final String code)
{
this.code = code;
}
#XmlElement(name = "Country")
public String getName()
{
return name;
}
public void setName(final String name)
{
this.name = name;
}
}
When i run the code
JAXBContext context = JAXBContext.newInstance(AddressDto.class);
Unmarshaller un = context.createUnmarshaller();
AddressDto emp = (AddressDto) un.unmarshal(response.getSOAPBody().extractContentAsDocument());
return emp;
I am able to get the street and city in AddressDto object. But the field country is displaying as null...Any idea whats going wrong here?
Thanks
Parser don't know what Country / CountryCode means. You defined only Addr and Locality as XmlElement inside your AddressDto class. Therefore you will get null.
You need to modify your xml to something like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns1:Data xmlns:ns1="http://vv.com/namespace">
<Addr>Address 1</Addr1>
<Locality>San Francisco</Locality>
<CountryDto>
<Country>Japan</Country>
<CountryCode>JP</CountryCode>
</CountryDto>
</ns1:Data>
</soapenv:Body>
</soapenv:Envelope>
And also modify your addressDto so getCountry() is XmlElement as well:
#XmlElement(name = "CountryDto")
public CountryDto getCountry()
{
return country;
}
Now Country and CountryCode won't be null anymore

how create xml from java object using jaxb

How can i create following type xml in java using jaxb
<myInfo>
<firstName>MyfirstName</firstName>
<lastName>MyLstNme</lastName>
<contactList>
<contact>
<id>001</id>
<name>name1</name>
<contact/>
<contact>
<id>002</id>
<name>name2</name>
<contact/>
<contact>
<id>003</id>
<name>name3</name>
<contact/>
</ContactList>
</myInfo>
Bean Classes are..
#XmlRootElement(name = "myInfo")
#XmlAccessorType(XmlAccessType.FIELD)
public class MyInfo {
#XmlElement(name = "firstName")
public String firstName;
#XmlElement(name = "lastName")
public String lastName;
#XmlElement(name = "contactList")
public ContactList contactList;
...getter setter
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "contactList")
public class ContactList {
#XmlElement(name = "contact", type = Contact.class)
public List<Contact> list = new ArrayList<Contact>();
public ContactList() {
}
public ContactList(List<Contact> list) {
this.list = list;
}
...getter setter
}
#XmlRootElement(name = "Contact")
public class Contact {
#XmlElement(name = "id")
public String id;
#XmlElement(name = "name")
public String name;
...getter setter
And Exception
objData ToXML 2 counts of IllegalAnnotationExceptions
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions
==
Class has two properties of the same name "id"
this problem is related to the following location:
at public java.lang.String java8javafx8.Contact.getId()
at java8javafx8.Contact
at public java.util.List java8javafx8.ContactList.list
at java8javafx8.ContactList
at public java8javafx8.ContactList java8javafx8.MyInfo.contactList
at java8javafx8.MyInfo
this problem is related to the following location:
at public java.lang.String java8javafx8.Contact.id
at java8javafx8.Contact
at public java.util.List java8javafx8.ContactList.list
at java8javafx8.ContactList
at public java8javafx8.ContactList java8javafx8.MyInfo.contactList
at java8javafx8.MyInfo
Class has two properties of the same name "name"
this problem is related to the following location:
at public java.lang.String java8javafx8.Contact.getName()
at java8javafx8.Contact
at public java.util.List java8javafx8.ContactList.list
at java8javafx8.ContactList
at public java8javafx8.ContactList java8javafx8.MyInfo.contactList
at java8javafx8.MyInfo
this problem is related to the following location:
at public java.lang.String java8javafx8.Contact.name
at java8javafx8.Contact
at public java.util.List java8javafx8.ContactList.list
at java8javafx8.ContactList
at public java8javafx8.ContactList java8javafx8.MyInfo.contactList
at java8javafx8.MyInfo
How create Bean Class and Bean List Class??
Ok hear you go:
Make one class call MyInfo as:
#XmlRootElement(name="myInfo")
public class MyInfo {
private String firstName;
private String lastName;
private List<Contact> contactList = new ArrayList<Contact>(0);
public MyInfo(){}
public MyInfo(String fName, String lName){
this.firstName = fName;
this.lastName = lName;
}
#XmlElement(name = "firstName")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#XmlElement(name="lastName")
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public List<Contact> getContactList() {
return contactList;
}
#XmlElement(name = "contactList")
public void setContactList(List<Contact> contactList) {
this.contactList = contactList;
}
}
write another class called Contact as:
public class Contact {
private int id;
private String name;
public Contact(){}
public Contact(int id, String name){
this.id = id;
this.name = name;
}
#XmlElement(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
#XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Marshell it with JAXB (create XML) as:
public class Test {
public static void main(String[] args){
Contact c1 = new Contact(1, "first");
Contact c2 = new Contact(2, "second");
MyInfo info = new MyInfo("Shekhar", "Khairnar");
info.getContactList().add(c1);
info.getContactList().add(c2);
try {
JAXBContext jaxbContext = JAXBContext.newInstance(MyInfo.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(info, System.out);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
In above eg. I just print the xml output on console you can write in a file also.
out put will be:
<myInfo>
<firstName>Shekhar</firstName>
<lastName>Khairnar</lastName>
<contactList>
<id>1</id>
<name>first</name>
</contactList>
<contactList>
<id>2</id>
<name>second</name>
</contactList>
You can do the following:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class MyInfo {
private String firstName;
private String lastName;
#XmlElementWrapper
#XmlElement(name="contact")
private List<Contact> contactList;
// getters & setters
}
Things to note:
JAXB is configuration by exception so you only need to annotate where you want the XML representation to differ from the default.
By default JAXB treats public fields and properties as mapped. If you want to treat only fields as mapped you should specify #XmlAccessorType(XmlAccessType.FIELD).
The mapped fields can be private.
#XmlElementWrapper is used to add a grouping element to a collection.
When #XmlElement is used on a collection it applies to each item in the collection.

Convert Java ENUM to XML

I want to make a xml from enum Type with parameters.
e.g:
#XmlRootElement(name="category")
#XmlAccessorType(XmlAccessType.NONE)
public enum category{
FOOD(2, "egg"),
private final double value;
#XmlElement
private final String description;
private Category(double value, String name){
this.value = value;
this.description = name;
}
}
I want to the generated XML be like this
<category>
FOOD
<description>Egg</description>
</category>
but, this is what I have:
<category>FOOD</category>
Any annotation from javax.xml.bind.annotation can do this?
Sorry for my bad English
You may want this
marshaller.marshal(new Root(), writer);
output <root><category description="egg">FOOD</category></root>
since #XmlValue and #XmlElement would not be allow to be in a same class
i change it to attribute
#XmlJavaTypeAdapter(CategoryAdapter.class)
enum Category {
FOOD(2D, "egg");
private double value;
#XmlAttribute
String description;
Category(double value, String name) {
this.value = value;
this.description = name;
}
}
#XmlRootElement(name = "root")
#XmlAccessorType(XmlAccessType.FIELD)
class Root {
#XmlElementRef
Category c = Category.FOOD;
}
#XmlRootElement(name = "category")
#XmlAccessorType(XmlAccessType.NONE)
class PrintableCategory {
#XmlAttribute
//#XmlElement
String description;
#XmlValue
String c;
}
class CategoryAdapter extends XmlAdapter<PrintableCategory, Category> {
#Override
public Category unmarshal(PrintableCategory v) throws Exception {
return Category.valueOf(v.c);
}
#Override
public PrintableCategory marshal(Category v) throws Exception {
PrintableCategory printableCategory = new PrintableCategory();
printableCategory.description = v.description;
printableCategory.c = v.name();
return printableCategory;
}
}

Categories

Resources