Eclipse MOXy Unmarshall Exception: Missing class indicator field from database row - java

I am having issue while unmarshalling an XML message. However, marshaling works fine. I am using inheritance via XML class extractor annotation.
Can you please help me identify the issue here?
Exception:
Caused by: Exception [EclipseLink-44] (Eclipse Persistence Services - 2.7.3.v20180807-4be1041): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Missing class indicator field from database row [org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl#631330c].
Descriptor: XMLDescriptor(main.TransitionGuard --> [])
at org.eclipse.persistence.exceptions.DescriptorException.missingClassIndicatorField(DescriptorException.java:961)
at org.eclipse.persistence.internal.oxm.XMLRelationshipMappingNodeValue.processChild(XMLRelationshipMappingNodeValue.java:85)
at org.eclipse.persistence.internal.oxm.XMLCompositeObjectMappingNodeValue.startElement(XMLCompositeObjectMappingNodeValue.java:385)
at org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.startElement(UnmarshalRecordImpl.java:864)
at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parseEvent(XMLStreamReaderReader.java:138)
at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:102)
at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:89)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:940)
at org.eclipse.persistence.internal.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:655)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:637)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:216)
... 1 more
Here are my classes:
Transition
public class Transition {
private String from;
private String to;
TransitionGuard guard;
public Transition() {
// For Moxy
}
public Transition(String from, String to) {
this(from, to, null);
}
public Transition(String from, String to, TransitionGuard guard) {
setFrom(from);
setTo(to);
setTransitionGuard(guard);
}
#XmlAttribute(name = "from")
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
#XmlAttribute(name = "to")
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
#XmlElement(name = "guard")
public TransitionGuard getTransitionGuard() {
return guard;
}
public void setTransitionGuard(TransitionGuard guard) {
this.guard = guard;
}
}
TransitionGuard
#XmlClassExtractor(TransitionGuardClassExtractor.class)
#XmlSeeAlso({ ExceptionGuard.class, ScriptedGuard.class })
public abstract class TransitionGuard {
}
TransitionGuardClassExtractor
public class TransitionGuardClassExtractor extends ClassExtractor {
#Override
public Class extractClassFromRow(Record record, Session session) {
if (null != record.get("/abpm:exception-guard")) {
return ExceptionGuard.class;
} else if (null != record.get("/abpm:scripted-guard")) {
return ScriptedGuard.class;
}
return null;
}
}
ScriptedGuard
public class ScriptedGuard extends TransitionGuard {
String script;
public ScriptedGuard() {
}
public ScriptedGuard(String script) {
setScript(script);
}
#XmlPath("abpm:scripted-guard/text()")
#XmlCDATA
public String getScript() {
return script;
}
public void setScript(String script) {
this.script = script;
}
}
TestPE
#XmlRootElement(name = "TestPE")
public class TestPE {
List<Transition> transition;
public List<Transition> getTransition() {
return transition;
}
public void setTransition(List<Transition> transition) {
this.transition = transition;
}
}
package-info
#XmlSchema(namespace = "jelly:com.werken.blissed.jelly.BlissedTagLibrary", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = {
#XmlNs(prefix = "version", namespaceURI = "4.7"), #XmlNs(prefix = "j", namespaceURI = "jelly:core"),
#XmlNs(prefix = "abpm", namespaceURI = "jelly:com.adeptia.indigo.jelly.IndigoTagLibrary"),
#XmlNs(prefix = "pd", namespaceURI = "jelly:com.adeptia.indigo.pd.ProcessDesignerTagLibrary"),
#XmlNs(prefix = "", namespaceURI = "jelly:com.werken.blissed.jelly.BlissedTagLibrary") })
package main;
import javax.xml.bind.annotation.XmlNs;
Input XML
<?xml version="1.0" encoding="UTF-8"?>
<TestPE xmlns:version = "4.7" xmlns:j = "jelly:core" xmlns:abpm = "jelly:com.adeptia.indigo.jelly.IndigoTagLibrary" xmlns:pd = "jelly:com.adeptia.indigo.pd.ProcessDesignerTagLibrary" xmlns = "jelly:com.werken.blissed.jelly.BlissedTagLibrary" >
<transition from="state-BPMN:GATEWAY:XOR_DATA_GATEWAY-892276265" to="state-BPMN:EVENT:END_EVENT-892276264" >
<guard>
<abpm:scripted-guard><![CDATA[*** Script ***]]></abpm:scripted-guard>
</guard>
</transition>
</TestPE>
Demo code
Map<String, String> properties = new HashMap<String, String>();
properties.put("javax.xml.bind.context.factory", "org.eclipse.persistence.jaxb.JAXBContextFactory");
JAXBContext jc = JAXBContext.newInstance(new Class[] { TestPE.class }, properties);
// JAXB unmarshall
Unmarshaller unmarshaller = jc.createUnmarshaller();
TestPE testPE = (TestPE) unmarshaller.unmarshal(new File("resources/Transition.xml"));

Currently, MOXy requires that the inheritance indicator is in an XML attribute. If it is in an XML element you could use the following approach with an XmlAdapter.

Related

How to unmarshal an XML String contain diffgr to JAVA POJO

Hi I got a below XML string which contain diffgram
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Result xmlns="">
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet xmlns="">
<DT1 diffgr:id="DT11" msdata:rowOrder="0">
<TEST_NO>93481324345</TEST_NO>
<TEST_DESC>Description1</TEST_DESC>
</DT1>
<DT1 diffgr:id="DT12" msdata:rowOrder="1">
<TEST_NO>93481366454</TEST_NO>
<TEST_DESC>Description2</TEST_DESC>
</DT1>
<DT1 diffgr:id="DT13" msdata:rowOrder="2">
<TEST_NO>934813267783</TEST_NO>
<TEST_DESC>Description3</TEST_DESC>
</DT1>
</NewDataSet>
</diffgr:diffgram>
</Result>
How can I unmarshal this String to java POJO using JAXB ?
Below are the current POJO seems not able to bind by this way.
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"diffgr",
"newDataSet",
"dt"
})
#XmlRootElement(name="Result")
public class Response {
#XmlElement(name = "diffgr:diffgram")
protected String diffgr;
#XmlElement(name = "NewDataSet")
protected String newDataSet;
#XmlElement(name = "DT1")
protected List<Response.DT> dt;
public String getDiffgr() {
return diffgr;
}
public void setDiffgr(String diffgr) {
this.diffgr = diffgr;
}
public String getNewDataSet() {
return newDataSet;
}
public void setNewDataSet(String newDataSet) {
this.newDataSet = newDataSet;
}
public List<Response.DT> getDt() {
if (dt == null) {
dt = new ArrayList<Response.DT>();
}
return this.dt;
}
public void setDt(List<Response.DT> dt) {
this.dt = dt;
}
#Override
public String toString() {
return "Response [diffgr=" + diffgr + ", newDataSet=" + newDataSet + ", dt=" + dt + "]";
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"testNo",
"testDesc"
})
public static class DT {
#XmlElement(name = "TEST_NO")
protected String testNo;
#XmlElement(name = "TEST_DESC")
protected String testDesc;
public String getTestNo() {
return testNo;
}
public void setTestNo(String testNo) {
this.testNo = testNo;
}
public String getTestDesc() {
return testDesc;
}
public void setTestDesc(String testDesc) {
this.testDesc = testDesc;
}
#Override
public String toString() {
return "DT [testNo=" + testNo + ", testDesc=" + testDesc + "]";
}
}
}
I'm using the below sample code to unmarshal the String
JAXBContext jaxbContext = JAXBContext.newInstance(Response.class);
Unmarshaller jaxbUnMarshaller = jaxbContext.createUnmarshaller();
Response response = (Response)jaxbUnMarshaller.unmarshal(new StringReader(xml));
When execute there is no any error throwing out while the POJO was empty.
How to unmarshal an XML String contain diffgr to JAVA POJO like this case?

changing mapping field for #XmlValue in #JsonProperty

I have an element "SubElement2" that has value and attribute.
Working :
My Annotation are
#XmlValue
#JsonProperty(value="content")
private String value;
Request in XML : <SubElement2 parameterName = "tested">ELEMENT_2_TAG_VAL</SubElement2>
TO JSON :
{
"SubElement2" : {
"content" : "ELEMENT_2_TAG_VAL",
"parameterName" : "tested"
}
}
Here I want to change the property name content to myOwnContent
Not Working:
Modified annotations :
#XmlValue
#JsonProperty(value="myOwnContent") // Modified
private String value;
Request in XML : <SubElement2 parameterName = "tested">ELEMENT_2_TAG_VAL</SubElement2>
For the above annotation change, I'm facing below exception:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "content" (class SubElement2), not marked as ignorable (2 known properties: "parameterName", "myOwnContent"])
at [Source: (String)"{"SubElement2":{"parameterName":"tested","content":"ELEMENT_2_TAG_VAL"}}"; line: 1, column: 53] (through reference chain: Element1["SubElement2"]->SubElement2["content"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:60)
Below is my code :
ObjectFactory.java
#XmlRegistry
public class ObjectFactory {
public SubElement2 createSubElement2() {
return new SubElement2();
}
}
MainProgram.java
public class MainProgram {
public static void main(String[] args) throws ClassNotFoundException, IOException {
String request = "<SubElement2 parameterName = \"tested\">ELEMENT_2_TAG_VAL</SubElement2>";
System.out.println("Request in XML : "+request);
JSONObject jObject = XML.toJSONObject(request);
ObjectMapper mapper = createCombinedObjectMapper();
Object json = mapper.readValue(jObject.toString(), Class.forName("Element1"));
String output = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
System.out.println(output);
}
private static ObjectMapper createCombinedObjectMapper() {
return new ObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, false)
.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
.setAnnotationIntrospector(createJaxbJacksonAnnotationIntrospector());
}
private static AnnotationIntrospector createJaxbJacksonAnnotationIntrospector() {
final AnnotationIntrospector jaxbIntrospector = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
final AnnotationIntrospector jacksonIntrospector = new JacksonAnnotationIntrospector();
return AnnotationIntrospector.pair(jacksonIntrospector, jaxbIntrospector);
}
}
SubElement2.java
#XmlRootElement(name = "SubElement2")
public class SubElement2 {
#XmlValue
#JsonProperty(value="myOwnContent")
private String value;
#JsonProperty(value="parameterName",required=true)
#XmlAttribute(required = true)
protected String parameterName;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getParameterName() {
return parameterName;
}
public void setParameterName(String parameterName) {
this.parameterName = parameterName;
}
}
Element1.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "element1", propOrder = {
"element1"
})
#XmlRootElement(name = "Element1")
public class Element1 {
#XmlElement(name="SubElement2")
protected SubElement2 subElement2;
public SubElement2 getSubElement2() {
return subElement2;
}
public void setSubElement2(SubElement2 subElement2) {
this.subElement2 = subElement2;
}
}
I'm using Jackson version : 2.9.7
Help me to solve this exception ,thanks in advance
What I want to do :
I want to have jsonproperty as myOwnContent because content is already used by another attribute in XML in my existing implementation. (Existing implementation doesn't have JSON suuport , we are adding JSON support)

java soap web service how to get a list from a xml request

I work with a SOAP web service. I want to recover the list productOrder from a java. My problem is that the list productOrder recovered from the java class is zero.
I dont't know how to recover this list from the java.
Below I explain my classes:
This is the request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://uciext.ws.hw3/wsdl">
<soapenv:Header/>
<soapenv:Body>
<wsdl:processOrder>
<!--Optional:-->
<arg0>
<vendorCode>330029</vendorCode>
<vendorName>My Shop</vendorName>
<orderNumber>1000339</orderNumber>
<!--1 or more repetitions:-->
<wsdl:productOrder>
<!--Optional:-->
<productSku>111</productSku>
<!--Optional:-->
<productName>Kindle Fire</productName>
<!--Optional:-->
<orderQuantity>5</orderQuantity>
</wsdl:productOrder>
</arg0>
</wsdl:processOrder>
</soapenv:Body>
</soapenv:Envelope>
I have the Order.java to parse this xml
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"vendorCode",
"vendorName",
"orderNumber",
"productOrder"
})
#XmlRootElement(name = "order")
public class Order {
#XmlElement(required = true)
protected String vendorCode;
#XmlElement(required = true)
protected String vendorName;
#XmlElement(required = true)
protected String orderNumber;
#XmlElement(required = true)
protected List<ProductOrder> productOrder;
public String getVendorCode() {
return vendorCode;
}
public void setVendorCode(String value) {
this.vendorCode = value;
}
public String getVendorName() {
return vendorName;
}
public void setVendorName(String value) {
this.vendorName = value;
}
public String getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(String value) {
this.orderNumber = value;
}
public List<ProductOrder> getProductOrder() {
if (productOrder == null) {
productOrder = new ArrayList<ProductOrder>();
}
return this.productOrder;
}
}
I have a method processOrder in a interface and their implementation. This
is the interface
#WebService(targetNamespace = "http://uciext.ws.hw3/wsdl")
public interface OrderServiceWS {
#WebMethod
OrderConfirm processOrder(#WebParam(name="arg0", mode=Mode.IN) Order order) throws Exception;
}
processOrder is in the class
#XmlRootElement(name = "processOrder", namespace = "http://uciext.ws.hw3/wsdl")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "processOrder", namespace = "http://uciext.ws.hw3/wsdl")
public class ProcessOrder {
#XmlElement(name = "arg0", namespace = "")
private com.uciext.ws.hw3.service.model.order.Order arg0;
public com.uciext.ws.hw3.service.model.order.Order getArg0() {
return this.arg0;
}
public void setArg0(com.uciext.ws.hw3.service.model.order.Order arg0) {
this.arg0 = arg0;
}
}
This is the interface implementation where is called the method processOrder.
#WebService(
portName = "OrderPort",
serviceName = "OrderService",
targetNamespace = "http://uciext.ws.hw3/wsdl",
endpointInterface = "com.uciext.ws.hw3.service.OrderServiceWS")
public class OrderServiceWSImpl implements OrderServiceWS {
private InventoryManagerImpl manager = new InventoryManagerImpl();
#Override
public OrderConfirm processOrder(Order order) throws Exception {
Util.log("SOAP processOrder request [ order=" + order);
Util.log("OrderServiceWS start processOrder");
OrderDAO orderDAO = new OrderDAO();
List<ProductOrder> productOrderList = new ArrayList<ProductOrder>();
List<ProductOrderDAO> productOrderDAOList = new ArrayList<ProductOrderDAO>();
ProductOrderDAO productOrderDAO1 = null;
ProductDAO productDAO = null;
OrderConfirm orderConfirm = null;
ProductOrder productOrder = null;
ProductConfirm productConfirm = null;
List<ProductConfirm> productConfirmList = new ArrayList<ProductConfirm>();
Double totalPrice = 0.0;
Util.log("OrderServiceWS start processOrder vendorCode "+order.getVendorCode());
orderDAO.setVendorCode(order.getVendorCode());
orderDAO.setVendorName(order.getVendorName());
orderDAO.setOrderId(Long.parseLong(order.getOrderNumber()));
Util.log("OrderServiceWS processOrder before productOrderList ");
productOrderList = order.getProductOrder();
Util.log("OrderServiceWS processOrder before productOrderList size "+productOrderList.size());
The value of vendorCode is right but productOrderList.size() is cero

Java Unmarshal list of objects with a class wrapper with JAXB

From an XQuery performed by BaseX server I get a result like that:
<ProtocolloList>
<protocollo>
<numero>1</numero>
<data>2014-06-23</data>
<oggetto/>
<destinatario/>
<operatore/>
</protocollo>
...
</ProtocolloList>
And I need to convert this result in a List of Protocollo objects with JAXB so that I can show them with JList. Thus, following one of the discussions here I've declared the following classes:
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "protocollo")
public class Protocollo {
private int numero;
private String data;
private String oggetto;
private String destinatario;
private String operatore;
public Protocollo(String d, String o, String des, String op) {
this.data = d;
this.oggetto = o;
this.destinatario = des;
this.operatore = op;
}
public Protocollo() {
}
#XmlElement
public int getNumero() {
return numero;
}
public void setNumero(int numero) {
this.numero = numero;
}
#XmlElement
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
#XmlElement
public String getOggetto() {
return oggetto;
}
public void setOggetto(String oggetto) {
this.oggetto = oggetto;
}
#XmlElement
public String getDestinatario() {
return destinatario;
}
public void setDestinatario(String destinatario) {
this.destinatario = destinatario;
}
#XmlElement
public String getOperatore() {
return operatore;
}
public void setOperatore(String operatore) {
this.operatore = operatore;
}
}
and
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "ProtocolloList")
public class ProtocolloList {
#XmlElementWrapper(name = "ProtocolloList")
#XmlElement(name = "protocollo")
private ArrayList<Protocollo> ProtocolloList;
public ArrayList<Protocollo> getProtocolloList() {
return ProtocolloList;
}
public void setProtocolloList(ArrayList<Protocollo> protocolloList) {
ProtocolloList = protocolloList;
}
}
and finally I execute the converion like that:
JAXBContext jaxbContext = JAXBContext.newInstance(Protocollo.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(this.resultXML);
protocolli = (ProtocolloList) unmarshaller.unmarshal(reader);
And I keep on getting this exception:
unexpected element (uri:"", local:"ProtocolloList"). Expected elements are <{}protocollo>
I suppose I'm making some mistakes with annotations.
Can you help?
For your use case you do not need the #XmlElementWrapper annotation. This is because the ProtocolList element corresponds to your #XmlRootElement annotation. Then you need the #XmlElement annotation on the property to grab each of the list items.
#XmlRootElement(name = "ProtocolloList")
public class ProtocolloList {
private ArrayList<Protocollo> ProtocolloList;
#XmlElement(name = "protocollo")
public ArrayList<Protocollo> getProtocolloList() {
return ProtocolloList;
}
}
Note:
By default you should annotate the property. If you want to annotate the fields you should put #XmlAccessorType(XmlAccessType.FIELD) on your class.
UPDATE
You need to make sure your JAXBContext is aware of the root class. You can change your JAXBContext creation code to be the following:
JAXBContext jaxbContext = JAXBContext.newInstance(ProtocolloList.class);

Mapping nested xml elements to single Java Object

How would I map this
<urn:envelope xmlns:urn="urn:com.twinstrata.webservice:2.1">
<urn:encoded>
<urn:response>
<urn:license>
<urn:licenseTag>WHATEVER934</urn:licenseTag>
<urn:accountNumber>2016763117</urn:accountNumber>
<urn:licenseType>TRIAL</urn:licenseType>
<urn:licenseClass>Credentialed</urn:licenseClass>
<urn:volumeAllowed>Unlimited</urn:volumeAllowed>
<urn:volumeProvisioned>0</urn:volumeProvisioned>
<urn:snapshotLimit>Unlimited</urn:snapshotLimit>
<urn:snapshotLimitPerVolume>10</urn:snapshotLimitPerVolume>
<urn:status>Active</urn:status>
<urn:usedSpace>0</urn:usedSpace>
<urn:expirtationDate>2013-03-27 14:48:47.0</urn:expirtationDate>
<urn:storageLimit>Unlimited</urn:storageLimit>
</urn:license>
</urn:response>
</urn:encoded>
<urn:signature>Hl8rk2aTEsOkkq5e383LH0BqdFfmVcKIg9FuFEnnrlFk9fwYVEQwkrm/7MPM2Zmli2Um00L2Ab25tZg2w8pEzXyDsd+vwCAH0ypQwhIVPayDjgYKlYXbnkqG5S+7qiVbqD2qZDektuPoEWvaSdxO3ZgUibT+nnrO0kl6E7i4lB0=
</urn:signature>
to this
package com.folio3.bean;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "envelope" , namespace = "urn:com.twinstrata.webservice:2.1")
public class ResponseXML {
private String userName;
private String license;
private String signature;
private String licenseTag;
private String accountNumber;
private String licenseType;
private String licenseClass;
private String volumeAllowed;
private String volumeProvisioned;
private String publicKey;
#XmlElement(name = "userName" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
#XmlElement(name = "license" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getLicense() {
return license;
}
public void setLicense(String license) {
this.license = license;
}
#XmlElement(name = "signature" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
#XmlElement(name = "licenseTag" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getLicenseTag() {
return licenseTag;
}
public void setLicenseTag(String licenseTag) {
this.licenseTag = licenseTag;
}
#XmlElement(name = "accountNumber" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
}
#XmlElement(name = "licenseType" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getLicenseType() {
return licenseType;
}
public void setLicenseType(String licenseType) {
this.licenseType = licenseType;
}
#XmlElement(name = "licenseClass" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getLicenseClass() {
return licenseClass;
}
public void setLicenseClass(String licenseClass) {
this.licenseClass = licenseClass;
}
#XmlElement(name = "volumeAllowed" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getVolumeAllowed() {
return volumeAllowed;
}
public void setVolumeAllowed(String volumeAllowed) {
this.volumeAllowed = volumeAllowed;
}
#XmlElement(name = "volumeProvisioned" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getVolumeProvisioned() {
return volumeProvisioned;
}
public void setVolumeProvisioned(String volumeProvisioned) {
this.volumeProvisioned = volumeProvisioned;
}
#XmlElement(name = "publicKey" , namespace = "urn:com.twinstrata.webservice:2.1")
public String getPublicKey() {
return publicKey;
}
public void setPublicKey(String publicKey) {
this.publicKey = publicKey;
}
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("ResponseXML [userName=");
builder.append(userName);
builder.append(", license=");
builder.append(license);
builder.append(", signature=");
builder.append(signature);
builder.append(", licenseTag=");
builder.append(licenseTag);
builder.append(", accountNumber=");
builder.append(accountNumber);
builder.append(", licenseType=");
builder.append(licenseType);
builder.append(", licenseClass=");
builder.append(licenseClass);
builder.append(", volumeAllowed=");
builder.append(volumeAllowed);
builder.append(", volumeProvisioned=");
builder.append(volumeProvisioned);
builder.append(", publicKey=");
builder.append(publicKey);
builder.append("]");
return builder.toString();
}
}
Currently , It maps only one property of XML , that is "signature".
For the sake of simplicity, I don't want to make other classes and nest the objects inside it. I just want to parse nested xml tags in single Java class.
How do I do that ?
Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.
ResponseXML
You could use MOXy's #XmlPathextension to map your use case (see: http://blog.bdoughan.com/2010/09/xpath-based-mapping-geocode-example.html). Below is a partial mapping of your use case.
package forum15391077;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
#XmlRootElement(name = "envelope")
#XmlType(propOrder={"licenseTag", "accountNumber", "licenseType", "licenseClass", "volumeAllowed", "volumeProvisioned", "signature", "license", "publicKey", "userName"})
#XmlAccessorType(XmlAccessType.FIELD)
public class ResponseXML {
private String userName;
private String license;
private String signature;
#XmlPath("urn:encoded/urn:response/urn:license/urn:licenseTag/text()")
private String licenseTag;
#XmlPath("urn:encoded/urn:response/urn:license/urn:accountNumber/text()")
private String accountNumber;
#XmlPath("urn:encoded/urn:response/urn:license/urn:licenseType/text()")
private String licenseType;
#XmlPath("urn:encoded/urn:response/urn:license/urn:licenseClass/text()")
private String licenseClass;
#XmlPath("urn:encoded/urn:response/urn:license/urn:volumeAllowed/text()")
private String volumeAllowed;
#XmlPath("urn:encoded/urn:response/urn:license/urn:volumeProvisioned/text()")
private String volumeProvisioned;
private String publicKey;
}
package-info
We will use the package level #XmlSchema annotation to specify the namespace qualification (see: http://blog.bdoughan.com/2010/08/jaxb-namespaces.html). We will also use it to define the urn prefix which we leveraged in the #XmlPath annotation.
#XmlSchema(
namespace="urn:com.twinstrata.webservice:2.1",
elementFormDefault=XmlNsForm.QUALIFIED,
xmlns={
#XmlNs(namespaceURI = "urn:com.twinstrata.webservice:2.1", prefix = "urn")
}
)
package forum15391077;
import javax.xml.bind.annotation.*;
jaxb.properties
To specify MOXy as your JAXB provider you need to include a file called jaxb.properties in the same package as your domain model with the following entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html)
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
Demo
Since MOXy is a standard JAXB implementation, the standard JAXB runtime APIs are used.
package forum15391077;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(ResponseXML.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum15391077/input.xml");
ResponseXML response = (ResponseXML) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(response, System.out);
}
}
input.xml/Output
Below is a sample XML document based on the part of your use case that I mapped.
<?xml version="1.0" encoding="UTF-8"?>
<urn:envelope xmlns:urn="urn:com.twinstrata.webservice:2.1">
<urn:encoded>
<urn:response>
<urn:license>
<urn:licenseTag>WHATEVER934</urn:licenseTag>
<urn:accountNumber>2016763117</urn:accountNumber>
<urn:licenseType>TRIAL</urn:licenseType>
<urn:licenseClass>Credentialed</urn:licenseClass>
<urn:volumeAllowed>Unlimited</urn:volumeAllowed>
<urn:volumeProvisioned>0</urn:volumeProvisioned>
</urn:license>
</urn:response>
</urn:encoded>
<urn:signature>Hl8rk2aTEsOkkq5e383LH0BqdFfmVcKIg9FuFEnnrlFk9fwYVEQwkrm/7MPM2Zmli2Um00L2Ab25tZg2w8pEzXyDsd+vwCAH0ypQwhIVPayDjgYKlYXbnkqG5S+7qiVbqD2qZDektuPoEWvaSdxO3ZgUibT+nnrO0kl6E7i4lB0=
</urn:signature>
</urn:envelope>
I made it working by creating nested classes and by using proper JAXB annotations.

Categories

Resources