how create xml from java object using jaxb - java

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.

Related

I can't read attributes with namespace (ns2) using JAXB to parse XML in Java

I have to read data from this XML file:
<SENT_112 xmlns:ns2="http://www.mf.gov.pl/SENT/2017/01/18/STypes.xsd" xmlns="http://www.mf.gov.pl/SENT/2017/01/18/SENT_112.xsd">
<Carrier><ns2:TraderInfo><ns2:IdSisc>PL957271726800000</ns2:IdSisc><ns2:TraderName>FIRMA SPÓŁKA Z OGRANICZONĄ ODPOWIEDZIALNOŚCIĄ</ns2:TraderName>
<ns2:TraderIdentityType>NIP</ns2:TraderIdentityType>
<ns2:TraderIdentityNumber>9572717268</ns2:TraderIdentityNumber>
</ns2:TraderInfo>
<ns2:TraderAddress><ns2:Street>Arysztacka</ns2:Street><ns2:HouseNumber>91A</ns2:HouseNumber><ns2:City>Cieszyn</ns2:City><ns2:Country>PL</ns2:Country><ns2:PostalCode>43-400</ns2:PostalCode></ns2:TraderAddress></Carrier>
</SENT_112>
My main class is using JAXB:
JAXBContext jc = JAXBContext.newInstance(SENT_112.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
SENT_112 sent_112 = (SENT_112) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(sent_112, System.out);
Carrier.java
public class Carrier implements java.io.Serializable {
private int nrCarrier;
//private String sentnumber;
private String IdSisc;
private String tradername;
private String traderidentitytype;
private String traderidentitynumber;
private String street;
private String housenumber;
private String city;
private String country;
private String postalcode;
//Contrutors
//Getters and Setters
//ToString Method
SENT_112.java
#XmlRootElement(name="SENT_112")
public class SENT_112 {
#XmlElement(name="Carrier")
private List<Carrier> carrier;
public List<Carrier> getCarrier() {
return carrier;
}
PACKAGE-INFO.JAVA
#XmlSchema(
namespace = "http://www.mf.gov.pl/SENT/2017/01/18/SENT_112.xsd",
elementFormDefault = XmlNsForm.QUALIFIED)
package com.przedlak.entity;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
And my Code return that
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SENT_112 xmlns="http://www.mf.gov.pl/SENT/2017/01/18/SENT_112.xsd">
<Carrier>
<nrCarrier>0</nrCarrier>
</Carrier>
</SENT_112>
What is wrong with my Code? I need read all information.
If you want to get all information, write your classes appropriately i.e. to retrieve all data. Change Carrier.java to :
Carrier.java
#XmlRootElement(name="Carrier")
#XmlAccessorType(XmlAccessType.FIELD)
public class Carrier implements java.io.Serializable
{
#XmlElement( name = "TraderInfo" )
private TraderInfo traderInfo;
#XmlElement( name = "TraderAddress" )
private TraderAddress traderAddress;
private int nrCarrier;
public int getNrCarrier() {
return nrCarrier;
}
public void setNrCarrier(int nrCarrier) {
this.nrCarrier = nrCarrier;
}
public TraderInfo getTraderInfo() {
return traderInfo;
}
public void setTraderInfo(TraderInfo traderInfo) {
this.traderInfo = traderInfo;
}
public TraderAddress getTraderAddress() {
return traderAddress;
}
public void setTraderAddress(TraderAddress traderAddress) {
this.traderAddress = traderAddress;
}
}
Then define two classes for TraderAddress, TraderInfo as:
TraderInfo
#XmlRootElement(name="TraderInfo")
#XmlAccessorType(XmlAccessType.FIELD)
public class TraderInfo
{
#XmlElement( name = "IdSisc")
private String IdSisc;
#XmlElement( name = "TraderName")
private String tradername;
#XmlElement( name = "TraderIdentityType")
private String traderidentitytype;
#XmlElement( name = "TraderIdentityNumber")
private String traderidentitynumber;
public String getIdSisc() {
return IdSisc;
}
public void setIdSisc(String idSisc) {
IdSisc = idSisc;
}
public String getTradername() {
return tradername;
}
public void setTradername(String tradername) {
this.tradername = tradername;
}
public String getTraderidentitytype() {
return traderidentitytype;
}
public void setTraderidentitytype(String traderidentitytype) {
this.traderidentitytype = traderidentitytype;
}
public String getTraderidentitynumber() {
return traderidentitynumber;
}
public void setTraderidentitynumber(String traderidentitynumber) {
this.traderidentitynumber = traderidentitynumber;
}
}
TraderAddress.java
#XmlRootElement(name="TraderInfo")
#XmlAccessorType(XmlAccessType.FIELD)
public class TraderAddress
{
#XmlElement( name = "Street")
private String street;
#XmlElement( name = "HouseNumber")
private String houseNumber;
#XmlElement( name = "City")
private String city;
#XmlElement( name = "Country")
private String country;
#XmlElement( name = "PostalCode")
private String postalCode;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getHouseNumber() {
return houseNumber;
}
public void setHouseNumber(String houseNumber) {
this.houseNumber = houseNumber;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
}
With this setup, you should get full xml from marshalling:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SENT_112 xmlns="http://www.mf.gov.pl/SENT/2017/01/18/SENT_112.xsd">
<Carrier>
<TraderInfo>
<IdSisc>PL957271726800000</IdSisc>
<TraderName>FIRMA SPÓÅ?KA Z OGRANICZONÄ„ ODPOWIEDZIALNOÅšCIÄ„
</TraderName>
<TraderIdentityType>NIP</TraderIdentityType>
<TraderIdentityNumber>9572717268</TraderIdentityNumber>
</TraderInfo>
<TraderAddress>
<Street>Arysztacka</Street>
<HouseNumber>91A</HouseNumber>
<City>Cieszyn</City>
<Country>PL</Country>
<PostalCode>43-400</PostalCode>
</TraderAddress>
<nrCarrier>0</nrCarrier>
</Carrier>
</SENT_112>

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

CassandraInvalidQueryException String didn't validate Composite Primary Query

I am trying to use Spring-Data-Cassandra with UserDefinedType and Compound Query Key. I am using 1.5.0.DATACASS-172-SNAPSHOT of the spring-cql and spring-data-cassandra. The code throws below exception.
Caused by: org.springframework.cassandra.support.exception.CassandraInvalidQueryException:
String didn't validate.; nested exception is com.datastax.driver.core.exceptions.InvalidQueryException:
String didn't validate.
Below is my code
#PrimaryKeyClass
public class EmployeeIdKey implements Serializable {
#PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED,name = "id")
#CassandraType(type = DataType.Name.UUID)
private UUID id;
#PrimaryKeyColumn(ordinal = 1,type = PrimaryKeyType.CLUSTERED, name = "user_id")
#CassandraType(type = DataType.Name.TEXT)
private String userId;
public EmployeeIdKey(){
id = null;
userId = null;
}
public UUID getUuId() {
return id;
}
public void setUuId(UUID uuId) {
this.id = uuId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
}
Employee.java
#Table("employee")
public class Employee {
#PrimaryKey
private EmployeeIdKey id;
private Person person;
#Column("employee_no")
private String employeeNo;
#Column("email_ids")
private List<String> emailId;
//Getters and setters
}
Person.java
#UserDefinedType
public class Person {
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
#Column("first_name")
private String firstName;
#Column("last_name")
private String lastName;
// Getters adn setters;
}
EmployeeRepository.java
public interface EmployeeRepository extends TypedIdCassandraRepository<Employee,EmployeeIdKey> {
}
App.java
#SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
#Bean
public CommandLineRunner demo( EmployeeRepository repository) {
Employee employee = new Employee();
EmployeeIdKey key = new EmployeeIdKey();
key.setUserId("55550");
key.setUuId(UUID.randomUUID());
employee.setId(key);
List<String> emailIds = Arrays.asList("myemail#domain.com","myemail2#domain2.com");
employee.setEmailId(emailIds);
Person person = new Person("John", "Mathew");
employee.setPerson(person);
repository.save(employee);
return null;
}
}
When I use simple primary key it works well.

JAXB - change property name without changing variable name in class

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;
}

Correct XML annotations. Java. JAXB

There is a structure. I want to link the three entities in this way: the Company should contain id, name of company and the list of Departments, each Department has a list of Workers, id and name of department. Each worker has name, id.
+Company
-int companyId
-String companyName
-Set<Department> listOfDepartments = new HashSet<Department>();
+Department
-int departmentId
-String departmentName
-Set<Worker> listOfWorkers = new HashSet<Worker>();
+Worker
-int workerId
-String workerName
My attempt:
Company
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#Entity
public class Company {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private int companyId;
private String companyName;
#XmlElementWrapper(name="listOfDepartments")
#XmlElement
#OneToMany(mappedBy = "company", cascade=CascadeType.PERSIST, fetch = FetchType.EAGER)
private Set<Department> listOfDepartments = new HashSet<Department>();
public Set<Department> getListOfDepartments() {
return listOfDepartments;
}
public void setListOfDepartments(Set<Department> listOfDepartments) {
this.listOfDepartments = listOfDepartments;
}
public Company(){}
public Company(String companyName){
this.companyName = companyName;
}
#XmlAttribute(name="id")
public int getCompanyId() {
return companyId;
}
public void setCompanyId(int companyId) {
this.companyId = companyId;
}
#XmlElement(name="companyName")
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
Department
#Entity
public class Department {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private int idDepartment;
private String departmentName;
#XmlAttribute(name="companyId")
#ManyToOne()
#JoinColumn(name="companyId")
private Company company;
#XmlElementWrapper(name="listOfWorkers")
#XmlElement
#OneToMany(mappedBy = "department", cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
private Set<Worker> listOfWorkers = new HashSet<Worker>();
public Set<Worker> getListOfWorkers() {
return listOfWorkers;
}
public void setListOfWorkers(Set<Worker> listOfWorkers) {
this.listOfWorkers = listOfWorkers;
}
public Department(){}
public Department(String departmentName, Company company){
this.departmentName = departmentName;
this.company = company;
}
#XmlAttribute(name="id")
public int getIdDepartment() {
return idDepartment;
}
public void setIdDepartment(int idDepartment) {
this.idDepartment = idDepartment;
}
#XmlElement(name="departmentName")
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
Worker
#Entity
public class Worker {
#Id #GeneratedValue(strategy = GenerationType.AUTO)
private int idWorker;
private String workerName;
#ManyToOne
#JoinColumn(name="departmentId")
private Department department;
public Worker(){}
public Worker(String workerName,Department department){
this.workerName = workerName;
this.department = department;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
#XmlAttribute(name="id")
public int getIdWorker() {
return idWorker;
}
public void setIdWorker(int idWorker) {
this.idWorker = idWorker;
}
#XmlElement(name="name")
public String getWorkerName() {
return workerName;
}
public void setWorkerName(String workerName) {
this.workerName = workerName;
}
}
I catched the error:
com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
Class has two properties of the same name "companyId"
this problem is related to the following location:
at public int ru.eldarkaa.dto.Company.getCompanyId()
at ru.eldarkaa.dto.Company
this problem is related to the following location:
at private int ru.eldarkaa.dto.Company.companyId
at ru.eldarkaa.dto.Company
Class has two properties of the same name "companyName"
this problem is related to the following location:
at public java.lang.String ru.eldarkaa.dto.Company.getCompanyName()
at ru.eldarkaa.dto.Company
this problem is related to the following location:
at private java.lang.String ru.eldarkaa.dto.Company.companyName
at ru.eldarkaa.dto.Company
Class has two properties of the same name "listOfWorkers"
this problem is related to the following location:
at public java.util.Set ru.eldarkaa.dto.Department.getListOfWorkers()
at ru.eldarkaa.dto.Department
at private java.util.Set ru.eldarkaa.dto.Company.listOfDepartments
at ru.eldarkaa.dto.Company
this problem is related to the following location:
at private java.util.Set ru.eldarkaa.dto.Department.listOfWorkers
at ru.eldarkaa.dto.Department
at private java.util.Set ru.eldarkaa.dto.Company.listOfDepartments
at ru.eldarkaa.dto.Company
GODs of XML Annotations please advise me a solution.
By default JAXB treats public fields and properties as mapped. When you annotate a non-public field it causes that to become mapped as well resulting in the conflict.
Solutions
Annotate the property (get or set method) instead of the field (instance variable).
Annotate the field and the class with #XmlAccessorType(XmlAccessType.FIELD).
For More Information
http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html

Categories

Resources