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.
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 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.
I am using the socialauth library following this tutorial:
https://github.com/3pillarlabs/socialauth/wiki/Getting-Started-with-implementing-SocialAuth
Everything works find, I just do not understand where/what to store after the end of step 3. I mean I do not want to force the user to login every click. I tried to figure this out from the examples but I could not ....
Here is what I have:
#WebServlet("/success")
public class AfterOAuth extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
// get the auth provider manager from session
SocialAuthManager manager = (SocialAuthManager) req.getSession().getAttribute("authManager");
// call connect method of manager which returns the provider object.
// Pass request parameter map while calling connect method.
Map<String, String> paramsMap = SocialAuthUtil.getRequestParametersMap(req);
AuthProvider provider = manager.connect(paramsMap);
// get profile
Profile p = provider.getUserProfile();
// you can obtain profile information
resp.getOutputStream().print(p.getFirstName());
// OK, everything is fine by now what should I store in my Session?
} catch (Exception e) {
throw new ServletException(e);
}
}
}
Ok, I found a solution by using the provided CDI Class and overwrote simply the init() and servlet sections to so:
package com.test.oauth;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Properties;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import config.KicEngineRootRessourceLoader;
import org.apache.log4j.Logger;
import org.brickred.socialauth.AuthProvider;
import org.brickred.socialauth.AuthProviderFactory;
import org.brickred.socialauth.Contact;
import org.brickred.socialauth.Profile;
import org.brickred.socialauth.SocialAuthConfig;
import org.brickred.socialauth.SocialAuthManager;
import org.brickred.socialauth.util.SocialAuthUtil;
/**
* Created by kic on 19.02.15.
*/
#Named("socialauth")
#SessionScoped
public class SocialAuth implements Serializable {
/**
* Serial version UID generated by Eclipse
*/
private static final long serialVersionUID = 1789108831048043099L;
private static final Logger log = Logger.getLogger( SocialAuth.class);
private String id;
private Profile profile;
private AuthProvider provider;
private String status;
private String viewUrl;
private SocialAuthManager manager;
private SocialAuthConfig config;
public void init() {
id = null;
provider = null;
config = new SocialAuthConfig().getDefault();
try {
Properties oauth = new Properties();
KicEngineRootRessourceLoader.loadProperties(oauth, "oauth_consumer");
config.load(oauth);
manager = new SocialAuthManager();
manager.setSocialAuthConfig(config);
} catch (Exception e) {
e.printStackTrace();
}
}
public SocialAuth() {
init();
}
public String getId() {
return id;
}
/**
* Sets the authentication provider. It is mandatory to do this before
* calling login
*
* #param id
* Can either have values facebook, foursquare, google, hotmail,
* linkedin, myspace, twitter, yahoo OR an OpenID URL
*/
public void setId(final String id) {
this.id = id;
}
/**
* Sets the view URL to which the user will be redirected after
* authentication
*
* #param viewUrl
* Relative URL of the view, for example "/openid.xhtml"
*/
public void setViewUrl(final String viewUrl) {
this.viewUrl = viewUrl;
}
/**
* Gets the relative URL of the view to which user will be redirected after
* authentication
*
* #return relative URL of the view
*/
public String getViewUrl() {
return viewUrl;
}
/**
* This is the most important action. It redirects the browser to an
* appropriate URL which will be used for authentication with the provider
* you set using setId()
*
* #throws Exception
*/
public void login(HttpServletRequest req, HttpServletResponse resp) throws Exception {
//String url = manager.getAuthenticationUrl(req.getParameter("provider"), successUrl);
String returnToUrl = viewUrl;
String url = manager.getAuthenticationUrl(id, returnToUrl);
// Store in session
req.getSession().setAttribute("authManager", manager);
// redirect
log.info("Redirecting to:" + url);
resp.sendRedirect(url);
}
/**
* Verifies the user when the external provider redirects back to our
* application
*
* #throws Exception
*/
public void connect(HttpServletRequest request) throws Exception {
provider = manager.connect(SocialAuthUtil.getRequestParametersMap(request));
profile= provider.getUserProfile();
}
/**
* Reinitializes the bean
*/
public void logout() {
init();
}
/**
* Returns the Profile information for the user. Should be called only after
* loginImmediately()
*
* #return Profile of the user
*/
public Profile getProfile() {
return profile;
}
/**
* Status of the user to be updated on a provider like Facebook or Twitter.
* Remember this will not give us the current status of the user
*
* #return status message to be updated
*/
public String getStatus() {
return status;
}
/**
* Status of the user to be updated on a provider like Facebook or Twitter.
* To actually update the status, call updateStatus action.
*
* #param status
*/
public void setStatus(final String status) {
this.status = status;
}
/**
* Updates the status on the given provider. Exception will be thrown if the
* provider does not provide this facility
*/
public void updateStatus() throws Exception {
provider.updateStatus(status);
}
/**
* Gets the list of contacts available from the provider. This may be used
* to import contacts of any user in your web application from your chosen
* provider like Gmail, Yahoo or Hotmail
*
* #return list of contacts
*/
public List<Contact> getContactList() throws Exception {
return provider.getContactList();
}
/**
* Retrieves the user profile from the provider.
*
* #return Profile object containing the profile information.
* #throws Exception
*/
public Profile getUserProfile() throws Exception {
return provider.getUserProfile();
}
}
Now I simply can use #Inject SocialAuth wherever needed.
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.
Im using Jersey to build a REST Service and want to return a Collection<String> as XML.
#GET
#Produces(MediaType.TEXT_XML)
#Path("/directgroups")
public Response getDirectGroupsForUser(#PathParam("userId") String userId) {
try {
Collection<String> result = service.getDirectGroupsForUser(userId, null, true);
// return result; //first try
// return result.toArray(new String[0]); //second try
return Response.ok().type(MediaType.TEXT_XML).entity(result).build(); //third try
} catch (UserServiceException e) {
LOGGER.error(e);
throw new RuntimeException(e.getMessage());
}
}
but my attempts fail with the following exception:
javax.ws.rs.WebApplicationException: com.sun.jersey.api.MessageException: A message body writer for Java class java.util.ArrayList, and Java type class java.util.ArrayList, and MIME media type text/xml was not found
and all results to that exception I found via google dealt with returning text/json instead of text/xml like in my situation.
Can anyone help me? I thought, if I use a Response, that would be my root element in XML and my collection a list of string elements in it..
Use
List<String> list = new ArrayList<String>();
GenericEntity<List<String>> entity = new GenericEntity<List<String>>(list) {};
Response response = Response.ok(entity).build();
The Generic entity wrapper works to get the output when using the Response builder.
Reference
NOTE: Although this answer works, anar's answer is better.
You should try to use a JAXB annotated class to solve your problem. You could change your method to this:
#GET
#Produces(MediaType.TEXT_XML)
#Path("/directgroups")
public Groups getDirectGroupsForUser(#PathParam("userId") String userId) {
try {
Groups groups = new Groups();
groups.getGroup().addAll(service.getDirectGroupsForUser(userId, null, true));
return groups;
} catch (UserServiceException e) {
LOGGER.error(e);
throw new RuntimeException(e.getMessage());
}
}
And then create a JAXB annotated class for your groups. I have included a generated class for you, using the process described in this answer. Here is an example of the documents that it will produce:
<groups>
<group>Group1</group>
</group>Group2</group>
</groups>
And here is the generated class:
package example;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
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 ref="{}group" maxOccurs="unbounded"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"group"
})
#XmlRootElement(name = "groups")
public class Groups {
#XmlElement(required = true)
protected List<String> group;
/**
* Gets the value of the group property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the group property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getGroup().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {#link String }
*
*
*/
public List<String> getGroup() {
if (group == null) {
group = new ArrayList<String>();
}
return this.group;
}
}
The only thing that worked for me so far is to create my own Wrapper object.
Don't forget the #XmlRootElement annotation to explain JAXB how to parse it.
Note that this will work for any type of object - in this example I used ArrayList of String.
e.g.
The Wrapper object should look like this:
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class ArrayListWrapper {
public ArrayList<String> myArray = new ArrayList<String>();
}
And the REST method should look like this:
#GET
#Produces(MediaType.TEXT_XML)
#Path("/directgroups")
public ArrayListWrapper getDirectGroupsForUser(#PathParam("userId") String userId) {
try {
ArrayListWrapper w = new ArrayListWrapper();
w.myArray = service.getDirectGroupsForUser(userId, null, true);
return w;
} catch (UserServiceException e) {
LOGGER.error(e);
throw new RuntimeException(e.getMessage());
}
}
adding #XmlRootElement(name = "class name") to the object I want to return , resolved my issue