i have a XML parsed pojo like below
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"activity",
"orderDetails"
})
#XmlRootElement(name = "GxML")
public class GxML {
#XmlElement(name = "Activity", required = true)
public String activity;
#XmlElement(name = "OrderDetails", required = true)
public GxML.OrderDetails orderDetails;
//get set
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"initiatorRole",
"productDetails"
})
public static class OrderDetails {
#XmlElement(name = "InitiatorRole", required = true)
public String initiatorRole;
//get set
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"product"
})
public static class ProductDetails {
#XmlElement(name = "Product", required = true)
public List<GxML.OrderDetails.ProductDetails.Product> product;
public List<GxML.OrderDetails.ProductDetails.Product> getProduct() {
if (product == null) {
product = new ArrayList<GxML.OrderDetails.ProductDetails.Product>();
}
return this.product;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"quantity",
"commodity"
})
public static class Product {
#XmlElement(name = "Quantity", required = true)
public BigDecimal quantity;
#XmlElement(name = "Commodity", required = true)
public String commodity;
//get set
}}}}
i need to Get All Field Names and their corresponding values using Java Reflection
Class c1 = gXml.getClass();
Field[] valueObjFields = c1.getDeclaredFields()[1].getType().getDeclaredFields();
for (int i = 0; i < valueObjFields.length; i++) {
String fieldName = valueObjFields[i].getName();
valueObjFields[i].setAccessible(true);
Object newObj = valueObjFields[i].get(gXml.getOrderDetails());
orderMap.put(valueObjFields[i].getAnnotation(XmlElement.class).name(), newObj);
if("productDetails".equalsIgnoreCase(fieldName)){
Class c2 = gXml.getOrderDetails().getProductDetails().getProduct().get(0).getClass();
Field[] valueObjFields1 = c2.getDeclaredFields();
for (int j = 0; j < valueObjFields1.length; j++) {
String fieldName2 = valueObjFields1[j].getName();
valueObjFields1[j].setAccessible(true);
Object newObj2 = valueObjFields1[j].get(gXml.getOrderDetails().getProductDetails().getProduct());
orderMap.put(valueObjFields1[j].getAnnotation(XmlElement.class).name(), newObj2);
} } }
for order details it is working fine but in product details to get quantity and commodity it is giving illegal argument exception at
Object newObj2 = valueObjFields1[j].get(gXml.getOrderDetails().getProductDetails().getProduct());
how to get list values using reflection.
You get fields from getProduct().get(0) class (look like a list's member)
Class c2 = gXml.getOrderDetails().getProductDetails().getProduct().get(0).getClass();
Field[] valueObjFields1 = c2.getDeclaredFields();
But try to read value from the collection itself (rather than get(0) element)
valueObjFields1[j].get(gXml.getOrderDetails().getProductDetails().getProduct());
Related
The following code is resulting in a cast exception and I'm not sure why. Objects in ParameterValueList should be eagerly unmarshalled to the JAXB object ParameterValueStruct, but it's not. Everything was generated directly from the soap encoding and cwmp schema files.
Does anyone have any suggestions?
public static void main(String[] args) throws JAXBException, FileNotFoundException
{
JAXBContext c = JAXBContext.newInstance("org.dslforum.cwmp_1_1");
Unmarshaller u = c.createUnmarshaller();
Inform inform = (Inform) u.unmarshal(new FileInputStream("test.xml"));
List<Object> list = inform.getParameterList().getAny();
System.out.println(list); // prints [[ParameterValueStruct: null], ...
for (Object o : list) {
ParameterValueStruct pv = (ParameterValueStruct)o; // exception here
System.out.println(pv.getName());
}
}
Exception in thread "main" java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to org.dslforum.cwmp_1_1.ParameterValueStruct
at Test.main(Test.java:26)
I have this class which was generated from http://schemas.xmlsoap.org/soap/encoding/ using Java's xjc tool:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Array", propOrder = {
"any"
})
#XmlSeeAlso({
ParameterValueList.class,
})
public class Array {
#XmlAnyElement(lax = true)
protected List<Object> any;
#XmlAttribute(name = "id")
#XmlJavaTypeAdapter(CollapsedStringAdapter.class)
#XmlID
#XmlSchemaType(name = "ID")
protected java.lang.String id;
#XmlAttribute(name = "href")
#XmlSchemaType(name = "anyURI")
protected java.lang.String href;
#XmlAttribute(name = "arrayType", namespace = "http://schemas.xmlsoap.org/soap/encoding/")
protected java.lang.String arrayType;
#XmlAttribute(name = "offset", namespace = "http://schemas.xmlsoap.org/soap/encoding/")
protected java.lang.String offset;
#XmlAnyAttribute
private Map<QName, java.lang.String> otherAttributes = new HashMap<QName, java.lang.String>();
public List<Object> getAny() {
if (any == null) {
any = new ArrayList<Object>();
}
return this.any;
}
....
}
I also have these 2 classes which were also generated via the same tool, but from https://www.broadband-forum.org/cwmp/cwmp-1-1.xsd:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ParameterValueList")
public class ParameterValueList
extends Array
{
}
Second file:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ParameterValueStruct", propOrder = {
"name",
"value"
})
public class ParameterValueStruct {
#XmlElement(name = "Name", required = true)
protected String name;
#XmlElement(name = "Value", required = true)
#XmlSchemaType(name = "anySimpleType")
protected Object value;
...
}
And here is my test.xml file:
<?xml version="1.0"?>
<cwmp:Inform xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:cwmp="urn:dslforum-org:cwmp-1-1" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ParameterList soap-enc:arrayType="cwmp:ParameterValueStruct[3]">
<ParameterValueStruct>
<Name>Device.DHCPv4.ClientNumberOfEntries</Name>
<Value xsi:type="xsd:unsignedInt">0</Value>
</ParameterValueStruct>
<ParameterValueStruct>
<Name>Device.DNS.Client.ServerNumberOfEntries</Name>
<Value xsi:type="xsd:unsignedInt">1</Value>
</ParameterValueStruct>
<ParameterValueStruct>
<Name>Device.DeviceInfo.AdditionalSoftwareVersion</Name>
<Value xsi:type="xsd:string">DM: 532,SK: 2.6.33.9-rt31,SF: 251X 137.0,BK: 10</Value>
</ParameterValueStruct>
</ParameterList>
</cwmp:Inform>
You just have to add #XmlRootElement(name="ParameterValueStruct",namespace="") in front of ParameterValueStruct
Here you need explicit namespace="" becauce of the package-info.java
#javax.xml.bind.annotation.XmlSchema(namespace = "urn:dslforum-org:cwmp-1-1")
package org.dslforum.cwmp_1_1;
The correct class should look like this:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ParameterValueStruct", propOrder = {
"name",
"value"
})
#XmlRootElement(name="ParameterValueStruct",namespace="")
public class ParameterValueStruct {
#XmlElement(name = "Name", required = true)
protected String name;
#XmlElement(name = "Value", required = true)
#XmlSchemaType(name = "anySimpleType")
protected Object value;
...
}
PS: See this http://blog.bdoughan.com/2012/12/jaxbs-xmlanyelementlaxtrue-explained.html for a better JAXB-tutorial about #XmlAnyElement(lax=true)
I want to have JAXB-annotated classes which would be marshalled/unmarshalled to different XML namespaces.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="http://test.com/">
<soapenv:Header/>
<soapenv:Body>
<v1:UpdateMemberRequest>
<v1:memberID>568</v1:memberID>
<v1:member>
<v1:Address>USA</v1:Address>
</v1:member>
</v1:UpdateMemberRequest>
</soapenv:Body>
</soapenv:Envelope>
how will the class look like?
Below the required Java classes. Add getters and setters according to standard practice. In package com.test;:
// MemberType.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "MemberType", propOrder = {
"address"
})
public class MemberType {
#XmlElement(name = "Address", required = true)
protected String address;
}
// UpdateMemberRequestType.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "UpdateMemberRequestType", propOrder = {
"memberID",
"member"
})
public class UpdateMemberRequestType {
#XmlElement(required = true)
protected String memberID;
#XmlElement(required = true)
protected MemberType member;
}
// ObjectFactory.java
#XmlRegistry
public class ObjectFactory {
private final static QName _UpdateMemberRequest_QNAME =
new QName("http://test.com/", "UpdateMemberRequest");
public ObjectFactory() {
}
public UpdateMemberRequestType createUpdateMemberRequestType() {
return new UpdateMemberRequestType();
}
public MemberType createMemberType() {
return new MemberType();
}
#XmlElementDecl(namespace = "http://test.com/",
name = "UpdateMemberRequest")
public JAXBElement
createUpdateMemberRequest(UpdateMemberRequestType value) {
return new JAXBElement(_UpdateMemberRequest_QNAME,
UpdateMemberRequestType.class, null, value);
}
}
Another package org.xmlsoap.schemas.soap.envelope;:
// BodyType.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "BodyType", propOrder = {
"updateMemberRequest"
})
public class BodyType {
#XmlElement(name = "UpdateMemberRequest", namespace = "http://test.com/", required = true)
protected UpdateMemberRequestType updateMemberRequest;
}
// EnvelopeType.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "EnvelopeType", propOrder = {
"header",
"body"
})
public class EnvelopeType {
#XmlElement(name = "Header", required = true)
protected String header;
#XmlElement(name = "Body", required = true)
protected BodyType body;
}
// ObjectFactory.jav
#XmlRegistry
public class ObjectFactory {
private final static QName _Envelope_QNAME =
new QName("http://schemas.xmlsoap.org/soap/envelope/", "Envelope");
public ObjectFactory() {
}
public EnvelopeType createEnvelopeType() {
return new EnvelopeType();
}
public BodyType createBodyType() {
return new BodyType();
}
#XmlElementDecl(namespace = "http://schemas.xmlsoap.org/soap/envelope/",
name = "Envelope")
public JAXBElement createEnvelope(EnvelopeType value) {
return new JAXBElement(_Envelope_QNAME,
EnvelopeType.class, null, value);
}
}
Here is my object:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {"profile", "request", "filter"})
#XmlRootElement(name = "SubmitXml")
public class SubmitXml {
#XmlElement(name = "Profile")
protected String profile;
#XmlElement(name = "Request")
protected SubmitXml.Request request;
#XmlElement(name = "Filter")
protected SubmitXml.Filter filter;
public String getProfile() {
return profile;
}
public void setProfile(String value) {
this.profile = value;
}
public SubmitXml.Request getRequest() {
return request;
}
public void setRequest(SubmitXml.Request value) {
this.request = value;
}
public SubmitXml.Filter getFilter() {
return filter;
}
public void setFilter(SubmitXml.Filter value) {
this.filter = value;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"any"
})
public static class Filter {
#XmlAnyElement(lax = true)
protected Object any;
public Object getAny() {
return any;
}
public void setAny(Object value) {
this.any = value;
}
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"any"
})
public static class Request {
#XmlAnyElement(lax = true)
#XmlElementRefs({
#XmlElementRef(name = "AirAvailability", type = AirAvailability.class)
})
protected Object any;
public Object getAny() {
return any;
}
public void setAny(Object value) {
this.any = value;
}
}
}
and I want to marshal it into this xml below:
<?xml version=\"1.0\" encoding=\"utf-8\"?>
<soap:Envelope>
<soap:Body><SubmitXml>
<Profile>DynGalileoProd_7OQ7</Profile>
<Request>
<AirAvailability_12 xmlns=\"\">
<AirAvailMods>
<GenAvail>
<NumSeats>2</NumSeats>
<Class>Y</Class>
<StartDt>20151201</StartDt>
<StartPt>TPE</StartPt>
<EndPt>HKG</EndPt>
<StartTm><![CDATA[ ]]></StartTm>
</GenAvail>
</AirAvailMods>
</AirAvailability_12>
</Request>
<Filter><_ /></Filter>
</SubmitXml>
</soap:Body>
the problem is how can I generate such an element like <_ /> at element Filter?
another question is how can I generate element text like <![CDATA []]> at element <StartTm>? The characters < and > are always changed into < and >.
With this method:
<T> JAXBElement<T> wrap( String ns, String tag, T o ){
QName qtag = new QName( ns, tag );
Class<?> clazz = o.getClass();
#SuppressWarnings( "unchecked" )
JAXBElement<T> jbe = new JAXBElement( qtag, clazz, o );
return jbe;
}
it is possible to do
Filter filter = new Filter();
String s = "";
filter.setAny( wrap( "", "_", s ) );
and this will create
<Filter><_></_></Filter>
and since <_/> is, by definition, the same as <_></_>, you have what you want.
Your second request cannot fulfilled without writing your own XML writer. However, it is definitely unnecessary to do so. Using or not using <![CDATA []]> is a matter of convenience when editing XML manually. If the XML writer escapes < and > properly, there is no reason why CDATA should be used.
Here my XmlRoot class:
#XmlRootElement(name = "IGE")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "IGEType", propOrder = { "altin" })
public class IGEType {
#XmlElement(name = "ALTIN", required = true)
protected List<ALTINType> altin;
public List<ALTINType> getALTIN() {
if (altin == null) {
altin = new ArrayList<ALTINType>();
}
return this.altin;
}
}
Then successor(child) class of root :
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ALTINType", propOrder = { "seanSytl" })
public class ALTINType {
#XmlElement(name = "SEANSytl", required = true)
protected SEANSytlType seanSytl;
}
At last, successor class of successor of root :
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "SEANSytlType", propOrder = { "birim", "oncekiKapanis", "enDusuk", "enYuksek", "kapanis", "agirlikliOrtalama", "islemHacmi", "islemMiktari", "bicim", "gram", "islemSayisi" })
public class SEANSytlType {
#XmlElement(required = true)
protected String birim;
#XmlElement(name = "onceki_kapanis", required = true)
protected BigDecimal oncekiKapanis;
#XmlElement(name = "en_dusuk", required = true)
protected BigDecimal enDusuk;
#XmlElement(name = "en_yuksek", required = true)
protected BigDecimal enYuksek;
#XmlElement(required = true)
protected BigDecimal kapanis;
#XmlElement(name = "agirlikli_ortalama", required = true)
protected BigDecimal agirlikliOrtalama;
#XmlElement(name = "islem_hacmi", required = true)
protected BigDecimal islemHacmi;
#XmlElement(name = "islem_miktari", required = true)
protected BigDecimal islemMiktari;
#XmlElement(name = "BICIM", required = true)
protected BigDecimal bicim;
#XmlElement(name = "GRAM", required = true)
protected BigDecimal gram;
#XmlElement(name = "islem_sayisi")
protected int islemSayisi;
}
Myhandler class:
#Override
public void handleXMLtoIABData(RequestTcmbXMLData req) throws HmnServiceException {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(IGEType.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
File XMLfile = new File("C:\\Users\\U067944\\Desktop\\IAB_bülten.xml");
IGEType igeRoot = (IGEType) jaxbUnmarshaller.unmarshal(XMLfile);
**List<SEANSytlType> listofAltinYtl = (List<SEANSytlType>) ((List<ALTINType>) igeRoot.getALTIN()).getSEANSytl();**
for (SEANSytlType altinYtl : listofAltinYtl) {
}
} catch (JAXBException e) {
e.printStackTrace();
}
}
In my handler class I try to reach last successor class (List SEANSytlType ), but it doesnt work.
I get this error :
jvmId: [300], transactionId:[3005624292568000] .Root Cause: [java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.ykb.hmn.mdt.marketdata.xmlparser.iab.ALTINType]
I also try this in handler but same:
IGEType igeRoot = (IGEType) jaxbUnmarshaller.unmarshal(XMLfile);
String inputDate = igeRoot.getIGEBULTENGUNTR().getGun2();
List<ALTINType> listAltinRoot = (List<ALTINType>) igeRoot.getALTIN();
List<SEANSytlType> listofAltinYtl = (List<SEANSytlType>) listAltinRoot.get(0);
Where am I wrong?
Thanks in advance!
Based your sample classes
IGEType
#XmlRootElement(name = "IGE")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "IGE", propOrder = { "altin" })
public class IGEType {
#XmlElement(name = "Altin", required = true)
public List<ALTINType> altin;
public List<ALTINType> getALTIN() {
if (altin == null) {
altin = new ArrayList<ALTINType>();
}
return this.altin;
}
}
Then ALTINType
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "altin", propOrder = { "seanSytl" })
public class ALTINType {
#XmlElement(name = "SEANSytl", required = true)
protected SEANSytlType seanSytl;
}
Then SEANSytlType
<!-- language: java -->
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "SEANSytl", propOrder = { "birim"})
public class SEANSytlType {
#XmlElement(required = true)
protected String birim;
}
Then sample class for test
<!-- language: java -->
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
JAXBContext jaxbContext = JAXBContext.newInstance(IGEType.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
File XMLfile = new File("sample1.xml");
IGEType igeRoot = (IGEType) jaxbUnmarshaller.unmarshal(XMLfile);
List<ALTINType> listAltinRoot = igeRoot.getALTIN();
// here you ll be have error ///
// List<SEANSytlType> listofAltinYtl = (List<SEANSytlType>) listAltinRoot.get(0);
//
// for (SEANSytlType altinYtl : listofAltinYtl) {
// System.out.println(altinYtl.birim);
// }
} catch (JAXBException e) {
e.printStackTrace();
}
}
So and and end sample xml
<?xml version="1.0" encoding="UTF-8"?>
<IGE>
<Altin>
<SEANSytl>
<birim>cccc</birim>
</SEANSytl>
</Altin>
<Altin>
<SEANSytl>
<birim>dddd</birim>
</SEANSytl>
</Altin>
</IGE>
So basicly problem was that you have in root (IGE) childs list altin but in altin object thest is only 1 child object seansylt not at list like you have in altin so fix altin object add list there and take look at my example
Inner Lists are not return as a JSON String.. only the first data list is return...
Is there any way to get all data as JSON string ?
------My method ---------------------
#RequestMapping(value="/mainreservationChart", method = RequestMethod.GET)
public ModelAndView getMRChartData(#ModelAttribute ("ReservationSummaryRQDTO") ReservationSummaryRQDTO search){
ReservationSummaryDTO returnDataDTO = new ReservationSummaryDTO();
MainReservationChartWSImpl wsImpl = MRWSUtil.getInstance().getWS_ServicePort();
search.setHotelCode("BBH");
search.setReportDate(toXmlDateGMT(new Date()));
returnDataDTO = wsImpl.getReservationSummary(search);
Map<String, Object> model = new HashMap<String, Object>();
model.put("status", true);
model.put("hotelCode", returnDataDTO.getHotelCode());
model.put("summary", returnDataDTO.getSummaryMonth());
model.put("data", returnDataDTO);
return new ModelAndView("jsonView", model);
}
DTOs
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "reservationSummaryDTO", propOrder = {
"hotelCode",
"summaryMonth"
})
public class ReservationSummaryDTO {
protected String hotelCode;
#XmlElement(nillable = true)
protected List<SummaryMonthDTO> summaryMonth;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "summaryMonthDTO", propOrder = {
"month",
"summaryType"
})
public class SummaryMonthDTO {
protected String month;
#XmlElement(nillable = false)
protected List<SummaryTypeDTO> summaryType;
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "summaryTypeDTO", propOrder = {
"date",
"displaySequence",
"total",
"typeCode"
})
public class SummaryTypeDTO {
#XmlElement(nillable = true)
protected List<SummaryDateDTO> date;
protected Integer displaySequence;
protected Double total;
protected String typeCode;
try this
#RequestMapping(value="/mainreservationChart", method = RequestMethod.GET, headers = "Accept=application/json")