Before anything else, I want you to know that I can already connect to the web service server. I'm asking this question because I want to gain a deeper knowledge on how a wsimport generated client works. Based from my research, wsimport uses JAXWS. Please note that I have no knowledge from JAXWS.
I generated my client using wsimport. The WSDL I used is from an Axis2 web service and was automatically generated by Axis2. The classes below are the results of wsimport:
Under com.datamodel.xsd
DataBeanRequest.java
DataBeanResponse.java
ObjectFactory.java
package-info.java
Under com.service
MyWebService.java
MyWebServicePortType.java
MyMethod.java
MyMethodResponse.java
ObjectFactory.java
package-info.java
With the classes above, I can that tell that com.datamodel.xsd contains the beans used by the web service server (excluding ObjectFactory and package-info). Meanwhile, MyMethod and MyMethodResponse are also beans used to set the request and response parameter of the web service method/operation.
Below are my questions: (You don't really have to answer all of it if you don't know the answers on some of my questions. :) And please feel free to share any info that you think I might find useful.)
Am I correct with
Am I correct with my assumptions above?
What are the function of the other classes?
I inspected MyWebService and it contains an annotation referring to the absolute location of the WSDL I used to generate the client. What is the relevance of specifying the wsdllocation in the client? How does the client use that info?
I noticed that the actual URL of the web service is not declared in any of the classes generated. How does the client know where it needs to connect to?
Was the WSDL file annotated so that the client can read the URL on the WSDL file upon connection? If so, then does it mean that the WSDL file is always read when a new connection must be established?
Since there's a need for me to compile my application and install it on a different server, the will become invalid. Can I set it to a relative path instead of an absolute path? How? (Answer: Yes, it can be set to a relative path. The wsimport command has a wsdllocation attribute wherein the value of the wsdllocation can be specified.)
What if I need to connect to an HTTPS. How can I set the server certificate?
Is there any difference when I generate my client using wsimport and when I generate it using Axis2 or Apache CXF.
Before I answer the questions, some clarification: JAX-WS is a specification for implementing web services in Java. It describes how WSDL artifacts can be mapped to Java classes and how this mapping can be applied using annotations. You can download the specification here. The tool wsimport is part of the reference implementation of this specification and the reference implementation is part of the Java class library. There are several alternative implementations, such as Axis2, CXF or Metro, that enhance the basic JAX-WS support with support for additional standards such as WS-ReliableMessaging or WS-Security.
Now to your questions:
Am I correct with my assumptions above?
Yes, you are.
What are the function of the other classes?
The package-info exists to map the XML namespace used in the web service to the package in which your implementation classes reside. The namespace normally looks different from a Java package name (normally, it is a URL) and this makes the mapping necessary.
The ObjectFactory allows you to create any of the messages sent and received by the service. You need this if you want to hook in code in front of your stub class, provide modified messages or similar things.
I can't see the content of your classes, but if I understand it right MyWebServicePortType is an interface that resembles the portType in your WSDL. That is, it maps the operations and their signatures in the WSDL to Java methods. If you want to provide the service (which you don't, you are asking about the client), you would need to implement this interface. As you implement the client, you simply use it.
Finally, the class MyWebService contains the client stub you need if you want to invoke the web service.
I inspected MyWebService and it contains an annotation referring to
the absolute location of the WSDL I used to generate the client. What
is the relevance of specifying the wsdllocation in the client? How
does the client use that info?
The interface you generated contains the signature of the portType of the service, but it does not explain how you can talk to the service. This is part of the binding in the WSDL. The most basic setting is a document/literal style for the messages using SOAP over HTTP. Other configurations, such as SOAP over JMS, are possible and your client needs to know what protocol to use. Therefore it needs the binding WSDL. Also, as you state later, there is no endpoint address in your Java files. This address is also read from the WSDL.
I noticed that the actual URL of the web service is not declared in
any of the classes generated. How does the client know where it needs
to connect to?
It reads the address from the port of the service in the WSDL. This is located of the end of the WSDL.
Was the WSDL file annotated so that the client can read the URL on the
WSDL file upon connection?
No, the port is a typical element of a concrete web service endpoint. There's nothing special needed here.
If so, then does it mean that the WSDL file is always read when a new
connection must be established?
Well, there could be caching at the client side (I don't know about the details of the reference implementation on this one). From a conceptual point of view: yes, it is.
What if I need to connect to an HTTPS. How can I set the server
certificate
This can be tricky, I can't give you an out-of-the-box answer. I would suggest to read through questions on this topic, such as this one.
Is there any difference when I generate my client using wsimport and
when I generate it using Axis2 or Apache CXF
Yes, there is. wsimport is better, don't use wsdl2java. Here is a description, why.
You asked: I noticed that the actual URL of the web service is not declared in any of the classes generated. How does the client know where it needs to connect to?
If the WSDL was downloaded using a browser and passed as input to wsimport, then the local wsdl file location is embedded into the generated code. That is why you don't see the actual service location in the generated code. It also means if you deleted the local copy of the wsdl file the generated code will not work (when inovked using a main method) .
If the URL of the wsdl was passed as input to wsimport then that URL is embedded in the generated code, which is further used to get the actual service location. The idea is that the WSDL locations are fixed. They are expected to be in a UDDI or as a local file. This allows the actual services to move around and if they do move, you just have to modify the local copy of the wsdl file alone or update the wsdl in the UDDI. [mostly this does not happen as service locations are never IP but DNS names]
This is why it is never a good idea to publish the wsdl in the same server where your webservice is running
Related
I'm creating a WSDL-first webservice with spring-ws in gradle.
Some examples I have been looking at
(e g https://spring.io/guides/gs/producing-web-service/ )
it seems they will only generate the java-classes from the XSD-schema,
but no java-interface (or abstract-class) from the WSDL service-operations?
Also, in the spring-ws doc, it says "... in Spring-WS, writing the WSDL by hand is not required ...".
Is it correctly understood that spring-ws will not generate any java-interface or class for the actual service itself?
Is it possible to override this default behaviour and force it to do so?
I would like to ensure the full WSDL is correctly and completely implemented...
With spring-ws you can build contract first WS, although it is not necessary to build your WSDL, because it can generate it dynamically.
For java objects, spring-ws allows you to marshall/unmarshall using jaxb2 or similar. This way, you can obtain java classes from XSD, but this code generation is made by the marshaller.
From a server point of view, you create WS Endpoints that match WSDL operations. That Endpoints are annotated and bound to a request/response java objects. Thus, spring can generate dynamically WSDL, but you can use your own WSDL.
From a client point of view, you need a WSTemplate that needs to retrieve a WSDL (static or dynamic, it doesn't mind). Using this way, WSTemplate ensure you can call all server endpoints, without implementing client stubs or generated code.
I rather prefer to use static WSDL, because dynamic generation can't ensure that your WSDL change if you upgrade Spring or so, and this could break compatibility with your clients.
However, while I am developing I use dynamic WSDL, for the shake of simplicity. Once I have the service I want, I get dynamically generated WSDL (customize if I need) and use it as static. That WSDL is full for all the endpoints.
Hope it helps!
If you want only interfaces from WSDL just use wsimport command. Its part of jdk so no extra things needed.
run the commend: wsimport -keep wsdlUrl
it will generate all the interfaces and client code (.java as well as .class)to hit the web service. just search your interface.
Let your generated URL is :http://www.host.com/testservice?WSDL
then commend will be wsimport -keep http://www.host.com/testservice?WSDL
there are much more options with wsimport commend use as you want.
http://docs.oracle.com/javase/7/docs/technotes/tools/share/wsimport.html
ws import generate all the client side code.
asn wellm as much more things try wsimport, wsgen for more details
I am currently working on a Java SOAP client that consumes the SOAP Web Services from a large ecommerce provider (Magento). On that server, I want to be able to talk to multiple instances (in this case stores). Now normally, one would get the WSDL file and generate the classes with it. However, on that server, each instance has its own WSDL file that may or may not be identical in structure. What is the strategy for me as the client. Should I generate Java classes for each WSDL file? Would that give me too many packages? Are these packages permanent or temporary for a request? Should I forego creating classes and just use the harder approach: some SOAP Client (any recommendations?) along with HttpUrlConnection?
Go through this
You need to create the object (http://magentohost/api/V2_soap?wsdl=1) once and this will have all the information required for the webservices and its structure as well.
(I am fairly new to web services, kindly excuse any incorrect terminology)
Given a WSDL URL, how does one determine what methods are available in that web service by looking at the source of the WSDL file?
Also, how does one construct a SOAP response to use with the WSDL file to post data back to the web service?
I think what you ask is how to interpret a wsdl. Following articles[1][2] may help you.
[1] http://wso2.org/library/2873
[2] http://wso2.org/library/2935
Unlike the others, I'm not going to go into details about the WSDL file and how you can read it. You will eventually learn all of that by yourself by reading books, articles, experimenting with web services etc.
What I'm going to do is recommend you a very simple to use, yet powerful tool, than must be in the toolbox of every web service developer (especially someone new to web services): SoapUI.
You create a simple project in SoapUI and point it to the WSDL file of the web service. It will discover the operations, create sample request and response messages, create mocks of the web service and much more.
You can then look at the WSDL code and with the help of what's presented inside SoapUI discover which elements are involved in each method.
Just open this url to WSDL (looks like http://host:port/ddfdgfgd?wsdl) in your browser or download it to file.
Find all WSDL sections portType (portType is similar Java interface). All WSDL port types contains operations linked to input/output messages. These messages linked with XSD elements or types (it depends SOAP encoding type).
Also you can import WSDL with Java with wsimport command line tool and implement client or server side.
I wrote a java web service on Netbeans 6.9.1 and deployed on GlassFish 3.0.1
I have a wsdl url like this "http://localhost:8080/web2/service2Service?wsdl".
How can I use this url to access this web service from another java application.
Thanks
You need to generate some Java that represents the client's view of the Web Service and then invoke that Java. Here's an article which explains some of the detail.
Generating client from WSDL in Eclipse
The general idea is that you generate some Java classes from the WSDL. Those classes act as a proxy for the service you want to call. Your java invokes methods on the proxy objects, the generated code creates the appropriate SOAP messages, sends the HTTP request, interprets the response and your code just sees a Java result.
I just use the tooling built into Eclipse, but you will also find other suitable generators, for example in Apache's Axis
1º U must save the content in a "myWebServices.wsdl" file
2º Run your Wsdl converter, all compilers have one of this, normally the name is WDSL.EXE
This process will create a new file with NameSpace or Package with the definitions of webservices built in.
3º Then imports this package or built a library.
Develop web service Client in second application.
You can use Netbeans to create web service client by giving your wsdl url
The document at this url is the actual wsdl (a description of the actual webservice, written in WebService Definfition Language).
The description includes information about the services url, the protocol(s), the method names and and data objects. Your application will use that information to call the remote methods of that service.
The protocol may or may not be SOAP, and without knowing the webservice details, it's quite impossible to recommend a toolset or methodology to use the webservice, there is no general approach. In most cases we see SOAP, for those services I recomment soapUI as a general tool to use and test SOAP based webservices and apache axis to implement java based service consumers.
I'm creating a web-service client. I used a WSDL file to generate the client side stubs.
But now I have to authenticate to the web-service, and invoke methods.
I've checked some tutorials on how this should be done, but they always explain generating the client code and server code then having them work together.
I was wondering if all the info needed to authenticate and invoke requests is contained within the WSDL file(and thus auto generated code)? Or do I have to also have knowledge of the web-service code?
Any help appreciated.
Generally speaking, a WSDL should be all you need (assuming it's been written by someone who knows what they're doing).
A well-written WSDL should have sensible method and parameter names such that the generated client bindings are more or less self-explanatory. Through the <annotation><documentation></documentation></annotation> attribute, comments should be added to resolve any ambiguities. In other words, think about a WSDL just like a JavaDoc API page. You shouldn't need to care about what's inside the black box, just so long as you know what you need to put in and what you'll get out of it.
As for authentication mechanisms there are really two cases to consider: the web service level authentication and application server level authentication.
At an application server level (e.g. Tomcat or GlassFish), the WSDL won't give you indication of the authentication method used (because the WSDL is at a level above the application server). In this case, you can try debugging by accessing the WSDL file in a browser (or maybe try invoking the service in SoapUI) and seeing what you need to be authenticated.
At a web service level the security mechanism should be described in the WSDL. I'm not aware of any IDEs that can automatically recognise the authentication mechanism described in the WSDL and then prompt you to what you need to supply (although I only really use NetBeans). However, you should be able to work it out - either by examining the WSDL or by looking at the error messages your web service client spits out when you try and access a protected resource.
A WSDL file does not contain information on the order of invoking certain functions (if any). So, in my opinion there should always be additional documentation.