How to add blank namespace in java using javax.xml.bind.annotation - java

I'm new to SOAP service, this is my output and java class detail.
How to add the blank xmlns in sub level class?
Out-Put Request:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sendEmail xmlns="http://ws.cns.channel.sendnotification.sdfsfds.com/">
<EmailNotificationRequest>
<requestHeader>
<channel>fsdfs</channel>
<subChannel>sdfds</subChannel>
<systemName>sdfsd</systemName>
<applicationName>dsfs</applicationName>
</requestHeader>
</EmailNotificationRequest>
</sendEmail>
Package Class
#javax.xml.bind.annotation.XmlSchema(namespace = "http://ws.cns.channel.sendnotification.sdfsfds.com/",
elementFormDefault = XmlNsForm.QUALIFIED
)
package com.etisalat.sendnotification.channel.cns.ws;
import javax.xml.bind.annotation.XmlNsForm;
Request Header Class
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "requestHeader", propOrder = {
"channel",
"subChannel",
"agentID",
"systemName",
"applicationName",
"hostID",
"requestDate"
})
public class RequestHeader {
#XmlElement(required = true)
protected String channel;
protected String subChannel;
protected String agentID;
#XmlElement(required = true)
protected String systemName;
protected String applicationName;
}
Required Input Request
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sendEmail xmlns="http://ws.cns.channel.sendnotification.sdfsfds.com/">
<EmailNotificationRequest>
<requestHeader xmlns="">
<channel>fsdfs</channel>
<subChannel>sdfds</subChannel>
<systemName>sdfsd</systemName>
<applicationName>dsfs</applicationName>
</requestHeader>
</EmailNotificationRequest>
</sendEmail>

Related

Soap Message to Java Object

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\" xmlns:cs=\"urn:CardServices\" xmlns:ebppif1=\"urn:PaymentServer\" xmlns:el=\"urn:ExtListsServices\" xmlns:iiacs=\"urn:IIACardServices\" xmlns:lm=\"urn:Limits\">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Client</faultcode>
<faultstring></faultstring>
<detail>
<ebppif1:PaymentServerException>
<provider>RSW</provider>
<error>129</error>
<description>201433</description>
<screen>RSW129</screen>
</ebppif1:PaymentServerException>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
How to create java object using #XmlRootElement,#XmlElement.
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "Fault", namespace = "http://schemas.xmlsoap.org/soap/envelope/")
#Data
public class FaultDto {
#XmlElement(name = "faultcode")
private String faultCode;
#XmlElement(name = "detail")
private DetailDto detail;
}
#XmlRootElement(name = "detail")
#XmlAccessorType(XmlAccessType.FIELD)
public class DetailDto {
#XmlElement(name = "PaymentServerException")
private PaymentExcepDto excepDto;
}
#XmlRootElement(name = "PaymentServerException")
#XmlAccessorType(XmlAccessType.FIELD)
public class PaymentExcepDto {
#XmlElement(name = "provider")
protected String provider;
#XmlElement(name = "error")
protected String error;
//others
}
I am getting this result : FaultDto(faultCode=SOAP-ENV:Client, detail=DetailDto(excepDto=null))
How to catch PaymentServerException ?

Create XML string in java with custom namespace

I want to generate xml string in java programmatically whose name space is custom as shown below
and all data must come dynamically in xml.How can I achieve something like this?
<faxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="test.xsd">
<person>
<name>ABC</name>
</person>
</faxml>
I have gone through examples like this https://howtodoinjava.com/jaxb/write-object-to-xml/ but here when xml generated its starting line is
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
but I want start and end tag <faxml> and namespaces as I mentioned in my sample code as output
Here is one approach:
First, here is my class representing the required XML data:
package org.ajames.jaxb.persons;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "")
#XmlRootElement(name = "faxml")
public class Faxml {
private Person person;
public static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
I chose to nest the Person class inside the root class - just for this test. There are other ways to arrange these classes, of course, so they are not nested.
Then I define the package-info for org.ajames.jaxb.persons as follows:
#XmlSchema(
namespace = "",
elementFormDefault = XmlNsForm.UNSET,
xmlns = {
#XmlNs(prefix = "", namespaceURI = "http://www.w3.org/2001/XMLSchema-instance")
})
package org.ajames.jaxb.persons;
import javax.xml.bind.annotation.XmlSchema;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
To process the data from a Java object to XML, I use the following test data:
Faxml.Person person = new Faxml.Person();
person.setName("ABC");
Faxml faxml = new Faxml();
faxml.setPerson(person);
The JAXB context and marshaller are as follows, assuming we are writing the XML to a Java String, for this test:
JAXBContext jaxbContext = JAXBContext.newInstance(Faxml.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "test.xsd");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter stringWriter = new StringWriter();
marshaller.marshal(faxml, stringWriter);
String xml = stringWriter.toString();
System.out.println(xml);
The resulting XML is:
<faxml xsi:noNamespaceSchemaLocation="test.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<person>
<name>ABC</name>
</person>
</faxml>
String name= "name"
String createXml="<faxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"//
xsi:noNamespaceSchemaLocation="test.xsd">"//
+"<person>"//
+"<name>"+name+"</name>"//
+"</>person">"//
+"</faxml>";
Sysout(createXml);
get the name in a variable. Hard code these lines and insert it like this..

Problem with unmarshalling name spaced SOAP XML parameter

I have a problem processing a SOAP request. I can read everything from the envelope but the name space decorated parameter (cs:measurand) cannot be parsed.
Here you can find the SOAP Envelope:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:cs="urn://Ocpp/Cs/2012/06/" xmlns:soap-enc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Header>
<cs:identity>17083A00001101</cs:identity>
<a:From>
<a:Address>http://172.0.0.0:9080</a:Address>
</a:From>
<a:MessageID>urn:uuid:xxxxxxxxxxxx</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To>http://172.0.0.0:8080/ws/ocp</a:To>
<a:Action>/MValues</a:Action>
</soap:Header>
<soap:Body>
<cs:mValuesRequest>
<cs:id>1</cs:id>
<cs:transactionId>1881</cs:transactionId>
<cs:values>
<cs:timestamp>2019-03-07T13:41:52.405Z</cs:timestamp>
<cs:value cs:measurand="e.a.i.r" cs:unit="Wh">300</cs:value>
<cs:value cs:measurand="c.i" cs:unit="Amp">38.5</cs:value>
<cs:value cs:measurand="v" cs:unit="Volt">399.5</cs:value>
<cs:value cs:measurand="p.a.i" cs:unit="W">15380</cs:value>
<cs:value cs:measurand="t" cs:unit="Celsius">35</cs:value>
</cs:values>
</cs:mValuesRequest>
</soap:Body>
</soap:Envelope>
Here is the service which receive the request:
#Action("/MValues")
#ResponsePayload
public JAXBElement<MValuesResponse> receive(#RequestPayload MValuesRequest request,
MessageContext messageContext) {
....
}
And here is the MValuesRequest:
...
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ValuesRequest", propOrder = {
"id",
"transactionId",
"values"
})
public class MValuesRequest {
protected int id;
protected Integer transactionId;
protected List<MValue> values;
// getters setters...
}
Any your thoughts would be really appreciated.
try with this,
MValuesRequest.java
#XmlRootElement(name="cs:mValuesRequest")
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name ="ValuesRequest", propOrder = { "id", "transactionId", "values" })
public class MValuesRequest {
#XmlElement(name="cs:id")
protected int id;
#XmlElement(name="cs:transactionId")
protected Integer transactionId;
#XmlElement(name="cs:values")
protected Values values;
// getters and setters...
}
Values.java
#XmlRootElement(name="cs:values")
public class Values{
#XmlElement(name="cs:timestamp")
protected String timestamp;
#XmlElement(name="cs:value")
protected List<Value> value;
// getters and setters...
}
Value.java
#XmlRootElement(name="cs:value")
public class value{
#XmlAttribute(name="measurand" namespace="http://www.w3.org/XML/1998/namespace")
protected String measurand;
#XmlAttribute(name="unit" namespace="http://www.w3.org/XML/1998/namespace")
protected String unit;
#XmlValue
protected String elementValue;
// getters and setters...
}
I finally could solve this is issue, big thanks to Rathnayake.
I didn't have to add #XmlRootElement but only add the namespace parameter to #XmlAttribute.
So currently my XML parameters look like this:
#XmlAttribute(name = "context", namespace="urn://Ocpp/Cs/2012/06/")
protected ReadingContext context;
#XmlAttribute(name = "format", namespace="urn://Ocpp/Cs/2012/06/")
protected ValueFormat format;
#XmlAttribute(name = "measurand", namespace="urn://Ocpp/Cs/2012/06/")
protected Measurand measurand;
#XmlAttribute(name = "location", namespace="urn://Ocpp/Cs/2012/06/")
protected Location location;
#XmlAttribute(name = "unit", namespace="urn://Ocpp/Cs/2012/06/")
protected UnitOfMeasure unit;
Just to remember here is my SOAP header:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:cs="urn://Ocpp/Cs/2012/06/" xmlns:soap-enc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
And I added as namespace="..." value xmlns:cs="..." from the header.

JAXB marshal polymorphic POJO to XML

I am trying to use JAXB to marshal class file(with annotations). Under <profile-set> it can have different tags for e.g.
<organization-information-profile>
<connection-profile>
<user-information-profile>
Sample output XML files are as below
a)
<?xml version="1.0"?>
<request version="2.0" principal="111" credentials="xxxxx">
<target name="TestAPI" operation="create">
<parameter>
<organization>
<qualified-name>some-qualified-name</qualified-name>
<profile-set>
<name>TestOrg</name>
<organization-information-profile>
<name>Organization Information</name>
<qualified-name>/Organization Information</qualified-name>
<last-name>Test</last-name>
<address>some-address</address>
<city>my-city</city>
<province></province>
<postal-code>1111</postal-code>
<country>Timbaktu</country>
<phone-number-day>1111</phone-number-day>
<email-address>some#email.com</email-address>
<attribute name="PhoneNumber1">
<value context="organization">23333</value>
</attribute>
<attribute name="ShortName">
<value context="organization">my company</value>
</attribute>
<attribute name="TaxId">
<value context="organization">myorg</value>
</attribute>
</organization-information-profile>
</profile-set>
</organization>
</parameter>
</target>
</request>
b)
<?xml version="1.0"?>
<request version="2.0" principal="11111" credentials="xxxxx">
<target name="TestAPI" operation="update">
<parameter>
<organization>
<qualified-name>some-qualified-name</qualified-name>
<profile-set>
<name>TestOrg</name>
<connection-profile>
<qualified-name>some-qualified-name</qualified-name>
<service>
<name>some service</name>
</service>
<attribute name="att-1">
<value context="organization" segment="some-segment" subscript="524288">fill-the-value</value>
</attribute>
<attribute name="att-2">
<value context="organization" segment="some-segment" subscript="524288">qedqwe</value>
</attribute>
</connection-profile>
</profile-set>
</organization>
</parameter>
</target>
</request>
Below is the code (only profile-set)
public static class ProfileSet
{
#XmlElement(name = "name")
public String name;
// innerPayLoad is template to store different profile objects
#XmlJavaTypeAdapter(CustomAdaptor.class)
#XmlElement
public InnerPayLoad innerPayLoad;
public ProfileSet(String name, InnerPayLoad innerPayLoad)
{
this.name = name;
this.innerPayLoad = innerPayLoad;
}
}
And CustomAdaptor
public class CustomAdaptor extends XmlAdapter<String,InnerPayLoad<?>>
{
#Override
public InnerPayLoad<?> unmarshal(String v) throws Exception
{
return null;
}
#Override
public String marshal(InnerPayLoad<?> v) throws Exception
{
String value = TestCode.convertToXmlNoHeader(v.whichProfile,v.whichProfile.getClass());
// after converting value becomes
// <organization-information-profile>
// <name>Organization Information</name>
// </organization-information-profile>
return value;
}
}
But the final XML produced is not similar to (a) for organization-information-profile
<?xml version='1.0' encoding='UTF-8'?>
<request version="2.0" principle="11111" credentials="xxxxx">
<target name="TestAPI" operation="create">
<parameter>
<organization>
<qualified-name>newOrg</qualified-name>
<profile-set>
<innerPayLoad><organization-information-profile>
<name>Organization Information</name>
</organization-information-profile></innerPayLoad>
<name>testOrg</name>
</profile-set>
</organization>
</parameter>
</target>
</request>
Is it possible to remove <innerPayLoad> tag and just insert with CustomAdaptor marshal function return value?
Appreciate help and hints to solve this issue.
You don't need to write a custom adapter for the various profile types within your ProfileSet.
Instead, to handle such mixed XML Content the canonical approach goes like this.
In your ProfileSet class you should define a polymorphic Java property profile
which can take the contents of a <organization.information-profile>,
<connection-profile> or <user-information-profile> element.
(I preferred the name profile here instead of innerPayload).
The mapping between these XML element names and Java classes is done
by using the #XmlElements annotation.
#XmlAccessorType(XmlAccessType.FIELD)
public class ProfileSet {
#XmlElement(name = "name")
private String name;
// template to store different profile objects
#XmlElements({
#XmlElement(name = "organization-information-profile", type = OrganizationInfomationProfile.class),
#XmlElement(name = "connection-profile", type = ConnectionProfile.class),
#XmlElement(name = "user-information-profile", type = UserInformationProfile.class)
})
private Profile profile;
// default constructor used by JAXB unmarshaller
public ProfileSet() {
}
public ProfileSet(String name, Profile profile) {
this.name = name;
this.profile = profile;
}
}
You need an abstract super-class Profile containing only the properties common to all kinds of profiles:
#XmlAccessorType(XmlAccessType.FIELD)
public abstract class Profile {
#XmlElement
private String name;
#XmlElement(name = "attribute")
private List<Attribute> attributes;
}
You have one subclass OrganizationInformationProfile for representing the
<organization-information-profile> element
#XmlAccessorType(XmlAccessType.FIELD)
public class OrganizationInfomationProfile extends Profile {
#XmlElement(name = "qualified-name")
private String qualifiedName;
#XmlElement(name = "last-name")
private String lastName;
#XmlElement(name = "address")
private String address;
// ... other properties
}
and another subclass ConnectionProfile for representing the <connection-profile> element
#XmlAccessorType(XmlAccessType.FIELD)
public class ConnectionProfile extends Profile {
#XmlElement(name = "service")
private Service service;
}
and yet another subclass UserInformationProfile for representing the <user-information-profile> element.
By using the above approach you can unmarshal your XML examples
and get the same output again when marshalling.

Can not unmarshall the SOAP response

I could send a request and receive the response but I can not parse the response. It returns the following error:
Local Name:Body
error is here
java.lang.NullPointerException
at com.ticketmaster.ticketmaster.TicketMaster.Search(TicketMaster.java:119)
at com.ticketmaster.ticketmaster.App.main(App.java:12)
Code
SOAPMessage response
= connection.call(message, endpoint);
connection.close();
SOAPMessage sm = response;
SOAPBody sb = response.getSOAPBody();
System.err.println("Node Name:" + sb.getNodeName()); //return nothing
System.err.println("Local Name:" + sb.getLocalName()); //return Local Name:Body
DOMSource source = new DOMSource(sb);
results = (FindEventsResponse) JAXB.unmarshal(source, FindEventsResponse.class);
System.err.println("Results size: " + this.results.returnTag.results.item.get(0).getName());
} catch (Exception ex) {
System.err.println("error is here");
ex.printStackTrace();
}
Response:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://ticketmaster.productserve.com/v2/soap.php"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<ns1:findEventsResponse>
<return xsi:type="ns1:Response">
<details xsi:type="ns1:Details">
<totalResults xsi:type="xsd:int">20662</totalResults>
<totalPages xsi:type="xsd:int">414</totalPages>
<currentPage xsi:type="xsd:int">1</currentPage>
<resultsPerPage xsi:type="xsd:int">50</resultsPerPage>
</details>
<results SOAP-ENC:arrayType="ns1:Event[50]" xsi:type="ns1:ArrayOfEvent">
<item xsi:type="ns1:Event">
<eventId xsi:type="xsd:int">1516682</eventId>
<ticketmasterEventId xsi:type="xsd:string">18004C6E8D7218A8</ticketmasterEventId>
<status xsi:type="xsd:string">onSale</status>
<name xsi:type="xsd:string">The Art of the Brick</name>
<url xsi:type="xsd:string">http://www.ticketmaster.ie/event/18004C6E8D7218A8?camefrom=CFC_UK_BUYAT&brand=[=BRAND=]</url>
<eventDate xsi:type="xsd:string">2014-05-23 10:00:00</eventDate>
<onSaleDate xsi:type="xsd:string">0000-00-00 00:00:00</onSaleDate>
<preSaleDate xsi:type="xsd:string">0000-00-00 00:00:00</preSaleDate>
<category xsi:type="xsd:string">Exhibitions</category>
<categoryId xsi:type="xsd:int">754</categoryId>
<parentCategory xsi:type="xsd:string">Family &amp; Attractions</parentCategory>
<parentCategoryId xsi:type="xsd:int">10003</parentCategoryId>
<minPrice xsi:type="xsd:float">17</minPrice>
<maxPrice xsi:type="xsd:float">17</maxPrice>
<artists SOAP-ENC:arrayType="ns1:Artist[1]" xsi:type="ns1:ArrayOfArtist">
<item xsi:type="ns1:Artist">
<artistId xsi:type="xsd:int">1806028</artistId>
<ticketmasterArtistId xsi:type="xsd:int">1663495</ticketmasterArtistId>
<name xsi:type="xsd:string">The Art of the Brick</name>
<url xsi:type="xsd:string">http://www.ticketmaster.co.uk/The-Art-of-the-Brick-tickets/artist/1663495?camefrom=CFC_UK_BUYAT&brand=[=BRAND=]</url>
<imageUrl xsi:type="xsd:string">http://media.ticketmaster.com/tm/en-us/tmimages/TM_GenCatImgs_Generic_BW.jpg</imageUrl>
<category xsi:type="xsd:string">Miscellaneous</category>
<categoryId xsi:type="xsd:int">0</categoryId>
<parentCategory xsi:type="xsd:string">Miscellaneous</parentCategory>
<parentCategoryId xsi:type="xsd:int">10005</parentCategoryId>
</item>
</artists>
<venue xsi:type="ns1:Venue">
<venueId xsi:type="xsd:int">3331</venueId>
<ticketmasterVenueId xsi:type="xsd:int">198292</ticketmasterVenueId>
<name xsi:type="xsd:string">Ambassador Theatre</name>
<street xsi:type="xsd:string">Oconnell Street</street>
<city xsi:type="xsd:string">Dublin</city>
<country xsi:type="xsd:string">United Kingdom</country>
<postcode xsi:type="xsd:string">Dublin 1</postcode>
<url xsi:type="xsd:string">http://www.ticketmaster.ie/Ambassador-Theatre-tickets-Dublin/venue/198292?camefrom=CFC_UK_BUYAT&brand=</url>
<imageUrl xsi:type="xsd:string">http://media.ticketmaster.co.uk/tmimages/TM_GenVenueImg_BW.jpg</imageUrl>
<state xsi:type="xsd:string"></state>
</venue>
</item>
<item xsi:type="ns1:Event">
....
Model Classes
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class FindEventsResponse {
#XmlElement(name = "return")
Return returnTag;
public FindEventsResponse() {
this.returnTag = new Return();
}
getter and setter
}
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Return {
#XmlElement(name = "details")
Details details;
#XmlElement(name = "results")
Results results;
public Return(Details details, Results results) {
this.details = new Details();
this.results = new Results();
}
getters and setters
}
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Details {
#XmlElement(name = "totalResults")
int totalResults;
#XmlElement(name = "totalPages")
int totalPages;
#XmlElement(name = "currentPage")
int currentPage;
#XmlElement(name = "resultPerPage")
int resultsPerPage;
getters and setters
}
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Results {
#XmlElement(name = "item")
List<Item> item;
public Results() {
this.item = new ArrayList();
}
getter and setter
}
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Item {
#XmlElement(name = "eventId")
int eventId;
#XmlElement(name = "ticketmasterEventId")
String ticketmasterEventId;
#XmlElement(name = "status")
String status;
#XmlElement(name = "name")
String name;
#XmlElement(name = "url")
String url;
#XmlElement(name = "eventDate")
String eventDate;
#XmlElement(name = "onSaleDate")
String onSaleDate;
#XmlElement(name = "preSaleDate")
String preSaleDate;
#XmlElement(name = "category")
String category;
#XmlElement(name = "categoryId")
int categoryId;
#XmlElement(name = "parentCategory")
String parentCategory;
#XmlElement(name = "parentCategoryId")
int parentCategoryId;
#XmlElement(name = "minPrice")
int minPrice;
#XmlElement(name = "maxPrice")
int maxPrice;
#XmlElement(name = "artists")
private Artists artist;
#XmlElement(name = "venue")
private Venue venue;
public Item() {
this.artist = new Artists();
this.venue = new Venue();
}
getters and setters
}
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Artists {
#XmlElement(name = "artists")
private ArtistItem item;
public Artists() {
this.item = new ArtistItem();
}
getter and setter
}
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class ArtistItem {
#XmlElement(name = "artistId")
int artistId;
#XmlElement(name = "ticketmasterArtistsId")
int ticketmasterArtistId;
#XmlElement(name = "name")
String name;
#XmlElement(name = "url")
String url;
#XmlElement(name = "imageUrl")
String imageUrl;
#XmlElement(name = "category")
String category;
#XmlElement(name = "categoryId")
int categoryId;
#XmlElement(name = "parentCategory")
String parentCategory;
#XmlElement(name = "parentCategoryId")
int parentCategoryId;
getters and setters
}
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Venue {
#XmlElement(name = "venueId")
int venueId;
#XmlElement(name = "ticketmasterVenueId")
int ticketmasterVenueId;
#XmlElement(name = "name")
String name;
#XmlElement(name = "street")
String street;
#XmlElement(name = "city")
String city;
#XmlElement(name = "country")
String country;
#XmlElement(name = "postcode")
String postcode;
#XmlElement(name = "url")
String url;
#XmlElement(name = "imageUrl")
String imageUrl;
#XmlElement(name = "state")
String state;
getters and setters
}
Based on one of the following answers, I marshalled the result and it shows a wrong response.
package-info.java
#XmlSchema(
namespace = "http://ticketmaster.productserve.com/v2/soap.php",
elementFormDefault = XmlNsForm.UNQUALIFIED)
package com.ticketmaster.ticketmaster;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
Code
SOAPBody sb = response.getSOAPBody();
System.err.println(">>"+ sb.getFirstChild().getNodeName());
Iterator itr = sb.getChildElements();
while(itr.hasNext()){
Object element = itr.next();
System.err.println(element + " ");
}
Document d = sb.extractContentAsDocument();
System.err.println("result of d:"+d.getTextContent());
DOMSource source = new DOMSource(d);
results = (FindEventsResponse) JAXB.unmarshal(source, FindEventsResponse.class);
System.err.println("results>"+results.getReturnTag().getResults().getItem().get(0).getName());
Error is
.....
><city xsi:type="xsd:string">London</city><country xsi:type="xsd:string">United Kingdom</country><postcode xsi:type="xsd:string">SE1 8XX</postcode><url xsi:type="xsd:string">http://www.ticketmaster.co.uk/The-London-Wonderground-tickets-London/venue/253993?camefrom=CFC_UK_BUYAT&brand=</url><imageUrl xsi:type="xsd:string">http://media.ticketmaster.co.uk/tmimages/TM_GenVenueImg_BW.jpg</imageUrl><state xsi:type="xsd:string"></state></venue></item></results></return></ns1:findEventsResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
>>ns1:findEventsResponse
[ns1:findEventsResponse: null]
result of d:null
error is here
java.lang.IllegalArgumentException: prefix xsd is not bound to a namespace
at com.sun.xml.internal.bind.DatatypeConverterImpl._parseQName(DatatypeConverterImpl.java:346)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.LeafPropertyXsiLoader.selectLoader(LeafPropertyXsiLoader.java:75)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.LeafPropertyXsiLoader.startElement(LeafPropertyXsiLoader.java:58)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:486)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:465)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:60)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:135)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:229)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:266)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:235)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:266)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:235)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:266)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:235)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:266)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:235)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:112)
at com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:95)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:312)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:288)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:238)
at javax.xml.bind.JAXB.unmarshal(JAXB.java:259)
at com.ticketmaster.ticketmaster.TicketMaster.Search(TicketMaster.java:132)
at com.ticketmaster.ticketmaster.App.main(App.java:12)
Ensure You Are Unmarshalling the Correct Thing
You need to unmarshal the content held onto by SOAP body, not the entire SOAP message. Below is what the code might look like:
SOAPMessage sm = response;
SOAPBody sb = response.getSOAPBody();
Document d = sb.extractContentAsDocument();
DOMSource source = new DOMSource(d);
results = (FindEventsResponse) JAXB.unmarshal(source, FindEventsResponse.class);
The result of sb.extractContentAsDocument is going to be a DOM that is equivalent to the following:
<?xml version="1.0" encoding="UTF-8"?>
<ns1:findEventsResponse xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://ticketmaster.productserve.com/v2/soap.php"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="ns1:Response">
<details xsi:type="ns1:Details">
<totalResults xsi:type="xsd:int">20662</totalResults>
<totalPages xsi:type="xsd:int">414</totalPages>
<currentPage xsi:type="xsd:int">1</currentPage>
<resultsPerPage xsi:type="xsd:int">50</resultsPerPage>
</details>
<results SOAP-ENC:arrayType="ns1:Event[50]" xsi:type="ns1:ArrayOfEvent">
<item xsi:type="ns1:Event">
<eventId xsi:type="xsd:int">1516682</eventId>
<ticketmasterEventId xsi:type="xsd:string">18004C6E8D7218A8</ticketmasterEventId>
<status xsi:type="xsd:string">onSale</status>
<name xsi:type="xsd:string">The Art of the Brick</name>
<url xsi:type="xsd:string">http://www.ticketmaster.ie/event/18004C6E8D7218A8?camefrom=CFC_UK_BUYAT&brand=[=BRAND=]</url>
<eventDate xsi:type="xsd:string">2014-05-23 10:00:00</eventDate>
<onSaleDate xsi:type="xsd:string">0000-00-00 00:00:00</onSaleDate>
<preSaleDate xsi:type="xsd:string">0000-00-00 00:00:00</preSaleDate>
<category xsi:type="xsd:string">Exhibitions</category>
<categoryId xsi:type="xsd:int">754</categoryId>
<parentCategory xsi:type="xsd:string">Family &amp; Attractions</parentCategory>
<parentCategoryId xsi:type="xsd:int">10003</parentCategoryId>
<minPrice xsi:type="xsd:float">17</minPrice>
<maxPrice xsi:type="xsd:float">17</maxPrice>
<artists SOAP-ENC:arrayType="ns1:Artist[1]" xsi:type="ns1:ArrayOfArtist">
<item xsi:type="ns1:Artist">
<artistId xsi:type="xsd:int">1806028</artistId>
<ticketmasterArtistId xsi:type="xsd:int">1663495</ticketmasterArtistId>
<name xsi:type="xsd:string">The Art of the Brick</name>
<url xsi:type="xsd:string">http://www.ticketmaster.co.uk/The-Art-of-the-Brick-tickets/artist/1663495?camefrom=CFC_UK_BUYAT&brand=[=BRAND=]</url>
<imageUrl xsi:type="xsd:string">http://media.ticketmaster.com/tm/en-us/tmimages/TM_GenCatImgs_Generic_BW.jpg</imageUrl>
<category xsi:type="xsd:string">Miscellaneous</category>
<categoryId xsi:type="xsd:int">0</categoryId>
<parentCategory xsi:type="xsd:string">Miscellaneous</parentCategory>
<parentCategoryId xsi:type="xsd:int">10005</parentCategoryId>
</item>
</artists>
<venue xsi:type="ns1:Venue">
<venueId xsi:type="xsd:int">3331</venueId>
<ticketmasterVenueId xsi:type="xsd:int">198292</ticketmasterVenueId>
<name xsi:type="xsd:string">Ambassador Theatre</name>
<street xsi:type="xsd:string">Oconnell Street</street>
<city xsi:type="xsd:string">Dublin</city>
<country xsi:type="xsd:string">United Kingdom</country>
<postcode xsi:type="xsd:string">Dublin 1</postcode>
<url xsi:type="xsd:string">http://www.ticketmaster.ie/Ambassador-Theatre-tickets-Dublin/venue/198292?camefrom=CFC_UK_BUYAT&brand=</url>
<imageUrl xsi:type="xsd:string">http://media.ticketmaster.co.uk/tmimages/TM_GenVenueImg_BW.jpg</imageUrl>
<state xsi:type="xsd:string"></state>
</venue>
</item>
<item xsi:type="ns1:Event"></item>
</results>
</return>
</ns1:findEventsResponse>
UPDATE
Based on the new exception you are getting:
java.lang.IllegalArgumentException: prefix xsd is not bound to a namespace
at com.sun.xml.internal.bind.DatatypeConverterImpl._parseQName(DatatypeConverterImpl.java:346)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.LeafPropertyXsiLoader.selectLoader(LeafPropertyXsiLoader.java:75)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.LeafPropertyXsiLoader.startElement(LeafPropertyXsiLoader.java:58)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:486)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:465)
It appears as though sb.extractContentAsDocument(); is not bringing along the xmlns:xsd declaration from the SOAP message. Instead you can change the code to do the following:
SOAPMessage sm = response;
SOAPBody sb = response.getSOAPBody();
DOMSource source = new DOMSource(sb.getFirstChild());
results = (FindEventsResponse) JAXB.unmarshal(source, FindEventsResponse.class);
Ensure the Namespace Qualification is Mapped Correctly
Having the following tells JAXB that everything mapped to an XML element without an explicitly specified namespace should belong in the http://ticketmaster.productserve.com/v2/soap.php namespace.
#XmlSchema(
namespace = "http://ticketmaster.productserve.com/v2/soap.php",
elementFormDefault = XmlNsForm.QUALIFIED)
package com.ticketmaster.ticketmaster;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
In your XML only the findEventsResponse element is namespace qualified. This means your annotation should be the following instead (note change from QUALIFIED to UNQUALIFIED):
#XmlSchema(
namespace = "http://ticketmaster.productserve.com/v2/soap.php",
elementFormDefault = XmlNsForm.UNQUALIFIED)
package com.ticketmaster.ticketmaster;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
Demo Code
Using the above XML as input.xml I was able to unmarshal and marshal the model as you have defined it in your question with the #XmlSchema fix mentioned above.
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(FindEventsResponse.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
StreamSource xml = new StreamSource("src/forum23806625/input.xml");
JAXBElement<FindEventsResponse> response = unmarshaller.unmarshal(xml, FindEventsResponse.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(response, System.out);
}
}

Categories

Resources