I have following java class and have published a wsdl for it, my question is that is there anyway to have different webservice classes and publish a single wsdl? I mean another seperate class to this one with number of methods or I have to have a webservice class as the main class of the application to keep all the webmethod methods and generate the wsdl from that?
package com.Services;
import javax.jws.WebService;
import javax.jws.WebMethod;
#WebService(name = "Hellos", targetNamespace = "http://localhost:8081/Mywebservice2/services/Hellos")
public class Hellos {
#WebMethod
public Customer[] mycustomers() {
.....
}
#WebMethod
public String Receiver(String name){
....
}
}
Exactly, that should be the way you should design your application. you should have one consolidated java file and that should be exposed. Clients should be given multiple end-points.
WSDL correspond to your service and literally each public method corresponds to a service. You can write many classes and methods but they will not be part of your wsdl if methods are private.
If you using any IDE plugin then it asks you during service creation what all public methods you want to be exposed to outer world. So in one java project you can have as many classes or methods you want. Finally when converting your project into web service you can decide which all methods can work as end point/service and then these will be part of your WSDL.
The tool wsgen since JDK 1.6 for generate de WSDL file takes only one Service Endpoint Interface or SEI.
wsgen [options] <SEI>
You can read that:
The wsgen tool generates JAX-WS portable artifacts used in JAX-WS web services. The tool reads a web service endpoint implementation class (SEI) and generates all the required artifacts for web service deployment, and invocation
And:
Note that you do not have to generate WSDL at the development time as JAXWS runtime will automatically generate a WSDL for you when you deploy your service.
In another hand, WSDL 1.1 supports having multiple services in a single WSDL file, but these services shares types. In that case, it's prefer put all in one service.
Related
From a colleague I have received a WSDL file that describes the web service he is offering, and which I am supposed to call from my code. I would now like to do two things:
1) Implement the client
2) Have a stub server that I can use for testing, until I have access to the real server.
What I tried is the following:
wsimport -clientjar foo.jar foo.wsdl
This gives me a jar file that contains the Datatype that will contain the data to be posted to the web service, and also an ObjectFactory. I guess I will have to use it as follows:
TestDataType testDataType = new TestDataType();
testDataType.setFoo("foo");
testDataType.setBar("bar");
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<TestDatatype> request = objectFactory.createTestRequest(testDatatype);
Now how do I send this request?
Also a class TestDemoService annotated with #WebServiceClient has been generated. How do I run this class?
Any advice is highly appreciated.
You've created the client. To use this client you need to set the endpoint(if not already set) and call the service using the generated api.
This site should be a good reference.
Using wsimport
I have written a wsdl file and trying to generate server side artifacts to provide the actual business logic.
but I am failed to generate server side artifacts
I am using the below command
wsimport -keep -d Employee.wsdl
Its not generating the service class with business method(Operation). It looks its generating the client artifacts instead server .
Can anybody help me to solve this?
I came across this issue. It looks like wsimport tool generates both client and service stub. The service interface class gets the name of "portType" in wsdl file:
<wsdl:portType name="XPortType">
Then in generated XPortType.java you can see web service annotation:
#WebService(name = "XPortType" ...
public interface XPortType {
You can create your service implementation class as follows:
public class XServiceImpl implements XPortType
I am having some classpath issue. I have a Web Application which is a web service. It uses JaxB and CXF. The web service has a dependecy of another JAR which is a Web Service Client. Now both the client and the service codes are generated by using wsdl2java plugin. The problem looks like this:
Parent WebService WAR
--PackageA
--ClassB
Dependency Jar
--PackageA
--ClassB
So both of them have the same package and the same class name and since these are generated by the plugin, it makes difficult to refactor one of the package so that they would not be identical.
The WebService calls the client and in client code initializes the parent classB from web service instead of the classB from web service client Jar. The only problem in this ClassB is that they have one method which takes differnet parameter, in one class B it takes, Date whereas in another classB it takes XmlGregorianCalendar. So while calling the client i am getting nosuchmethodexception.
Here is what i tried so far without luck:
1: In the Client jar i tried giving the full package and class name to initialize the ClassB
2: In the Client jar i tried wiring the classes using Spring bean and surprisingly it is still wiring the class from the webService instead of the client
3: In the web service ClassB, i tried adding the same method that takes the right parameter. This works partially but result in another exception which is not good.
Looking forward for your help. Thanks!
Solved the issue by passing extra args to wsdl2java plugin while generating classes from the wsdl as per user2880879 suggestion like this:
<extraarg>-p</extraarg>
<extraarg>http://www.example.com=mypackagename</extraarg>
I believe you are creating webservice using top down approach, means write java class first using jaxws annotations and then create wsdl using cxf maven plugin or ant, and use this wsdl to create client ?
If you are following this approach then you can provide binding file when you generate web service client code. click here to know what is binding file and how to write.
In this binding file you can specify package name you want to change for client code.
I have been doing some reading up on web services programming with Java, Eclipse, etc. and I found one particular example where the person created the web service and client by doing the following:
define the web service java class (interface + impl)
deploy the web service using Endpoint.publish
grab the wsdl from the url of the web service (eg, localhost://greeting?wsdl)
use wsimport to generate stubs
create a client class using generated stubs
Is there another way to generate the wsdl without having to publish the web service and download it? Perhaps a maven plugin to auto-generate wsdl and client stubs?
Update: Rather than creating a new question I am just going to piggyback on this one.
I have created my web service by defining an interface:
#WebService
public interface HelloWorldWs {
#WebMethod
public String sayHello(String name);
}
and an impl class:
#WebService(endpointInterface = "com.me.helloworldws.HelloWorldWs")
public class HelloWorldWsImpl implements HelloWorldWs {
#Override
#WebMethod
public String sayHello(String name) {
return "Hello World Ws, " + name;
}
}
When I run wsgen I get the following error:
The #javax.jws.WebMethod annotation cannot be used in with #javax.jws.WebService.endpointInterface element.
Eclipse seems to be okay with it.
Any idea why?
Note, I originally did not have the annotation but when I tried to call my webservice I got the following error:
com.me.helloworldws.HelloWorldWsImpl is not an interface
The JSR 224 says in 3.1 section:
An SEI is a Java interface that meets all of the following criteria:
Any of its methods MAY carry a javax.jws.WebMethod annotation (see 7.11.2).
javax.jws.WebMethod if used, MUST NOT have the exclude element set to true.
If the implementation class include the javax.jws.WebMethod, then you cant put #WebMethod(exclude=true) and that in not possible, according to specification.
Depends of custom version of Eclipse, shows a warning for this. e.g. Rational Application Developer for Websphere shows:
JSR-181, 3.1: WebMethod cannot be used with the endpointInterface
property of WebService
While programming/building a project (with some advanced IDE) normally you should be able to find it between auto-generated stuff - the IDE should generate it. Just check carefully.
When I publish a web service created from a WSDL, the WSDL which is created after publishing is different than the original one. The difference is that WSDL/XSD created after publishing had additional element(ARG0) which wraps all root elements.
Because of the reason above, I could not share original WSDL/XSD to client developers since original WSDL and the one created after publishing is not same.
I am using Java as a programming language and JAX-WS.
using API javax.xml.ws.Endpoint to publish the web service without needing any Application server.
Endpoint.publish(url,webserviceinstance)
Thanks in advance.
Since the problem is unneccesary wrapping issue, I focused on wrapping annotations. Eventually I have found out that there is a related annotation for this issue. After adding following annotation statement at the beginning of Class ,problem has been solved.
#SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.BARE)
public class WebServiceHandler implements WebService {
//....
}
From now on, I can make succesfull request created from original WSDL to deployed machine.
If you post the wsdl, a better assessment can be made. Given that you are seeing an unexpected wrapper, my guess is that jax-ws is interpreting your original wsdl differently than you intend. The page here (http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/) discusses different wsdl configurations. My suggestion is that you follow the instructions for using the document/literal/wrapped convention as it is more or less in the mainstream for soap-based services.
The resulting published wsdl will still likely be a little different in terms of service name, port name or namespace unless you use the #Webservice annotation attributes to force these to particular values, but they will be consistent such that you can provide the published wsdl to your clients and expect success.
The most common reason for this type of issue is that the class implementing the Web service doesn't have an #WebService annotation with the correct endpointInterface attribute. In fact, it is not sufficient to implement the endpoint interface generated from the WSDL.