Change Java soap service result element name - java

I'm trying to write simple java soap web service ,for that purpose download eclipse and create dynamic web application,in that project create this class and method:
package test;
public class Sayam{
public String helloworld(){
return "Hello world!";
}
}
on that class right click and choose web service and generate web service,every thing is ok and web service return this result:
<soapenv:Envelope>
<soapnv:Body>
<helloWorldResponse>
<helloWorldReturn>Hello World!</helloWorldReturn>
</helloWorldResponse>
</soapenv:Envelope>
</soapnv:Body>
i want change this line:
<helloWorldReturn>Hello World!</helloWorldReturn>
to my custome element:
<QueryResult>Hello World!</QueryResult>

You should not be aware of final contract's names, it's no matter. Any client should use any "wsdl to code" (codegen) tool.
You and your service clients should not treat directly with the XML layer (of the most general SOAP protocol).
If you are the webservice owner, you can define it as "code first" (you define your classes and methods and the platform update the WSDL definition for you).
If you aren't the owner, you should demand the contract (the WSDL) and use any codegen (wsimport is a typical one).
If you are trying to define a webservice for certain XML format and you have the XSD definition or whatelse, do not try to create a SOAP service, instead, treat that layer (the XML data) directly (using the proper tools of course like the standard specification for Java JAXB).
If anyway, you want to change that word, you have some options:
write the WSDL yourself (manually or using some tool) and then, create the webservice (eg. using wsimport).
search if you platform is able to do this (jaxws is not without hacking)

Related

wsdl file location path setup in java

I'm using wsdl files to generate client & is working fine on my local server since the generated files have path like "C:\path\to\wsdl\Air.wsdl"
I'm trying to replace all the paths as above to the one that work on live server I've found some hints but I'm not so sure how to implement it (I'm new to web services).
Below is how my files currently look like
#WebServiceClient(name = "AirService",
wsdlLocation = "file:/C:/Eclipse WorkSpace/TravelPortCXF/WebContent/wsdl/air_v33_0/Air.wsdl",
targetNamespace = "http://www.travelport.com/service/air_v33_0")
static {
URL url = null;
try {
url = new URL("file:/C:/Eclipse WorkSpace/TravelPortCXF/WebContent/wsdl/air_v33_0/Air.wsdl");
} catch (MalformedURLException e) {
java.util.logging.Logger.getLogger(AirService.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "file:/C:/Eclipse WorkSpace/TravelPortCXF/WebContent/wsdl/air_v33_0/Air.wsdl");
}
WSDL_LOCATION = url;
}
This seems to be like it should be changed (I'm not sure about that, found it on googling)
#WebServiceClient(name = "AirService",
wsdlLocation = "classpath:wsdl/air_v33_0/Air.wsdl",
targetNamespace = "http://www.travelport.com/service/air_v33_0")
static {
URL url = AirService.class.getClassLoader().getResource("wsdl/air_v33_0/Air.wsdl");
if (url == null) {
java.util.logging.Logger.getLogger(AirService.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "classpath:wsdl/air_v33_0/Air.wsdl");
}
WSDL_LOCATION = url;
}
But I actually don't understand how that method works.. Can someone please make me understand how can I change the path and where to place the wsdl files in the project so that it works properly on the live server and also the difference between both the codes.
Also I don't want to generate every-time when build is created, I want to generate the files (that are already been generated), place the wsdl somewhere in the project folder from where it can be accessed and then change the path in the Java files (by replacing all the paths at once) as in the above codes.
Few intro points for you:
Wsdl file contains description webmethods callable on the server (in general method names, their input parameters and its types and types of results of this methods). Therefore wsdl file is like contract between client and server - client knows what methods to call on the server, what parameters it will need to send with method name, and what type of result it can expect.
You can download and store wsdl file from server, and then use it for generation of special client class(es) (called stubs). This classes have java methods 1 to 1 corresponding to web service methods described in wsdl file. Source code of these classes is generated automatically by special tool (wsimport) which reads content of wsdl file and generate corresponding methods. From your perspective as developer of client, it is then very simple - you need only in some way create instance of this class (giving it url of wsdl file on the server) and call it's method like you call any other Java class method. (Generated implementation code of this methods cares for serialization of inputs and sending of webservice request to server, and then deserialization of response back to you, so you will obtain normal Java object as a result of call).
Maybe you now ask, why you need to set url to server's wsdl file before call of webservice method. Answer is that client code before calling your webservice automatically download's wsdl from the server and check's if it does not change meantime (if yes it does not call webservice and throws error). It sometimes happen that developer of server changed e.g. parameters of webservice method and you as client developer have still old version of wsdl, therefore validation aspect of this technology saves you a lot of time.
Now real examples:
Look at JAX-WS deployment best practice: WSDL location and client generation question to see client code how webservice method (hello) is called using HelloWorldPOCImpl stub class.
For server side implementation you need only two annotation #Webservice and #WebMethod, please look at chapter 3.1 to see example: https://metro.java.net/getting-started/building-a-simple-metro-application.html
For server, you dont need to create wsdl file manually, server generates wsdl file automatically - based on your code and mentioned annotations.

What is WSDL equivalent in restful WS . If nothing,how consumer generates required client side classes?

Say ,i have producer in java and consumer in dot net. Producer has a method that takes
Employee as method parameter and creates employee in db.
For SOAP based ws, dot net client will hit WSDL and creates the stubs (including employee data representation in dot net). Now it can fill
the object and send to producer.
I am not sure how it will work in restful webservices as there is no WSDL. How rest consumer will get to know what are the operations
exposed by producer without any WSDL contract and how dot net consumer will get stubs (like employee data object) so that it can simply fill it and send across?
I know there is WADL(parallel to WSDL) in rest but looks like its not very prominent and not a standard as of now.
I am not getting how client side code will generate EmployeeData class so that it can fill it and send to producer? Will client manually create extra class (instead of proxy EmployeeData that used to be generated on the basis of WSDL using utilities available at client side)? Even if client has to do it manually, how client will know what is the class definition of EmployeeData class without wsdl or wadl?
One important concept of REST is HATEOAS or Hypermedia as the Engine of Application State. What this means is that your client interacts with the REST service through hypermedia links that the service hands it.
Your REST web service has an entry point, say http://yourhost.com/rest. Your client will start by sending the request to that URL. Your service will respond with a resource that describes some or all the accessible resources and how to access them. You keep discovering and following links. This is how the API is published (and discovered).
Here's an awesome video describing this concept: Hypermedia APIs.
Through HATEOAS you can make your service API completely discoverable by just following hypermedia links.
There is no concept of top down/bottom up design in REST.
REST is about resources, not about method calls, which is basically what a WSDL describes.
Even if client has to do it manually, how client will know what is
the class definition of EmployeeData class without wsdl or wadl?
It won't need to create an EmployeeData class. Say you needed to create a new Employee, you would send a GET request to /employees which would possibly return a response containing how to do that. That might be an XHTML response like so (among other things)
<form class="new-employee" action="/context/employees" method="PUT" >
<input type="text" name="employee_name" />
<input type="text" name="employee_age" />
<input type="submit" name="submit" />
</form>
The response contains the exact format you need to follow to create a new employee. You need to submit the form to /context/employees with an HTTP PUT request containing those form parameters. This is HATEOAS. The hypermedia link is the /context/employees. The engine is following this link with a PUT request. The application state is that after this request, a new employee will exist.
Assuming that you're using the Json based WS - there is some tools that helps:
there are json parsers that can turn json, or json schema files into POJO classes, and put some annotations used by Json parsing libraries - take a look here: http://www.jsonschema2pojo.org/
I don't know any automated tool that can generate server stub in terms of all API calls etc. but there is a nice library to consume it - https://github.com/square/retrofit - you have to still put patches and methods signatures into interfase, but it's a way more convinient that playing with "pure" java.
There are also some quite nice tools helping to generate and format documentation for WS - one I like most is swagger: https://helloreverb.com/developers/swagger
There is no (or at least I don't know about it) tool that allow to generate stub, data classes etc. as it can ve usually done with WSDL file.

Generating a web service server implementation using wsdl2java in CXF

Background :
I have prior experience working on consuming Apache CXF web services but I am a bit new to generating a service endpoint interface (SEI) and a service implementation using the wsdl2java tool that comes along with the Apache CXF distribution.
The task :
I am currently working on the implementation of a SOAP based web-service that will be consumed by external systems. I have already defined the messages (XSD) and the WSDL file. I have tried generating the SEI by using the wsdl2java tool from Apache CXF. The SEI gets generated correctly with the JAXB types as the input parameters and return types to the web service methods.
When I take a look at the code generated for the service implementation class, I see that it extends the javax.xml.ws.Service class. Also, a lot of overloaded methods are generated which have the same name as the methods in the service endpoint interface with "Soap12Http" appended to the method name. A few of these methods take the parameter of type WebServiceFeature... features whereas the others don't take any parameters. Example :
public class Query extends Service {
#WebEndpoint(name = "product_query-soap12-http")
public IQuery getProductsSoap12Http(WebServiceFeature... features) {
return super.getPort(getProductsSoap12Http, IQuery.class,features);
}
}
*where IQuery is the service endpoint interface
The problem :
I was expecting the service implementation class to implement the service endpoint interface instead of extending javax.xml.ws.Service. Is this a valid expectation?
I was expecting the service implementation class to implement the methods from the service endpoint interface. Is this a valid expectation?
I would also like to know if the wsdl2java command can be asked to generate a jar for the JAXB POJOS instead of generating them as class files.
For 1 and 2, the answer is no. The generated XXXXService class is pretty much a factory for proxies of the various SEI's in the WSDL. Each endpoint/binding/portType combination in the wsdl should result in a series of "getXYZPort(...)" calls on the Service object to return an instance of that specific SEI.
For 3, a -clientjar option was added to cxf's tools last week (not released yet, would need the latest snapshots) that may be close to what is needed.

dynamic proxy soap web service client in java?

Is there any way to use soap-rpc web services such that the client is generated via a shared interface? Restful web services do it this way, but what about soap based? Do you always have to use a tool like Axis or CXF to generate your stubs and proxies, or is there something out there that will set it up dynamically?
Thanks.
EDIT #1:
To clarify, I'm looking to do something like this:
Common interface:
#WebService
public interface MyWebService {
#WebMethod
String helloWorld();
}
This common interface can already be used to create the server side component. My question is: can this type of common interface be used on the client side to generate dynamic proxies? Restful web services do it this way (Restlets & CXF) and it seems the .Net world has this type of functionality too.
I would see this tutorial of JAX-WS useful for your purposes:
In the example code the Web Services Client is configured by adding an annotation #WebServiceRef with a property pointing to the WSDL location to the client implementation class and no tools are needed to access the stuff from the Web Service that is referenced.
Was this the way you would like to have it, or did this even answer to right question?
Not exactly sure what you're looking for, but if you don't want to rely on JAX-WS/JAXB-generated artifacts (service interfaces and binding objects), you can make use of the Service and Dispatch APIs. For example:
QName serviceName = new QName(...);
Service service = Service.create(serviceName);
QName portName = new QName(...);
String endpointAddress = "...";
service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);
SOAPMessage request = ...;
SOAPMessage response = dispatch.invoke(request);
Check Apache CXF. Configuring a Spring Client (Option 1).
When you want to call a webservice, you must have knowledge of methods implemented on it. For that, We need to make stubs OR we can read it from WSDL.
I have created a WS client, using AXIS2 libraries, which is without stubs. The thing is, for each diff. WS we need to create response handles.
You can call any WS method using SOAP envelops and handle the response.
//common interface for response handlers...
//implement this for diff. web service/methods
public interface WSRespHandler{
public Object getMeResp(Object respData);
}
//pass particular handler to client when you call some WS
public class WebServiceClient {
public Object getResp(WSRespHandler respHandler) {
...
return repHandler.getMeResp(xmlData);
}
}
Please check the link below, which shows the example interface for WS client.
http://javalibs.blogspot.com/2010/05/axis2-web-service-client-without.html
For every diff. WS method we can have diff. implementation for WSRespHandler interface, which will help parsing the response.
Not knowing java so well, but being forced to learn some to accomplish a task that I was given, I needed to consume a .Net service that I have already written, I had to do a little research.
I found that 99% of the examples/samples/problems with invoking a method call against a .Net service, or any service for that matter involved using J2EE (ServiceManager) or build classes and a proxy that reflect the service being invoked. Unfortunately for me, none of this would work. I was working "in a box". I could not add new classes, could not WSDL references, did not have J2EE, but DID have access to the standard java libs.
I am used to doing this sort of thing in pretty much every other language but java, but now there was no choice, and java it was.
A lot of digging and figuring out all new terminology, methods, classes, etc, I knew I was getting close, but was having issues with some small items to complete the task.
Then I came across this post: http://www.ibm.com/developerworks/xml/library/x-jaxmsoap/
As long as you have some sort of idea of what you need to send the soap service in term of the soap envelope, the above link will give you the information you need to be able to invoke a service without the classes, wsdl class generators and J2EE, apache or other dependencies.
In an hour from the time I read the mentioned article, I had a class working and about 10 minutes later, converted the code to the "in the box" solution.
Hope this helps
Apache Tuscany might help you, although it may be heavier than you want
http://tuscany.apache.org/

Axis2 Web Service Client Generation - Types without modifying the client

Is it possible with Axis2 and Eclipse to generate a Web Service client and have it use java types that you already have in packages instead of creating it's own types. Reason being of course if I have type A already created and it creates it's own Type A I can't just assign variable of type A to variable of type B.
The wsdl is being generated from a Web Service deployed to an application server.
If it's not possible to generate it from that would it be possible to generate a client from the already existing java files.
If you really want to reuse existing classes, you can call the Axis2 API directly without generating a client using wsdl2java. Below is some relatively simple code to call a web service. You just need to fill in the web service endpoint, method QName, expected return Class(es), and arguments to the service. You could reuse your existing classes as the return values or arguments.
If your web service is pretty complicated then you may find that you have to go deeper into the API to get this approach to work.
serviceClient = new RPCServiceClient();
Options options = serviceClient.getOptions();
EndpointReference targetEPR = new EndpointReference("http://myservice");
options.setTo(targetEPR);
QName methodName = new QName("ns","methodName");
Class<?>[] returnTypes = new Class[] { String.class };
Object[] args = new Object[] { "parameter" };
Object[] response = serviceClient.invokeBlocking(methodName, args,
returnTypes);
You are generating the web service client from wsdl, correct?
The only thing that the wsdl2java tool knows about is the information in the wsdl, so it won't know about any types that you have already created.
If you can get the type information into the wsdl you may get it to work, although I have never tried.
If you want an easy way to copy from Type A to Type B then you could try BeanUtils.copyProperties, as long as the setters and getters of Type A and Type B match.
pretty much most java webservices projects go through this. I don't know if the .NET/C# world have a more elegant solution.
It makes sense, as Mike mentioned, to use BeanUtils.copyProperties.
BR,
~A
If you use eclipse as your ide, that is waht you need: http://www.eclipse.org/webtools/. It does beyond other things exactly what you want.
You can directly use ServiceClient class to call web service, which provides call using XML only and returns XML response. For different methods of web service, you have to convert the XML response to some java POJO to use it. Only Response handling needs to be done at your end. that you can do like from XML to Map etc...
So you won't need any other stub classes to call any web service, only needs to handle response XML. You can convert XML to POJO using Castor or JAXB libs.
This is the way you don't need to modify your client every time for diff. web services. You can develop like providing a response handler to client externally. So that for every different web service you will have diff. response handler class which is implementation of you interface.
//common interface for response handlers...
//implement this for diff. web service/methods
public interface WSRespHandler{
public Object getMeResp(Object respData);
}
//pass particular handler to client when you call some WS
public class WebServiceClient {
public Object getResp(WSRespHandler respHandler) {
..
return repHandler.getMeResp(xmlData);
}
}
reference:
http://www.developer.com/java/web/article.php/3863416/Using-Axis2-and-Java-for-Asynchronous-Web-Service-Invocation-on-the-Client-Side.htm
http://www.devdaily.com/blog/post/java/java-web-service-client-read-array-list/
thanks.
www.techlads.com
In case this post is still of any use to someone I read the axis2 generating clients guide: http://axis.apache.org/axis2/java/core/docs/userguide-creatingclients.html.
It seems that the Axis2 Eclipse plugin is configured to call ADB code generation in integrated mode (see http://axis.apache.org/axis2/java/core/docs/adb/adb-howto.html), thus creating inner classes in the Web service stub. I don't know if changing the generation mode to expanded mode (generate data classes out of the stub class) is possible, but you can do it command line using Wsdl2Java:
%AXIS2_HOME%\bin\WSDL2Java -uri <wsdl file path> -p <package name> -u
The -u option tells the ADB code generator to create data classes as separate classes and not inner classes in the stub.

Categories

Resources