I am very new to the building of web-services, so please forgive my ignorance.
I have been given some an .wsdl files with some .xsd files that it imports.
I am told that a web-service can be created from the .wsdl file by using wsdl2java from the apache axis2 project.
The web-service I am trying to build is expecting to have data pushed to it and I would like to test it that I have the process right for data to be pushed to a web-service that I created.
The basis for my actions have been from here, but not too sure how much of it is applicable.
I am on a MacOSX but also have access to an ubuntu system too.
the steps I have taken so far are:
cd /directory/of/wsdl/file
wsdl2java.sh -uri tmp.wsdl -d adb -s
This creates a build.xml file and src directory
I then try and run
ant
or
ant jar.client
After this I am not too sure what to do, in order to get the web-server running so that I could test it...any suggestions would be greatly appreciated.
Thanks in advance.
In SOAP web service:-
The basic concept in web service is that it has consumer and producer.
A consumer is one which consumes a web service and a producer is one which produces a web service. A producer publish its service so that consumer can consume it. It basically publishes a wsdl file so that you can create a client code or jar out of it and can directly call it from your code. You can use soap UI to call the web service directly as well. If you are looking for generating producer code from wsdl as well it will not be good enough since it will not provide business logic to you and you need to implement it by yourself. This is not a recommended approach. Generally first java implementation is written and based on it a wsdl is created from which client jars are created for the clients to use the web service in their code. For directly testing the producer soapui is used.
If you want to create producer it is a straight forward process. Need to create a dynamic project in eclipse-->create a class-->use #WebService(serviceName="xyz") on class and similarly on method level define #WebMethod. Deploy it as run on server and you are done with your Hello World Web service producer.
For creating the client:-
Lets take an example of a published wsdl on the net as :-
http://www.webservicex.net/geoipservice.asmx?WSDL
First you need to create the client jar or java classes as :-
wsimport -keep -s C:\wsdl http://www.webservicex.net/geoipservice.asmx?WSDL
Look at the documentation or look at the service name in the wsdl.
It will be GeoIPService.
Now in your class call the webservice method as:-
package com.soap.client;
import net.webservicex.GeoIP;
import net.webservicex.GeoIPService;
import net.webservicex.GeoIPServiceSoap;
public class SoapWebServiceClient {
public static void main(String[] args) {
GeoIPService ipService = new GeoIPService();
GeoIPServiceSoap gp = ipService.getGeoIPServiceSoap();
GeoIP ip = gp.getGeoIP("117.198.208.1"); //google.com
System.out.println(ip.getCountryName());
}
}
Now similarly for local wsdl you can create classes and jars by
using axis2 or simply wsimport
Put your wsdl and schemas in a folder as shown below:-
C:\wsdl>wsimport -keep -s C:\wsdl C:\wsdl
C:\wsdl>wsimport -clientjar client.jar C:\wsdl
It will create a client for you. Look at the service name and similarly can test the deployed service from java code as shown above.
For testing using soapui you use need to download it and create a new soap project. Give any name and browse to your local drive where all the schema and wsdl is present. It will create all the requests for your. You need to fill in the values in the request parameters ("?") and run the service. If everything went well it will display a result.
Note:-
wsimport is a command line tool for the JAX-WS reference implementation. The JAX-WS RI uses JAXB for data-binding.
Axis2 merely implements the JAX-WS API to some extent, so the Java artifacts generated can be quite different compared to those generated by the JAX-WS RI. Also Axis2 doesn't use JAXB but instead offers the choice of ADB (default), Apache XmlBeans, or JiBX for data-binding. The most popularly used are either xmlbeans or JAXB.
You lookup the wsdl file from publishing URL and reverse engineer the webservice to generate the types so use wsimport
wsimport -d . -p servicesource -keep tmp.wsdl
Related
I'm consuming a webservice where the WSDL file contains imports to other wsdl and xsd schemas, e.g:
<import namespace="http://my.api.com/" location="http://other.server.com:8888/context/services/MyService?wsdl=1"/>
which in turn can import other files
<xsd:import namespace="http://my.api.com/" schemaLocation="http://other.server.com:8888/context/services/MyService?xsd=1"/>
The client is generated by cxf with a maven plugin. The main WSDL file is added as a classpath resource. However, at runtime it appears that the client actually needs access to other.server.com:8888 to resolve the WSDL completely. So the question is, does a tool exist for importing and resolving all URLs in a WSDL so that it is not dependent absolute server URLs in other imports in the WSDL, and suitable for including in a client project?
We do not control the WSDL, so we can't change it in the source.
Edit: Looking for a tool that works on Linux
Check the ServiceModel Metadata Utility Tool (Svcutil.exe) from Windows SDK.
svcutil /t:metadata http://service/metadataEndpoint
This tool locates or discovers, one or more related documents that describe a particular XML Web service using the Web Services Description Language (WSDL).
I don't know if I understood your question correctly. I'm having my battles with Jax-ws/SOAP too. :)
If you need to generate the java classes needed to call the webservice you can use Apache CXF. Inside it you have a wsdl2java. You can use it on linux.
Another option in Java SDK, on the bin folder there's the wsimport that you can use it too.
Edit: You can change the final URL at runtime using the Service class created by Apache CXF.
new SomeRandomJaxWSService(new URL(wsdl),new QName(namespace, serviceName))
I'm using wsdl2java to generate service. Arguments for generation are following:
-p com.dummy.tst.service -u -f -sp -s -b -ssi -d xmlbeans -uri /some/path/service.wsdl -ss -g -sd -o /some/path/gen
After generation I've got a services.xml file with line like
<parameter name="ServiceClass">com.dummy.tst.service.TestSoapBindingImpl</parameter>
Then in gen directory I've got TestSoapBindingImpl.java with list of methods but every method is defined as follows
throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#myMethod");
And also there's a TestSoapBindingStub.java file which actually contains implemented methods. In axis-1 there was only one file with methods description and implementation and in axis-2 I've got 2 files.
What should I do with these files? Impl file, that is specified as default service methods container (in services.xml) contains only dummies, so I can't use deployed service and replacing TestSoapBindingImpl with TestSoapBindingStub in services.xml also does not lead to the desired result.
TestSoapBindingStub.java is for the client. It contains code to call the web service on a remote system.
On the service side, every time a request comes in, Axis2 will create an object of the type specified in services.xml as the ServiceClass. It will then call the requested function within the ServiceClass object, using the object that was provided by the client.
Using the code generated by wsdl2java, every call to the service will create an object of type om.dummy.tst.service.TestSoapBindingImpl, which as you've noted will throw an exception for each call. There are two approaches to make a working service.
You can use the TestSoapBindingImpl.java file that you have as a starting point. Remove the throws line from each function and fill in each function body with the code that you actually want to execute when a request comes in.
Alternately, you can use services.xml as a starting point. Define a class of your own to be the service class. Replace the reference to com.dummy.tst.service.TestSoapBindingImpl with a reference to the name of your own service class. wsdl2java probably generated a file named something like TestSoapBindingSkeleton.java which defines the interface which the service class should implement. Your custom service class should implement this interface.
The projects that I've been working on use approach #2. We write our own service class which implements the skeleton interface. When packaging the service into an AAR file, you include the services.xml file in the AAR. Our packaging rule performs a text substitution on the generated services.xml to update the ServiceClass with the name of our service class.
I'm comparing the client stubs generated by IBM Rational Application Developer with Java's wsimport and notice that IBM RAD generates an extra class which is the SOAPProxy class. This class allows the setting of the URL of the web service.
How can I generate a SOAPProxy class in Java's wsimport? Are IBM RAD's wsimport and Java's wsimport the same?
Below are the classes generated by IBM RAD:
ObjectFactory.java
package-info.java
WSCalculator_Service.java
WSCalculator.java
WSCalculatorRequest.java
WSCalculatorResponse.java
WSCalculatorSOAPProxy.java - This is not generated on Java's wsimport. How can I generate this using Java's wsimport?
Each tool (JBoss WS, wsimport, Apache CXF, RAD, etc) that generates classes from a WSDL does it slightly differently and they don't all generate the same classes, although they are usually similar. But there will be a way to supply your own URL that points to a WSDL. I am not familiar with RAD and how it generates web services but my guess would be that the WSCalculator_Service class has a constructor that takes a URL argument:
WSCalculator_Service service = new WSCalculator_Service(new URL("http://www.domain.com/ws/file.wsdl"));
WSCalculator port = service.getWSCalculatorPort();
port.callWebService(param1, param2, ...);
Sometimes the constructor that takes a URL also requires a QName. I would look in the source and just copy the QName that it is using.
In RAD 9.1 when you select "Java Proxy" for "Client type:" in the Web Service Client pop up wizard, it creates the proxy code as well. The wsimport.exe included with RAD doesn't seem to create the proxy code via command line.
When I create a new Web service using RSA 7.5 IDE and Web Sphere 7.0 server from a Web Application, then I can see a few auto-generated files created by this process, namely:
1) For the service, a SEI file is created
2) For the models, ser, deser and helper files are created.
But I cant understand what are the use of all these SEI, ser, deser and helper files.
Any valid explanation on this will be much appreciated.
BOUNTY EDIT:
Bounty-Edit:
Since I did not get any response I would like to ask this question again - offering a bounty to encourage an in-depth answer. I would love to know how and when are these files used internally?
Regards,
Service Endpoint Interface (SEI):
SEI is the Java interface corresponding to the Web service port type
being implemented. It is defined by the JAX-RPC, which specifies the
language mapping from WSDL 1.1 to Java. Ref
Or
A service endpoint interface (SEI) is a Java interface that
declares the methods that a client can invoke on the service. Ref
These ser,dser,helper are helpers to convert an XML document into a java object and vice versa (WebServices). Ref
Files generated in the server project: (WebSphere Application Server 6.1 Ref)
According to the settings made during the run of the wizard, the following files in the WeatherJavaBeanWeb project have been created:
Service endpoint interface (SEI): itso.bean.WeatherJavaBean_SEI.java is the interface defining the methods exposed in the Web service.
WSDL file: /WebContent/WEB-INF/wsdl/WeatherJavaBean.wsdl describes the Web service.
Deployment descriptor: webservices.xml, ibm-webservices-ext.xml and ibm-webservices-bnd.xml. These files describe the Web service according to the Web services for J2EE style (JSR 109). The JAX-RPC mapping is described in the WeatherJavaBean_mapping.xml file.
Data mapping files: The helper beans in the itso.objects package perform the data conversion from XML to Java objects and back.
A servlet is defined in the Web deployment descriptor to invoke the JavaBean.
Hope this information help you.
Those files are related to the WebSphere mapping between Java, WSDL, and XML. They are automatically generated, and should not need to be edited. You should pretend they are not there (except if they are not there you may have trouble deploying...).
SEI - Service Endpoint Interface
ser - Serialize
deser - Deserialize
helper - ?
Here are some psuedo-helpful links, that may provide some more insight into your question:
IBM Technotes
WebSphere v6.1 Handbook (check Chapter 15 -> Creating a Web Service --> Generated Files)
All these files are basically generated for webservice.
A web service ia basically a port between 2 running applications independant of the framework or language.
Leta say if you are using java from one side of web service then for complete compilation the java end would need some class files that have those methids which you wish to call on the service.
For this a stub is generated. This stub is basically an interface(SEI).
Also websphere needs additional files for implementing the webservices functionality, thus tge helper files.
This is basically the summary of it.
I have done this on Websphere (re: title of this topic) using wsdl2java for generating wsdl to java mapping xml file.
My endpoint is a generic stateless EJB. The code in EJB is generated by traversing the each wsdl and getting the wsdl operation and stuck it in the generated remote EJB interface.
Each EJB method impl is generic and handles all the services the same.
Used instructions on this doc to do this on WAS: http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=/com.ibm.websphere.base.doc/info/aes/ae/twbs_devwbsjaxrpcwsdl.html
Now, I am asking you all for help if anyone has done something similar in Sun AS 9.1.
Starting from existing WSDL (and xsd) files. Knowing the sole EJB service endpoint implementation for each services are the same, and generating an EAR file (webservices.xml, ejb-jar.xml, etc).
Have struggled with wscompile and alike, but not getting anyware in the same fashion I did for WebSphere.
Thanks for help.
You want to create a WS client which runs under Sun AS? I don't know Sun AS in detail and I don't know the WS libraries it supplies. But you may want to use a public WS library:
Apache Axis 2
Apache CXF
For every library there is documentation which describes how to create a project from WSDL.
You could even use Eclipse to create a project from WSDL for you: File -> New -> Other... -> Web Services -> WSDL. Make sure you have the "WST Web Services" Plugins installed.
I've never used it myself, but I just recently read about the wsdlLocation() attribute of the WebService annotation, which is supposed to map the service to a preexisting WSDL document (not sure if you're even using EJB3, though).