I need to make a Soap client in java for the EU tax id service.
I mamanged to generate the code from the WSDL using wsimport. My problem is that cannot figure out how to use it. More specifically, how do I make a Soap call to the service so I can validate the tax id?
I tried even multiple ways using code generated from SOAP UI, code from Intellij, etc. They are all quite different and I am kinda stuck into this. Could anyone light me up, please? Thanks!
It seems rather difficult for me and I already spent so many hours on this without a result. I have also tried al the tutorials I could find on google. I am guessing an answer on this would help many in the future.
Here's the generated code:
CheckTinService.java:
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.WebServiceFeature;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.4-b01
* Generated source version: 2.2
*
*/
#WebServiceClient(name = "checkTinService", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin", wsdlLocation = "https://ec.europa.eu/taxation_customs/tin/checkTinService.wsdl")
public class CheckTinService
extends Service
{
private final static URL CHECKTINSERVICE_WSDL_LOCATION;
private final static WebServiceException CHECKTINSERVICE_EXCEPTION;
private final static QName CHECKTINSERVICE_QNAME = new QName("urn:ec.europa.eu:taxud:tin:services:checkTin", "checkTinService");
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL("https://ec.europa.eu/taxation_customs/tin/checkTinService.wsdl");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
CHECKTINSERVICE_WSDL_LOCATION = url;
CHECKTINSERVICE_EXCEPTION = e;
}
public CheckTinService() {
super(__getWsdlLocation(), CHECKTINSERVICE_QNAME);
}
public CheckTinService(WebServiceFeature... features) {
super(__getWsdlLocation(), CHECKTINSERVICE_QNAME);
}
public CheckTinService(URL wsdlLocation) {
super(wsdlLocation, CHECKTINSERVICE_QNAME);
}
public CheckTinService(URL wsdlLocation, WebServiceFeature... features) {
super(wsdlLocation, CHECKTINSERVICE_QNAME);
}
public CheckTinService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public CheckTinService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
super(wsdlLocation, serviceName);
}
/**
*
* #return
* returns CheckTinPortType
*/
#WebEndpoint(name = "checkTinPort")
public CheckTinPortType getCheckTinPort() {
return super.getPort(new QName("urn:ec.europa.eu:taxud:tin:services:checkTin", "checkTinPort"), CheckTinPortType.class);
}
/**
*
* #param features
* A list of {#link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* #return
* returns CheckTinPortType
*/
#WebEndpoint(name = "checkTinPort")
public CheckTinPortType getCheckTinPort(WebServiceFeature... features) {
return super.getPort(new QName("urn:ec.europa.eu:taxud:tin:services:checkTin", "checkTinPort"), CheckTinPortType.class, features);
}
private static URL __getWsdlLocation() {
if (CHECKTINSERVICE_EXCEPTION!= null) {
throw CHECKTINSERVICE_EXCEPTION;
}
return CHECKTINSERVICE_WSDL_LOCATION;
}
}
CheckTinPortType.java
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.ws.Holder;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import eu.europa.ec.taxud.tin.services.checktin.types.ObjectFactory;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.4-b01
* Generated source version: 2.2
*
*/
#WebService(name = "checkTinPortType", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin")
#XmlSeeAlso({
ObjectFactory.class
})
public interface CheckTinPortType {
/**
*
* #param tinNumber
* #param countryCode
* #param validStructure
* #param requestDate
* #param validSyntax
*/
#WebMethod
#RequestWrapper(localName = "checkTin", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", className = "eu.europa.ec.taxud.tin.services.checktin.types.CheckTin")
#ResponseWrapper(localName = "checkTinResponse", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", className = "eu.europa.ec.taxud.tin.services.checktin.types.CheckTinResponse")
public void checkTin(
#WebParam(name = "countryCode", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", mode = WebParam.Mode.INOUT)
Holder<String> countryCode,
#WebParam(name = "tinNumber", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", mode = WebParam.Mode.INOUT)
Holder<String> tinNumber,
#WebParam(name = "requestDate", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", mode = WebParam.Mode.OUT)
Holder<XMLGregorianCalendar> requestDate,
#WebParam(name = "validStructure", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", mode = WebParam.Mode.OUT)
Holder<Boolean> validStructure,
#WebParam(name = "validSyntax", targetNamespace = "urn:ec.europa.eu:taxud:tin:services:checkTin:types", mode = WebParam.Mode.OUT)
Holder<Boolean> validSyntax);
}
ObjectFactory.java:
import com.exiqon.core.eu.europa.ec.taxud.tin.services.checktin.types.CheckTin;
import com.exiqon.core.eu.europa.ec.taxud.tin.services.checktin.types.CheckTinResponse;
import javax.xml.bind.annotation.XmlRegistry;
/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the eu.europa.ec.taxud.tin.services.checktin.types package.
* <p>An ObjectFactory allows you to programatically
* construct new instances of the Java representation
* for XML content. The Java representation of XML
* content can consist of schema derived interfaces
* and classes representing the binding of schema
* type definitions, element declarations and model
* groups. Factory methods for each of these are
* provided in this class.
*
*/
#XmlRegistry
public class ObjectFactory {
/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: eu.europa.ec.taxud.tin.services.checktin.types
*
*/
public ObjectFactory() {
}
/**
* Create an instance of {#link eu.europa.ec.taxud.tin.services.checktin.types.CheckTin }
*
*/
public CheckTin createCheckTin() {
return new CheckTin();
}
/**
* Create an instance of {#link CheckTinResponse }
*
*/
public CheckTinResponse createCheckTinResponse() {
return new CheckTinResponse();
}
}
CheckTinResponse.java:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="countryCode" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="tinNumber" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="requestDate" type="{http://www.w3.org/2001/XMLSchema}date"/>
* <element name="validStructure" type="{http://www.w3.org/2001/XMLSchema}boolean"/>
* <element name="validSyntax" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"countryCode",
"tinNumber",
"requestDate",
"validStructure",
"validSyntax"
})
#XmlRootElement(name = "checkTinResponse")
public class CheckTinResponse {
#XmlElement(required = true)
protected String countryCode;
#XmlElement(required = true)
protected String tinNumber;
#XmlElement(required = true)
#XmlSchemaType(name = "date")
protected XMLGregorianCalendar requestDate;
protected boolean validStructure;
protected Boolean validSyntax;
/**
* Gets the value of the countryCode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getCountryCode() {
return countryCode;
}
/**
* Sets the value of the countryCode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setCountryCode(String value) {
this.countryCode = value;
}
/**
* Gets the value of the tinNumber property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTinNumber() {
return tinNumber;
}
/**
* Sets the value of the tinNumber property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTinNumber(String value) {
this.tinNumber = value;
}
/**
* Gets the value of the requestDate property.
*
* #return
* possible object is
* {#link XMLGregorianCalendar }
*
*/
public XMLGregorianCalendar getRequestDate() {
return requestDate;
}
/**
* Sets the value of the requestDate property.
*
* #param value
* allowed object is
* {#link XMLGregorianCalendar }
*
*/
public void setRequestDate(XMLGregorianCalendar value) {
this.requestDate = value;
}
/**
* Gets the value of the validStructure property.
*
*/
public boolean isValidStructure() {
return validStructure;
}
/**
* Sets the value of the validStructure property.
*
*/
public void setValidStructure(boolean value) {
this.validStructure = value;
}
/**
* Gets the value of the validSyntax property.
*
* #return
* possible object is
* {#link Boolean }
*
*/
public Boolean isValidSyntax() {
return validSyntax;
}
/**
* Sets the value of the validSyntax property.
*
* #param value
* allowed object is
* {#link Boolean }
*
*/
public void setValidSyntax(Boolean value) {
this.validSyntax = value;
}
}
CheckTin.java:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="countryCode" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="tinNumber" type="{http://www.w3.org/2001/XMLSchema}string"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"countryCode",
"tinNumber"
})
#XmlRootElement(name = "checkTin")
public class CheckTin {
#XmlElement(required = true)
protected String countryCode;
#XmlElement(required = true)
protected String tinNumber;
/**
* Gets the value of the countryCode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getCountryCode() {
return countryCode;
}
/**
* Sets the value of the countryCode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setCountryCode(String value) {
this.countryCode = value;
}
/**
* Gets the value of the tinNumber property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTinNumber() {
return tinNumber;
}
/**
* Sets the value of the tinNumber property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTinNumber(String value) {
this.tinNumber = value;
}
}
sample client code.
public class WsTest {
public static void main(String[] args) {
try {
CheckTinService checkTinService = new CheckTinService();
CheckTinPortType portType = checkTinService.getPort(CheckTinPortType.class);
Holder<String> code = new Holder<String>("DE");
Holder<String> tin = new Holder<String>("12346789");
Holder<XMLGregorianCalendar> requestDate = new Holder<>();
Holder<Boolean> validStructure = new Holder<>();
Holder<Boolean> validSyntax = new Holder<>();
portType.checkTin(code, tin, requestDate, validStructure, validSyntax);
System.out.println("requestDate : " + requestDate.value);
System.out.println("validStructure : " + validStructure.value);
System.out.println("validSyntax : " + validSyntax.value);
} catch (Exception e) {
e.printStackTrace();
}
}
}
you can also add handler for response soap message.
or from soap UI : send below request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:ec.europa.eu:taxud:tin:services:checkTin:types">
<soapenv:Header/>
<soapenv:Body>
<urn:checkTin>
<urn:countryCode>DE</urn:countryCode>
<urn:tinNumber>12346789</urn:tinNumber>
</urn:checkTin>
</soapenv:Body>
</soapenv:Envelope>
What's the problem here?
Get a CheckTinPortType by calling a properly initialized CheckTinService's getCheckTinPort(), and use that to perform the call.
All the necessary classes are generated, you just need to perform the checkTin() call now with the appropriate parameters.
Related
Facing issues with unmarshalling using JAXB. I need to use multiple namespaces.
The Java classes are generated for the XSDs provided by a third party. So I do not want to specify the namespace at XMLRootElement in the Java classes and do not want to manually change multiple classes.
The marshalling logic as below:
private <R extends BasicResponseType, T extends BasicRequestType> R doPost(T request, String requestname) throws Exception {
if (jaxbContext == null)
jaxbContext = JAXBContext.newInstance(TokenRequest.class, TokenResponse.class,
BasicResponseType.class, GeneralErrorResponse.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
logXML(marshaller, request);
// POST to baseURL/requestname and show response
HttpURLConnection conn = openConnection("/" + requestname);
OutputStream os = conn.getOutputStream();
marshaller.marshal(request, os);
os.flush();
// Normaler Output oder Error liefern, je nach HTTP Response
InputStream is = null;
boolean ok = true;
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
is = conn.getErrorStream();
ok = false;
} else {
is = conn.getInputStream();
}
R response = (R) unmarshaller.unmarshal(new StreamSource(is));
is.close();
conn.disconnect();
logXML(marshaller, response);
if (ok) {
return response;
} else {
throw new Exception(getMessages((GeneralErrorResponse) response));
}
}
The xmlelement class TokenRequest.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "")
#XmlRootElement(name = "TokenRequest")
public class TokenRequest
extends BasicInRequestType{ }
BasicInRequestType.java
package exp._3_0.api;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "BasicInRequestType", propOrder = {
"software"
})
#XmlSeeAlso({
TokenRequest.class
})
public class BasicInRequestType
extends BasicRequestType {
#XmlElement(required = true)
protected SoftwareType software;
/**
* Gets the value of the software property.
*
* #return
* possible object is
* {#link SoftwareType }
*
*/
public SoftwareType getSoftware() {
return software;
}
/**
* Sets the value of the software property.
*
* #param value
* allowed object is
* {#link SoftwareType }
*
*/
public void setSoftware(SoftwareType value) {
this.software = value;
}}
BasicRequestType.java
package exp._3_0.api;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
propOrder = {
"header",
"user"
})
#XmlSeeAlso({
BasicInRequestType.class
})
public class BasicRequestType {
#XmlElement(required = true)
protected BasicHeaderType header;
#XmlElement(required = true)
protected UserHeaderType user;
#XmlType(name = "BasicRequestType", namespace = "http://foo/1.0/common",
/**
* Gets the value of the header property.
*
* #return
* possible object is
* {#link BasicHeaderType }
*
*/
public BasicHeaderType getHeader() {
return header;
}
/**
* Sets the value of the header property.
*
* #param value
* allowed object is
* {#link BasicHeaderType }
*
*/
public void setHeader(BasicHeaderType value) {
this.header = value;
}
/**
* Gets the value of the user property.
*
* #return
* possible object is
* {#link UserHeaderType }
*
*/
public UserHeaderType getUser() {
return user;
}
/**
* Sets the value of the user property.
*
* #param value
* allowed object is
* {#link UserHeaderType }
*
*/
public void setUser(UserHeaderType value) {
this.user = value;
}}
XML Output :
<TokenRequest xmlns:common="http://foo/1.0/common" xmlns:ns4="http://foo/3.0/api" xmlns:base="http://foo/3.0/base">
<common:header>
<common:requestId></common:requestId>
<common:timestamp></common:timestamp>
</common:header>
<common:user>
<common:login></common:login>
<common:passwordHash></common:passwordHash>
</common:user>
<software>
<softwareId></softwareId>
<softwareName></softwareName>
</software>
</TokenRequest>
I have specifies the prefix in package-info.java
#javax.xml.bind.annotation.XmlSchema(elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED, xmlns = {
#javax.xml.bind.annotation.XmlNs(namespaceURI = "http://foo/3.0/api", prefix = ""),
#javax.xml.bind.annotation.XmlNs(namespaceURI = "http://foo/3.0/base", prefix = "base"),
#javax.xml.bind.annotation.XmlNs(namespaceURI = "http://foo/1.0/common", prefix = "common") })
package exp._3_0.api;
The TokenRequest element actually refers to the namespace = "http://foo/3.0/api". In the xml output the TokenRequest does not have the any prefix which is correct but the xmlns is set to ns4 which is causing the below error.
Request body contains on line: [1] and column: [182] error:
[unexpected element (uri:"", local:"TokenRequest"). Expected elements
are <{http://foo/3.0/api}TokenRequest>]
Even after specifying the prefix = "" for namespace "http://foo/3.0/api" in package-info, in the output its still appending as ns4. Please help how to fix remove the ns4.
As remarked in the comments, your #XmlSchema lacks a namespace attribute, therefore all #XmlRootElement and #XmlType are considered to be without a namespace, unless explicitly qualified. Your java-package.info should look like this:
#XmlSchema(elementFormDefault = XmlNsForm.QUALIFIED, namespace = "http://foo/3.0/api", xmlns = {
#XmlNs(namespaceURI = "http://foo/3.0/api", prefix = ""),
#XmlNs(namespaceURI = "http://foo/3.0/base", prefix = "base"),
#XmlNs(namespaceURI = "http://foo/1.0/common", prefix = "common")})
package exp._3_0.api;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
The #XmlNs annotation does not specify the default namespace used in the Java package. They only provide a suggestion to the JAXB implementation on what prefixes to assign to those namespaces. In your example the tags <TokenRequest>, <software>, <softwareId> and <softwareName> do not belong to any namespace, therefore JAXB uses an empty prefix for these elements and must use another prefix (ns4) for the elements in the http://foo/3.0/api namespace (there aren't any).
I have a class ShipmentRequest which was initialized through JAXB.
In my main class to send a REST-API POST-Request I am filling an object of this class with the needed input and put it in a JSONArray
public JSONArray array = new JSONArray();
array.add(shipmentRequest);
And finally I am starting the POST:
HttpResponse<JsonNode> response = Unirest.post("https://someURL/services/rest/url")
.queryString("access_token","someTokenCode")
.body(array.get(0)).asJson();
I do not understand the error, because when I use myJSONArray.toJSONString() I get following output:
[{"Id":"123456","Reference":"Send","transport":{"transporterCode":"Deliverer","trackAndTrace":"someCode123456"}}]
What am I missing? My first character is a '[' ?
EDIT 1, Code of ShipmentRequest
//
// Diese Datei wurde mit der JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 generiert
// Siehe http://java.sun.com/xml/jaxb
// Änderungen an dieser Datei gehen bei einer Neukompilierung des Quellschemas verloren.
// Generiert: 2017.10.18 um 11:02:47 AM CEST
//
package bol.shipment;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java-Klasse für anonymous complex type.
*
* <p>Das folgende Schemafragment gibt den erwarteten Content an, der in dieser Klasse enthalten ist.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="OrderItemId" type="{http://www.w3.org/2001/XMLSchema}long"/>
* <element name="ShipmentReference" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="Transport" minOccurs="0">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="TransporterCode" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="TrackAndTrace" type="{https://plazaapi.bol.com/services/xsd/v2/plazaapi.xsd}TrackAndTrace" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </element>
* <element name="ShippingLabelCode" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"orderItemId",
"shipmentReference",
"transport",
})
#XmlRootElement(name = "ShipmentRequest")
public class ShipmentRequest {
#XmlElement(name = "OrderItemId")
protected String orderItemId;
#XmlElement(name = "ShipmentReference", required = true)
protected String shipmentReference;
#XmlElement(name = "Transport")
protected ShipmentRequest.Transport transport;
/**
* Ruft den Wert der orderItemId-Eigenschaft ab.
*
*/
public String getOrderItemId() {
return orderItemId;
}
/**
* Legt den Wert der orderItemId-Eigenschaft fest.
*
*/
public void setOrderItemId(String value) {
this.orderItemId = value;
}
/**
* Ruft den Wert der shipmentReference-Eigenschaft ab.
*
* #return
* possible object is
* {#link String }
*
*/
public String getShipmentReference() {
return shipmentReference;
}
/**
* Legt den Wert der shipmentReference-Eigenschaft fest.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setShipmentReference(String value) {
this.shipmentReference = value;
}
/**
* Ruft den Wert der transport-Eigenschaft ab.
*
* #return
* possible object is
* {#link ShipmentRequest.Transport }
*
*/
public ShipmentRequest.Transport getTransport() {
return transport;
}
/**
* Legt den Wert der transport-Eigenschaft fest.
*
* #param value
* allowed object is
* {#link ShipmentRequest.Transport }
*
*/
public void setTransport(ShipmentRequest.Transport value) {
this.transport = value;
}
/**
* <p>Java-Klasse für anonymous complex type.
*
* <p>Das folgende Schemafragment gibt den erwarteten Content an, der in dieser Klasse enthalten ist.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="TransporterCode" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="TrackAndTrace" type="{https://plazaapi.bol.com/services/xsd/v2/plazaapi.xsd}TrackAndTrace" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"transporterCode",
"trackAndTrace"
})
public static class Transport {
#XmlElement(name = "TransporterCode")
protected String transporterCode;
#XmlElement(name = "TrackAndTrace")
protected String trackAndTrace;
/**
* Ruft den Wert der transporterCode-Eigenschaft ab.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTransporterCode() {
return transporterCode;
}
/**
* Legt den Wert der transporterCode-Eigenschaft fest.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTransporterCode(String value) {
this.transporterCode = value;
}
/**
* Ruft den Wert der trackAndTrace-Eigenschaft ab.
*
* #return
* possible object is
* {#link String }
*
*/
public String getTrackAndTrace() {
return trackAndTrace;
}
/**
* Legt den Wert der trackAndTrace-Eigenschaft fest.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setTrackAndTrace(String value) {
this.trackAndTrace = value;
}
}
}
EDIT 2:
My Request should look like this!
<ShipmentRequest xmlns="https://plazaapi.bol.com/services/xsd/v2.1/plazaapi.xsd">
<OrderItemId>1234567890</OrderItemId>
<ShipmentReference>A321SR</ShipmentReference>
<Transport>
<TransporterCode>TNT</TransporterCode>
<TrackAndTrace>3SBOL0987654321</TrackAndTrace>
</Transport>
</ShipmentRequest>
EDIT 3:
I tried filling a JSONObject with these:
private JSONArray shipmentRequestArray = new JSONArray();
private JSONArray transportArray = new JSONArray();
private JSONObject requestObject = new JSONObject();
transportArray.add(new JSONObject().append("TransporterCode", transporter_Code));
transportArray.add(new JSONObject().append("TrackAndTrace", track_And_Trace));
shipmentRequestArray.add(new JSONObject().append("OrderItemId", orderItemIdTEST));
shipmentRequestArray.add(new JSONObject().append("ShipmentReference", shipment_Reference));
shipmentRequestArray.add(transportArray);
requestObject.put("ShipmentRequest", shipmentRequestArray);
And when I tried this with:
.body(requestObject).asJson();
I get the new error:
No serializer found for class org.codehaus.jettison.json.JSONObject and no properties discovered to create BeanSerializer
EDIT 4:
My example response should look like this:
Status: 201 created
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns1:ProcessStatus xmlns:ns1="https://plazaapi.bol.com/services/xsd/v2/plazaapi.xsd">
<ns1:id>1</ns1:id>
<ns1:sellerId>1084486</ns1:sellerId>
<ns1:entityId>1234567890</ns1:entityId>
<ns1:eventType>CONFIRM_SHIPMENT</ns1:eventType>
<ns1:description>Confirm shipment for order item 1234567890.</ns1:description>
<ns1:status>PENDING</ns1:status>
<ns1:createTimestamp>2016-02-17T17:30:00.142+01:00</ns1:createTimestamp>
<ns1:Links>
<ns1:link ns1:method="GET" ns1:href="https://plazaapi.bol.com/services/rest/process-status/v2/1234567" ns1:rel="self"/>
</ns1:Links>
</ns1:ProcessStatus>
Error is about wrong type of object. First character should be '[', but it's not - I guess its '{'.
It is because you are executing array.get(0), which returns you an JSONObject, where JSONArray is required.
UPD:
I did some debugging with additional info you provided.
Problem was that Unirest.post returns an object of RequestBodyEntity class. To convert it to json you need to get body of answer first via getBody().
Thats what worked for me:
ShipmentRequest shipmentRequest = new ShipmentRequest();
shipmentRequest.setOrderItemId("1234567890");
shipmentRequest.setShipmentReference("A321SR");
ShipmentRequest.Transport transport = new ShipmentRequest.Transport();
transport.setTrackAndTrace("3SBOL0987654321");
transport.setTransporterCode("TNT");
shipmentRequest.setTransport(transport);
String jsonRequest = new Gson().toJson(shipmentRequest);
RequestBodyEntity result = Unirest.post("https://plazaapi.bol.com/services/rest/shipments/v2")
.queryString(
"access_token",
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjaWQiOjMzMTgsInNlcSI6MSwidHlwIjoiYXBpIiwidnNuIjoxLCJuYmYiOjE1MTcyOTc2NjF9.hVdtwBfJAVfRVeBdf1XDAxe7Qpigwa0wmCvnF_Bicc8")
.body(jsonRequest);
System.out.println(new Gson().fromJson(result.getBody().toString(), ShipmentRequest.class));
You need to use result.getBody() to return object that you want.
After this you can do
System.out.println(result.getBody().toString())
to print it or
new Gson().fromJson(result.getBody().toString(), ShipmentRequest.class)
to save it into object of ShipmentRequest type.
I'm trying to unmarshall an xml file, but I get a binding exception, I'm new to using xml and schemas with java, but from what I can tell, it looks like a problem with the namespaces when it tries to bind the xml to an xsd schema I'm using.
I've been trying to work this out and I can't seem to find the issue. Thanks in advance.
This is the exception im getting:
javax.xml.bind.UnmarshalException: unexpected element (URI:"", local:"programacioAula"). Expected elements are <{http://www.xtec.cat/ProgramacioAula}programacioAula>
This is the namespaces declaration on the xml:
<programacioAula
xmlns:tns="http://www.xtec.cat/ProgramacioAula"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.xtec.cat/ProgramacioAula ProgramacioAula.xsd ">
This is the namespaces declaration on the xsd:
<schema
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.xtec.cat/ProgramacioAula"
xmlns:tns="http://www.xtec.cat/ProgramacioAula"
elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<element name="programacioAula" type="tns:ProgramacioAula"></element>
This is the pojo with the XML annotations:
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0-b52-fcs
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2015.06.04 at 10:32:59 PM CEST
//
package dani.java.model;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for ProgramacioAula complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="ProgramacioAula">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="resum" type="{http://www.xtec.cat/ProgramacioAula}Resum"/>
* <element name="unitatsFormatives" type="{http://www.xtec.cat/ProgramacioAula}UnitatsFormatives"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "programacioAula",namespace="http://www.xtec.cat/ProgramacioAula", propOrder = {
"resum",
"unitatsFormatives"
})
#XmlRootElement(name = "programacioAula")
public class ProgramacioAula {
#XmlElement(required = true)
protected Resum resum;
#XmlElement(required = true)
protected UnitatsFormatives unitatsFormatives;
/**
* Gets the value of the resum property.
*
* #return
* possible object is
* {#link Resum }
*
*/
public Resum getResum() {
return resum;
}
/**
* Sets the value of the resum property.
*
* #param value
* allowed object is
* {#link Resum }
*
*/
public void setResum(Resum value) {
this.resum = value;
}
/**
* Gets the value of the unitatsFormatives property.
*
* #return
* possible object is
* {#link UnitatsFormatives }
*
*/
public UnitatsFormatives getUnitatsFormatives() {
return unitatsFormatives;
}
/**
* Sets the value of the unitatsFormatives property.
*
* #param value
* allowed object is
* {#link UnitatsFormatives }
*
*/
public void setUnitatsFormatives(UnitatsFormatives value) {
this.unitatsFormatives = value;
}
}
This is the method where I'm trying to unmarshall the file:
public static ProgramacioAula readXML(File file) {
ProgramacioAula programacioAula = null;
try {
JAXBContext jaxbContext = JAXBContext.newInstance(dani.java.model.ObjectFactory.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
programacioAula = (ProgramacioAula) jaxbUnmarshaller.unmarshal(file);
} catch (JAXBException e) {
e.printStackTrace();
}
return programacioAula;
}
Your XML is in the default namespace:
<programacioAula
xmlns:tns="http://www.xtec.cat/ProgramacioAula"
I suspect you might need either
<tns:programacioAula
xmlns:tns="http://www.xtec.cat/ProgramacioAula"
or
<programacioAula
xmlns="http://www.xtec.cat/ProgramacioAula"
I'm using Netbeans IDE and I'm creating a webservivce client from a wsdl file.
Netbeans has created all the classes and I've inserted the webservice reference to a jsp page and Netbeans has generated the following code:
<%
try {
com.businessobjects.DataServicesServer service = new com.businessobjects.DataServicesServer();
com.businessobjects.RealTimeServices port = service.getRealTimeServices();
// TODO initialize WS operation arguments here
com.businessobjects.service.postcodelookup.input.PostcodeLookupRequest inputBody = null;
// TODO process result here
com.businessobjects.service.postcodelookup.output.PostcodeLookupReply result = port.postcodeLookup(inputBody);
out.println("Result = "+result);
} catch (Exception ex) {
// TODO handle custom exceptions here
}
%>
From this code I understand that I need to set a value for 'inputBody' (currently set as null by default) but I don't know what data type to use.
Here the code from PostcodeLookupReply.class
package com.businessobjects.service.postcodelookup.input;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="postcode">
* <simpleType>
* <restriction base="{http://www.w3.org/2001/XMLSchema}string">
* <maxLength value="7"/>
* </restriction>
* </simpleType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"postcode"
})
#XmlRootElement(name = "postcodeLookupRequest")
public class PostcodeLookupRequest {
#XmlElement(required = true)
protected String postcode;
/**
* Gets the value of the postcode property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getPostcode() {
return postcode;
}
/**
* Sets the value of the postcode property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setPostcode(String value) {
this.postcode = value;
}
}
The value that need to be passed to 'inputBody' will be created from a parameter value from a URL string. I just need to know what and how to convert it so that it's accepted by the class.
Any help will be appreciated.
Thanks
It would be a new PostcodeLookupRequest() with the setPostCode method called on that instance.
I have been given a wsdl for a SOAP webservice I need to consume. I have used the wsdl to create webservice classes in netbeans.
The SOAP Header requires a ServiceAuthHeader with username and password.
NetBeans did generate a ServiceAuthHeader class, but I do not know how I can add it to the SOAP Message that gets sent using the classes generated.
I know how to do it at a lower level, i.e. create a SOAPMEssage, add the header, connect to the service and send it, but I have never used jws before, where the nitty gritty bits are done for you, and I am struggling to find out where I add it in any documentation or tutorials.
The ServiceAuthHeader generated is this:
package com.theservice.webservice;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;
/**
* <p>Java class for ServiceAuthHeader complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="ServiceAuthHeader">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="Username" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="Password" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* </sequence>
* <anyAttribute/>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ServiceAuthHeader", propOrder = {
"username",
"password"
})
public class ServiceAuthHeader {
#XmlElement(name = "Username")
protected String username;
#XmlElement(name = "Password")
protected String password;
#XmlAnyAttribute
private Map<QName, String> otherAttributes = new HashMap<QName, String>();
/**
* Gets the value of the username property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getUsername() {
return username;
}
/**
* Sets the value of the username property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setUsername(String value) {
this.username = value;
}
/**
* Gets the value of the password property.
*
* #return
* possible object is
* {#link String }
*
*/
public String getPassword() {
return password;
}
/**
* Sets the value of the password property.
*
* #param value
* allowed object is
* {#link String }
*
*/
public void setPassword(String value) {
this.password = value;
}
/**
* Gets a map that contains attributes that aren't bound to any typed property on this class.
*
* <p>
* the map is keyed by the name of the attribute and
* the value is the string value of the attribute.
*
* the map returned by this method is live, and you can add new attribute
* by updating the map directly. Because of this design, there's no setter.
*
*
* #return
* always non-null
*/
public Map<QName, String> getOtherAttributes() {
return otherAttributes;
}
}
So I can succcesfully call the service using this:
private static PriceDetailRetunValue priceDetail(PriceDetailInputValue inputValue) {
com.theservice.webservice.WebService service = new com.theservice.webservice.WebService();
com.theservice.webservice.WebServiceSoap port = service.getWebServiceSoap12();
return port.priceDetail(inputValue);
}
and I can parse the response, which of course tells me I need to give credentials.
So how I do I get a handle on the actual SOAP Header message to be able to add the ServiceAuthHeader? I have been looking at the methods of the WebService that is created and seen you can get a request context, and I have seen how you can add credentials to the http request headers, but I haven;t been able to find anywhere to add to the SOAPMEssage.
Any help would be appreciated. Thanks.
I found the answer here http://www.javadb.com/using-a-message-handler-to-alter-the-soap-header-in-a-web-service-client
You need to create a handler, then tell your service to use it.
So my original method just has a couple of lines added
private static PriceDetailRetunValue priceDetail(PriceDetailInputValue inputValue) {
com.theservice.webservice.WebService service = new com.theservice.webservice.WebService();
HeaderHandlerResolver handlerResolver = new HeaderHandlerResolver();
service.setHandlerResolver(handlerResolver);
com.theservice.webservice.WebServiceSoap port = service.getWebServiceSoap12();
return port.priceDetail(inputValue);
}
and the HandlerResolver and Handler look like this...
package com.la.feed.xml.theservice;
import java.util.*;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.ws.handler.*;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class HeaderHandler implements SOAPHandler<SOAPMessageContext> {
#Override
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
try {
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
SOAPFactory soapFactory = SOAPFactory.newInstance();
Name headerName = soapFactory.createName("ServiceAuthHeader", "", "http://www.interhome.com/webservice");
SOAPHeaderElement headerElement = header.addHeaderElement(headerName);
Name username = soapFactory.createName("Username");
SOAPElement usernameElement = headerElement.addChildElement(username);
usernameElement.addTextNode("GB1009688");
Name password = soapFactory.createName("Password");
SOAPElement passwordElement = headerElement.addChildElement(password);
passwordElement.addTextNode("verbier");
} catch (Exception e) {
}
}
return outboundProperty;
}
#Override
public Set getHeaders() {
return null;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
return true;
}
#Override
public void close(MessageContext context) {
}
}
package com.la.feed.xml.theservice;
import java.util.*;
import javax.xml.ws.handler.*;
public class HeaderHandlerResolver implements HandlerResolver {
#Override
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
HeaderHandler hh = new HeaderHandler();
handlerChain.add(hh);
return handlerChain;
}
}
It needs to be finessed a little, but it does the job.