Hi I am new to Jaxb and trying to unmarshall a xml file through jaxb. I have added the xmpproporder and name fields correctly.
However two of my XML fields are populating as null while the others are populating perfectly.
My xml file is :-
<tables>
<table id="1">
<name>test1</name>
<schema>validator_test</schema>
<rowCountToValidate>7</rowCountToValidate>
<columnTypeCheckRequired>FALSE</columnTypeCheckRequired>
<additionalColumns>column1,column2</additionalColumns>
<targetName>target1</targetName>>
</table>
<table id="2">
<schema>validator_test</schema>
<name>validate_external1</name>
<rowCountToValidate>1</rowCountToValidate>
<columnTypeCheckRequired>FALSE</columnTypeCheckRequired>
<additionalColumns>column1,column2</additionalColumns>
</table>
</tables>
My code to unmarshall the elements is :
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
#XmlRootElement(name = "table")
#XmlType(propOrder = { "name", "schema","rowCountToValidate","columnTypeCheckRequired","additionalColumns","targetName"})
#Service
public class TableInfo {
private static final boolean TRUE = true;
#Value("${default.row.count.to.validate}")
private Integer defaultRowCountToValidate;
/**
*
*/
public TableInfo() {
}
private String name;
private String schema;
private Integer rowCountToValidate;
private String targetName;
private String columnTypeCheckRequired;
private String additionalColumns;
#XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElement(name = "schema")
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
#XmlElement(name = "rowCountToValidate")
public Integer getRowCountToValidate() {
return rowCountToValidate;
}
#XmlElement(name = "columnTypeCheckRequired")
public String getcolumnTypeCheckRequired(){
return columnTypeCheckRequired;
}
#XmlElement(name = "additionalColumns")
public String getadditionalColumns(){
return additionalColumns;
}
public void setRowCountToValidate(Integer rowCountToValidate) {
// If user configured value is not null and greater than zero then set
// the value otherwise use default value
if ((null != rowCountToValidate) && (rowCountToValidate.intValue() > 0)) {
this.rowCountToValidate = rowCountToValidate;
}else {
this.rowCountToValidate = defaultRowCountToValidate;
}
}
#XmlElement(name = "targetName")
public String getTargetName() {
return targetName;
}
public void setTargetName(String targetName) {
this.targetName = targetName;
}
public void setColumnTypeCheckRequired(String columnTypeCheckRequired) {
this.columnTypeCheckRequired = columnTypeCheckRequired;
}
public void setAdditionalColumns(String additionalColumns) {
this.additionalColumns = additionalColumns;
}
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}}
I am getting null values in columnTypeCheckRequired and additionalColumns. However other fields are populating correctly. Is there some other field or setting that I need to set?
I am completely new to Jaxb! Can someone please help me understand the error ?
You must change following getter, using camel case style. C and A capital case.
#XmlElement(name = "columnTypeCheckRequired")
public String getColumnTypeCheckRequired() {
return columnTypeCheckRequired;
}
#XmlElement(name = "additionalColumns")
public String getAdditionalColumns() {
return additionalColumns;
}
Related
Hi i'm new to JAXB Conversions.
I'm Unmarshalling an xml into java objects. For single occurrence sections there is no issue, but for multiple occurrence not able to map properly. Each time I'm getting null list for multiple occurrence section.
Please suggest me any useful url's or suggest me changes need to be done.
XML ::
<?xml version="1.0" encoding="UTF-8"?>
<designTheory>
<Administartor>
<circuitId>67565675476</circuitId>
<processId>567855</processId>
<version>01</version>
<circuitReferenceValue>ciruit-0001</circuitReferenceValue>
<property>cal-circuit</property>
</Administartor>
<designSec>
<priloc>priloc</priloc>
<secloc>secloc</secloc>
<remarks>remarks field</remarks>
</designSec>
<designNotes>
<notesNumber>1</notesNumber>
<notes>designNotes 1</notes>
</designNotes>
<designNotes>
<notesNumber>2</notesNumber>
<notes>designNotes 2</notes>
</designNotes>
<designNotes>
<notesNumber>3</notesNumber>
<notes>designNotes 3</notes>
</designNotes>
<designNotes>
<notesNumber>4</notesNumber>
<notes>designNotes 4</notes>
</designNotes>
</designTheory>
Code Snippets are as below :
DesignTheory.java
package org.manjunath.jaxbconversions.beans;
import java.util.List;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "designTheory")
public class DesignTheory {
#XmlElement(name = "Administartor", required = true)
private Administartor admin;
#XmlElement(name = "designSec", required = true)
private DesignSec designSec;
#XmlElementWrapper
#XmlElementRef(name = "designNotes")
private List<JAXBElement<DesignNotes>> designNotesList;
public void setAdministartor(Administartor admin){
this.admin = admin;
}
public Administartor getAdministartor() {
return admin;
}
public DesignSec getDesignSec() {
return designSec;
}
public void setDesignSec(DesignSec designSec) {
this.designSec = designSec;
}
public List<JAXBElement<DesignNotes>> getDlrnotes() {
return designNotesList;
}
public void setDlrnotes(List<JAXBElement<DesignNotes>> designNotesList) {
this.designNotesList = designNotesList;
}
}
Administartor.java
package org.manjunath.jaxbconversions.beans;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "Administartor")
public class Administartor {
#XmlElement(name = "circuitId")
private String circuitId;
#XmlElement(name = "processId")
private String processId;
#XmlElement(name = "version")
private String version;
#XmlElement(name = "circuitReferenceValue")
private String circuitReferenceValue;
#XmlElement(name = "property")
private String property;
public String getcircuitId() {
return circuitId;
}
public void setcircuitId(String circuitId) {
this.circuitId = circuitId;
}
public String getprocessId() {
return processId;
}
public void setprocessId(String processId) {
this.processId = processId;
}
public String getVer() {
return version;
}
public void setVer(String version) {
this.version = version;
}
public String getcircuitReferenceValue() {
return circuitReferenceValue;
}
public void setcircuitReferenceValue(String circuitReferenceValue) {
this.circuitReferenceValue = circuitReferenceValue;
}
public String getproperty() {
return property;
}
public void setproperty(String property) {
this.property = property;
}
}
DesignSec.java
package org.manjunath.jaxbconversions.beans;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "designSec")
public class DesignSec {
#XmlElement (name = "priloc")
private String priloc;
#XmlElement (name = "secloc")
private String secloc;
#XmlElement (name = "remarks")
private String remarks;
public String getpriloc() {
return priloc;
}
public void setpriloc(String priloc) {
this.priloc = priloc;
}
public String getSecloc() {
return secloc;
}
public void setSecloc(String secloc) {
this.secloc = secloc;
}
public String getremarks() {
return remarks;
}
public void setEcspc(String remarks) {
this.remarks = remarks;
}
}
DesignNotes.java
package org.manjunath.jaxbconversions.beans;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "designNotes")
#XmlAccessorType(XmlAccessType.FIELD)
public class DesignNotes {
#XmlElement (name = "notesNumber")
private String notesNumber;
#XmlElement (name = "notes")
private String notes;
public String getnotesNumber() {
return notesNumber;
}
public void setnotesNumber(String notesNumber) {
this.notesNumber = notesNumber;
}
public String getNotes() {
return notes;
}
public void setNotes(String notes) {
this.notes = notes;
}
}
And I found somewhere the #XmlRegistry and #XmlElementDecl will solve my problem.
But I'm not so good with these annotations, but I tried by using ObjectFactory.java class. No use of this class
ObjectFactory.java
package org.manjunath.jaxbconversions.factory;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
import org.manjunath.jaxbconversions.beans.DesignNotes;
#XmlRegistry
public class ObjectFactory {
private final static QName _DesignNotes_QNAME = new QName("designNotes");
public ObjectFactory(){
}
#XmlElementDecl(name="designNotes")
public JAXBElement<DesignNotes> createDesignNotes(DesignNotes value) {
return new JAXBElement<DesignNotes>(_DesignNotes_QNAME, DesignNotes.class, value);
}
}
Please suggest me to solve this problem
In your class DesignTheory the definition
#XmlElementWrapper
#XmlElementRef(name = "designNotes")
private List<JAXBElement<DesignNotes>> designNotesList;
is wrong.
In your XML you have
<designNotes>
...
</desinNotes>
<designNotes>
...
</designNotes>
...
But you do not have an additional wrapper around these <designNotes> like this
<designNotesList>
<designNotes>
...
</desinNotes>
<designNotes>
...
</designNotes>
...
<designNotesList>
That's why you need to remove the #XmlElementWrapper annotation.
And you should change its type from List<JAXBElement<DesignNotes>>
to List<DesignNotes>. So you end up with
#XmlElementRef(name = "designNotes")
private List<DesignNotes> designNotesList;
Also change the associated getter and setter from List<JAXBElement<DesignNotes>>
to List<DesignNotes>.
Then you don't need the ObjectFactory anymore and can remove it completely.
I verified the corrected classes with your XML and the following test-code
#Test
public void testUnmarshall() throws Exception {
JAXBContext context = JAXBContext.newInstance(DesignTheory.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
File file = new File("design-theory.xml");
DesignTheory designTheory = (DesignTheory) unmarshaller.unmarshal(file);
Assert.assertNotNull(designTheory.getDlrnotes());
Assert.assertEquals(4, designTheory.getDlrnotes().size());
}
The unmarshalled designTheory correctly has a non-null List<DesignNotes> with 4 elements.
I have a not-little problem with my current project, and probably you can help me with this...
When I worked before with xml messages, marshalling converted java objects to xml, where the java object attributes were set to xml nodes. But now I need to set that object attributes to xml node attributes, as I show here:
<Identification_List counter="">
<Identification number="XXXXXXX" letter="X" name="PERSON">
<TravelList counter="">
<Travel travelType="">
</TravelList>
</Identification>
</Identification_List>
How can I do this? What framework should I use? Thank you!
Edit: Example java class:
public class Identification {
private int number;
private char letter;
private String name;
private List<Travel> travelList;
//Add here constructors, getters and setters
}
That java class is the one that should be marshalled, where number, letter and name are the xml object properties
You need to add the appropriate JAXB annotations to your classes, to tell JAXB how to map your class to XML. For example:
#XmlRootElement(name = "Identification_List")
#XmlAccessorType(XmlAccessType.FIELD)
public class IdentificationList {
#XmlAttribute
private int counter;
#XmlElement(name = "Identification")
private List<Identification> identifications;
// getters and setters
}
#XmlAccessorType(XmlAccessType.FIELD)
public class Identification {
#XmlAttribute
private int number;
#XmlAttribute
private char letter;
#XmlAttribute
private String name;
#XmlElementWrapper(name = "TravelList")
#XmlElement(name = "Travel")
private List<Travel> travels;
// getters and setters
}
#XmlAccessorType(XmlAccessType.FIELD)
public class Travel {
#XmlAttribute
private String travelType;
// getters and setters
}
Do you need to convert java to xml ? use the same library ,
Here an Example
1-IdentificationList Class
package test;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
#XmlRootElement(name = "Identification_List")
public class IdentificationList {
private int counter;
private List<Identification> identificationList;
public IdentificationList() {
}
public IdentificationList(List<Identification> identificationList) {
this.identificationList = identificationList;
this.counter = identificationList == null ? 0 : identificationList.size();
;
}
#XmlElement(name = "Identification")
public List<Identification> getIdentificationList() {
return identificationList;
}
public void setIdentificationList(List<Identification> identificationList) {
this.identificationList = identificationList;
}
#XmlAttribute
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
}
2-Identification Class
package test;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
#XmlType(propOrder = {"number", "letter", "name","travelList"})
public class Identification {
private int number;
private String letter;
private String name;
private TravelList travelList;
public Identification() {
}
public Identification(int number, String letter, String name, TravelList travelList) {
this.number = number;
this.letter = letter;
this.name = name;
this.travelList = travelList;
}
#XmlAttribute
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
#XmlAttribute
public String getLetter() {
return letter;
}
public void setLetter(String letter) {
this.letter = letter;
}
#XmlAttribute
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElement(name = "TravelList")
public TravelList getTravelList() {
return travelList;
}
public void setTravelList(TravelList travelList) {
this.travelList = travelList;
}
}
3-TravelList Class
package test;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import java.util.List;
public class TravelList {
private List<Travel>travels;
private int counter;
public TravelList() {
}
public TravelList(List<Travel> travels) {
this.travels = travels;
this.counter=travels==null?0:travels.size();
}
#XmlElement(name = "Travel")
public List<Travel> getTravels() {
return travels;
}
public void setTravels(List<Travel> travels) {
this.travels = travels;
}
#XmlAttribute
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
}
4-Travel Class
package test;
import javax.xml.bind.annotation.XmlAttribute;
public class Travel {
private String travelType;
public Travel() {
}
public Travel(String travelType) {
this.travelType = travelType;
}
#XmlAttribute
public String getTravelType() {
return travelType;
}
public void setTravelType(String travelType) {
this.travelType = travelType;
}
}
5-IdentificationToXML Class
package test;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import java.io.FileOutputStream;
import java.util.ArrayList;
public class IdentificationToXML {
public static void main(String ...args) throws Exception {
JAXBContext contextObj = JAXBContext.newInstance(IdentificationList.class);
Marshaller marshallerObj = contextObj.createMarshaller();
marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Travel travel1=new Travel("My First Travel");
Travel travel2=new Travel("My Second Travel");
Travel travel3=new Travel("My Third Travel");
Travel travel4=new Travel("My Fourth Travel");
ArrayList<Travel> list=new ArrayList<Travel>();
list.add(travel1);
list.add(travel2);
ArrayList<Travel> list2=new ArrayList<Travel>();
list2.add(travel3);
list2.add(travel4);
Identification identification1=new Identification(111,"c","My Name",new TravelList(list));
Identification identification2=new Identification(222,"d","My Name",new TravelList(list2));
ArrayList<Identification> list3=new ArrayList<Identification>();
list3.add(identification1);
list3.add(identification2);
IdentificationList identification=new IdentificationList(list3);
marshallerObj.marshal(identification, new FileOutputStream("identification.xml"));
}
}
6-Output :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Identification_List counter="2">
<Identification number="111" letter="c" name="My Name">
<TravelList counter="2">
<Travel travelType="My First Travel"/>
<Travel travelType="My Second Travel"/>
</TravelList>
</Identification>
<Identification number="222" letter="d" name="My Name">
<TravelList counter="2">
<Travel travelType="My Third Travel"/>
<Travel travelType="My Fourth Travel"/>
</TravelList>
</Identification>
</Identification_List>
I am having an issue where the binding of a class against a XML element was not successfully. Instead it returns NullPointerException. Below is the sample XML
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sh="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns:getNumberResponse
xmlns="http://ccm.intra.bt.com/manageServiceFault/2006/06" xmlns:ns="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:cds="http://capabilities.nat.bt.com/xsd/manageServiceFault/2010/06/Contact/Details"
xmlns:sh="http://wsi.nat.bt.com/2005/06/StandardHeader/"
xsi:schemaLocation="http://ccm.intra.bt.com/manageServiceFault/2006/06 MSF_5.0.xsd">
<sh:standardHeader>
<sh:e2e>
<sh:E2EDATA>E2E.graphID=2.1,E2E.from=ORESB,E2E.to=ORautofix,E2E.compTxnName=FaultProcessing,E2E.compTxnID=385h6g8lbh,E2E.busTxnStage=REQ,E2E.busProcID=1-CKMT1EEV,E2E.busProcType=ManageFaultRequests,E2E.busTxnSeq=385h5smgod,E2E.threadID=385h6g8koz,E2E.busTxnSys=AddFault,tradingPartnerId=735380615,E2E.busTxnHdr=PCK002069,E2E.busTxnType=AddFault,E2E.busProcOriginator=ORESB-default,E2E.busTxnUsr=siebel,E2E.busTxnLoc=UNKNOWN,E2E.threadID.4=APP10639:385h6g75io:385h6g8koz,E2E.threadID.3=:385h6fq4wv,E2E.threadID.2=ORSiebel:385h5smh48:385h6fq4wv,E2E.threadID.1=:
</sh:E2EDATA>
</sh:e2e>
<sh:serviceState>
<sh:stateCode>OK</sh:stateCode>
<sh:errorCode />
<sh:errorDesc />
<sh:errorText />
<sh:errorTrace />
</sh:serviceState>
</sh:standardHeader>
<actionRequestId />
<appointment>
<apptRequired>Y</apptRequired>
<apptSlot>0</apptSlot>
<apptType>Type</apptType>
<apptReference>Reference001</apptReference>
<earliestApptSlot>1</earliestApptSlot>
<earliestDate>2015-05-25T01:00:00</earliestDate>
</appointment>
<endUserDetails>
<firstName>Chris</firstName>
<lastName>Wong</lastName>
<priTelephone>+60123333333</priTelephone>
<secTelephone>+60123333334</secTelephone>
<cssDBID>1234</cssDBID>
</endUserDetails>
<serviceAffectingFlag>N</serviceAffectingFlag>
<number>123456789</number>
<service>
<serviceId xsi:nil="false">ONEA20160721_0067</serviceId>
</service>
<service>
<serviceId xsi:nil="false">ONEA20160721_0068</serviceId>
</service>
</ns:getNumberResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
And below is my of domain class: UserDetail
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "endUserDetails")
#XmlAccessorType(XmlAccessType.FIELD)
public class UserDetail {
private String firstName;
private String lastName;
private String priTelephone;
private String secTelephone;
private String cssDBID;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPriTelephone() {
return priTelephone;
}
public void setPriTelephone(String priTelephone) {
this.priTelephone = priTelephone;
}
public String getSecTelephone() {
return secTelephone;
}
public void setSecTelephone(String secTelephone) {
this.secTelephone = secTelephone;
}
public String getCssDBID() {
return cssDBID;
}
public void setCssDBID(String cssDBID) {
this.cssDBID = cssDBID;
}
}
This is Appointment
package com.bt.automation.domain;
import java.util.Date;
public class Appointment {
private String apptRequired;
private String apptSlot;
private String apptType;
private String apptReference;
private String earliestApptSlot;
private Date earliestDate;
public String getApptRequired() {
return apptRequired;
}
public void setApptRequired(String apptRequired) {
this.apptRequired = apptRequired;
}
public String getApptSlot() {
return apptSlot;
}
public void setApptSlot(String apptSlot) {
this.apptSlot = apptSlot;
}
public String getApptType() {
return apptType;
}
public void setApptType(String apptType) {
this.apptType = apptType;
}
public String getApptReference() {
return apptReference;
}
public void setApptReference(String apptReference) {
this.apptReference = apptReference;
}
public String getEarliestApptSlot() {
return earliestApptSlot;
}
public void setEarliestApptSlot(String earliestApptSlot) {
this.earliestApptSlot = earliestApptSlot;
}
public Date getEarliestDate() {
return earliestDate;
}
public void setEarliestDate(Date earliestDate) {
this.earliestDate = earliestDate;
}
}
and lastly another domain class Response
package com.bt.automation.domain;
import java.util.List;
import javax.xml.bind.annotation.*;
import com.bt.automation.domain.autofix.UserDetail;
#XmlRootElement(name = "Envelope")
#XmlAccessorType(XmlAccessType.FIELD)
public class Response {
private long number;
private String actionRequestId;
private String serviceAffectingFlag;
private Appointment appointment;
private UserDetail userDetail;
private List<MyService> service;
public long getNumber() {
return number;
}
public void setNumber(long number) {
this.number = number;
}
public String getActionRequestId() {
return actionRequestId;
}
public void setActionRequestId(String actionRequestId) {
this.actionRequestId = actionRequestId;
}
public String getServiceAffectingFlag() {
return serviceAffectingFlag;
}
public void setServiceAffectingFlag(String serviceAffectingFlag) {
this.serviceAffectingFlag = serviceAffectingFlag;
}
public List<MyService> getService() {
return service;
}
public void setService(List<MyService> service) {
this.service = service;
}
public Appointment getAppointment() {
return appointment;
}
public void setAppointment(Appointment appointment) {
this.appointment = appointment;
}
public UserDetail getUserDetail() {
return userDetail;
}
public void setUserDetail(UserDetail userDetail) {
this.userDetail = userDetail;
}
}
In the code, I would like to bind class UserDetail to XML element endUserDetails. So below is my code
package com.bt.automation.xml;
import java.io.FileReader;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import com.bt.automation.domain.Appointment;
import com.bt.automation.domain.MyService;
import com.bt.automation.domain.Response;
import com.bt.automation.domain.autofix.UserDetail;
public class UnmarshalResponse {
public static void main(String[] args) throws Exception {
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("response.xml"));
xsr.nextTag(); // Advance to Envelope tag
int i = 0;
while (!xsr.getLocalName().equals("getNumberResponse")) {
System.out.println(i + xsr.getLocalName());
xsr.nextTag();
i = i + 1;
}
System.out.println("Current element: " + xsr.getLocalName());
System.out.println("Namespace: " + xsr.getNamespaceContext().getNamespaceURI("ns"));
JAXBContext jc = JAXBContext.newInstance(Response.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
JAXBElement<Response> je = unmarshaller.unmarshal(xsr, Response.class);
xsr.close();
Response response = je.getValue();
System.out.println("Object: " + response);
System.out.println("Number: " + response.getNumber());
System.out.println("Request ID: " + response.getActionRequestId());
System.out.println("Flag: " + response.getServiceAffectingFlag());
Appointment app = response.getAppointment();
System.out.println("Appointment.apptRequired: " + app.getApptRequired());
System.out.println("Appointment.apptReference: " + app.getApptReference());
System.out.println("Appointment.apptType: " + app.getApptType());
System.out.println("Appointment.earliestApptSlot: " + app.getEarliestApptSlot());
System.out.println("Appointment.apptSlot: " + app.getApptSlot());
System.out.println("Appointment.earliestDate: " + app.getEarliestDate());
UserDetail userDetail = response.getUserDetail();
System.out.println("UserDetail.getFirstName: " + userDetail.getFirstName());
System.out.println("UserDetail.getLastName: " + userDetail.getLastName());
System.out.println("UserDetail.getPriTelephone: " + userDetail.getPriTelephone());
System.out.println("UserDetail.getSecTelephone: " + userDetail.getSecTelephone());
System.out.println("UserDetail.getCssDBID: " + userDetail.getCssDBID());
List<MyService> list = response.getService();
for (i = 0; i < list.size(); i++) {
System.out.println("Service " + i + ": " + response.getService().get(i).getServiceId());
}
}
}
However, it returns NullPointerException when I run the code. One question here, is it a must that domain class must be the same name with the bound XML element?
You got a NullPointerException because response.getAnnotation() was null. Actually all properties of response were null because none of the corresponding XML contents was successfully unmarshalled.
The reason is: your Java classes completely ignore XML namespaces.
The namespace in the ns:getNumberResponse XML element and all the
sub-elements without namespace-prefix (appointment, endUserDetails, service, ...)
don't match the namespaces in your Java classes.
For learning more about JAXB annotations I suggest to read this tutorial and the javadoc of package javax.xml.bind.annotation especially of XmlElement and XmlRootElement.
For solving your problems you have two options:
change the XML contents to match your existing Java classes
or change the Java classes to match your existing XML content.
The following solution assumes you prefer to change the Java classes and don't change the XML content.
Class Response:
In #XmlRootElement you need to set the correct name and namespace.
For all properties you need to set the correct namespace.
For property userDetail you need to set name = "endUserDetails".
#XmlRootElement(name = "getNumberResponse", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
#XmlAccessorType(XmlAccessType.FIELD)
public class Response {
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private long number;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String actionRequestId;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String serviceAffectingFlag;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private Appointment appointment;
#XmlElement(name = "endUserDetails", namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private UserDetail userDetail;
#XmlElement(name = "service", namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private List<MyService> service;
// ... getters/setters
}
Class Appointment:
For all properties you need to set the correct namespace.
#XmlAccessorType(XmlAccessType.FIELD)
public class Appointment {
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String apptRequired;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String apptSlot;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String apptType;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String apptReference;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String earliestApptSlot;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private Date earliestDate;
// ... getters/setters
}
Class UserDetail:
For all properties you need to set the correct namespace.
You can omit #XmlRootElement, because it has no effect in a non-root element.
#XmlAccessorType(XmlAccessType.FIELD)
public class UserDetail {
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String firstName;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String lastName;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String priTelephone;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String secTelephone;
#XmlElement(namespace = "http://ccm.intra.bt.com/manageServiceFault/2006/06")
private String cssDBID;
// ... getters/setters
}
You didn't post your class MyService. I assume you need to do similar corrections there, too.
I create an java class:
public class ReturnObj {
private String returncode;
private String returndesc;
private Pkg pkg;
public String getReturncode() {
return returncode;
}
public void setReturncode(String returncode) {
this.returncode = returncode;
}
public String getReturndesc() {
return returndesc;
}
public void setReturndesc(String returndesc) {
this.returndesc = returndesc;
}
}
and other class:
public class Pkg {
private String packagecode;
private String cycle;
private String price;
private String desc;
public String getPackagecode() {
return packagecode;
}
public void setPackagecode(String packagecode) {
this.packagecode = packagecode;
}
public String getCycle() {
return cycle;
}
public void setCycle(String cycle) {
this.cycle = cycle;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
And I Want to convert object ReturnObj to this XML
<return>
<returncode>1</returncode>
<returndesc>DANG_KY_THANH_CONG</returndesc>
<package>
<packagecode>BD30</packagecode>
<cycle>1</cycle>
<price>15000</price>
<desc> BD30</desc>
</package>
</return>
So how do I serialize an attribute pkg to package in XML? Because Java doesn't allow to name variable as an keyword anh package is an keyword in Java !
You can use JAXB marshling in your class it will convert the object to XML, here is link to help you JAXB Marshling
Try xstream
XStream xstream = new XStream();
xstream.alias("package", Pkg.class);
String xml = xstream.toXML(myReturnObj);
You can use JAXB API that comes with java for converting java object to XML.
Below is the code that will solve your requirement.
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "return")
public class ReturnObj {
private String returncode;
private String returndesc;
private Pkg pkg;
public Pkg getPkg() {
return pkg;
}
#XmlElement(name = "package")
public void setPkg(Pkg pkg) {
this.pkg = pkg;
}
public String getReturncode() {
return returncode;
}
#XmlElement(name = "returncode")
public void setReturncode(String returncode) {
this.returncode = returncode;
}
public String getReturndesc() {
return returndesc;
}
#XmlElement(name = "returndesc")
public void setReturndesc(String returndesc) {
this.returndesc = returndesc;
}
}
#XmlRootElement
public class Pkg {
private String packagecode;
private String cycle;
private String price;
private String desc;
public String getPackagecode() {
return packagecode;
}
#XmlElement(name="packagecode")
public void setPackagecode(String packagecode) {
this.packagecode = packagecode;
}
public String getCycle() {
return cycle;
}
#XmlElement(name="cycle")
public void setCycle(String cycle) {
this.cycle = cycle;
}
public String getPrice() {
return price;
}
#XmlElement(name="price")
public void setPrice(String price) {
this.price = price;
}
public String getDesc() {
return desc;
}
#XmlElement
public void setDesc(String desc) {
this.desc = desc;
}
}
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class JAXBExample {
private static final String FILE_NAME = "C:\\ru\\jaxb-returnObj.xml";
public static void main(String[] args) {
ReturnObj returnObj = new ReturnObj();
returnObj.setReturncode("1");
returnObj.setReturndesc("DANG_KY_THANH_CONG");
Pkg pkg = new Pkg();
pkg.setCycle("1");
pkg.setPrice("15000");
pkg.setDesc("BD30");
returnObj.setPkg(pkg);
jaxbObjectToXML(returnObj);
}
private static void jaxbObjectToXML(ReturnObj emp) {
try {
JAXBContext context = JAXBContext.newInstance(ReturnObj.class);
Marshaller m = context.createMarshaller();
// for pretty-print XML in JAXB
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
// Write to System.out, this will print the xml on console
m.marshal(emp, System.out);
// Write to File
m.marshal(emp, new File(FILE_NAME));
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Explanation:
#XmlRootElement: This is a must have annotation for the Object to be used in JAXB. It defines the root element for the XML content.
#XmlElement: This will create the element. If you want to give some other name to the xml element when converting java object to xml then you can pass name attribute to the #XmlElement Example:
#XmlElement(name = "package")
Execute above code to see the desired output.
Happy Coding.
i have an XML document that have some configuration information i have to access the information from a java class.I am able to access the information using java unmarshalling,but the problem is that i can not access a specific portion of the xml file.Every time i am accessing the information i have to take the root tag first i.e i only can access the root tag elements,but i need to access the tag that is in the another section.This is my XML file
<?xml version="1.0" encoding="UTF-8"?>
<adapter name="Hua_GPRS_CS5_4.7" type="ASN.1" version="1.0" description="Huawie GPRS Output CDR Version 4.7"
execclass="hua.gprs.HuaGPRSFileExecutor" parallel="1" mode="server" statusfile="HuaGPRSStatus.csv" merge_factor="1" active="true">
<dirconfig>
<Poll protocol="" host="" path="./data/huagprs/source" pwd="" user="" clogging="true" startdir="" enddir=""
pattern="(.*)\.(\d{6})(\d{6})(\d{4})_(.*)" metafields="fileName,exchange,fileDate,fileTime,fileSeq,junk"/>
<Source path="./data/huagprs/source" clogging="false"/>
<Backup path="./data/huagprs/backup" active="false"/>
<Staging path="./data/huagprs/staging" clogging="false"/>
<Output path="./data/huagprs/output" clogging="false" compress="gz"/>
<Error path="./data/huagprs/error" clogging="true"/>
<Target protocol="" host="" path="/" pwd="" user="" active="true"/>
</dirconfig>
<dbConf id="1" name ="jjj" drivername="oracle.jdbc.driver.OracleDriver" hostname="localhost" portname="1521" dbname="rrr" servicename="orcl" user="param" password="param" sid="orcl">
<TableConfig ID= "1" TableName="">
</TableConfig>
</dbConf>
</adapter>
i can access only the elements of the adapter tag.but what i need to use dbconf.. here i am posting the class es i am using to get the value of the adapter tag.The model class
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Adapter {
String name;
String type;
String version;
String description;
String execclass;
String parallel;
String mode;
String statusfile;
String merge_factor;
String active;
String drivername;
public String getDrivername() {
return drivername;
}
#XmlAttribute
public void setDrivername(String drivername) {
this.drivername = drivername;
}
public String getName() {
return name;
}
#XmlAttribute
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
#XmlAttribute
public void setType(String type) {
this.type = type;
}
public String getVersion() {
return version;
}
#XmlAttribute
public void setVersion(String version) {
this.version = version;
}
public String getDescription() {
return description;
}
#XmlAttribute
public void setDescription(String description) {
this.description = description;
}
public String getExecclass() {
return execclass;
}
#XmlAttribute
public void setExecclass(String execclass) {
this.execclass = execclass;
}
public String getParallel() {
return parallel;
}
#XmlAttribute
public void setParallel(String parallel) {
this.parallel = parallel;
}
public String getMode() {
return mode;
}
#XmlAttribute
public void setMode(String mode) {
this.mode = mode;
}
public String getStatusfile() {
return statusfile;
}
#XmlAttribute
public void setStatusfile(String statusfile) {
this.statusfile = statusfile;
}
public String getMerge_factor() {
return merge_factor;
}
#XmlAttribute
public void setMerge_factor(String merge_factor) {
this.merge_factor = merge_factor;
}
public String getActive() {
return active;
}
#XmlAttribute
public void setActive(String active) {
this.active = active;
}
}
The main class to get the values
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class ReadXML {
/**
* #param args
*/
public static void main(String[] args) {
try {
File file = new File("./file/config.ds");
JAXBContext jaxbContext2 = JAXBContext.newInstance(Adapter.class);
Unmarshaller jaxbUnmarshaller2 = jaxbContext2.createUnmarshaller();
Adapter db2 = (Adapter) jaxbUnmarshaller2.unmarshal(file);
System.out.println(db2.active);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
You can use a StAX XMLStreamReader to advance parse the XML document. Then advance to the XML element you want to unmarshal. Then use the unmarshal method that takes XMLStreamReader as a parameter.
http://blog.bdoughan.com/2012/08/handle-middle-of-xml-document-with-jaxb.html