Abstract types in webservice definition (wsdl) - java

I'm using the framework xFire to publish a webservice in my web application. In this service I use abstract return types in the operations like List<GlobaleType>. The operations concrete return values are ArrayList<SpecialType>.
The concrete class SpecialType extends the abstract class GlobaleType. In the generated WSDL document only GlobaleType is given, with the additional definition, abstract="true". A generated client (with the help of apache axis) creates only an abstract class GlobaleType which can't be used for instantiation.
Has someone an idea why the wsdl contract is wrong?

If I understand you correctly, your web method signature is:
public List<GlobaleType> doSomething(args)
Then your wsdl is being generated correctly. As long as apache axis knows that the SpecialType extends hte GlobalType, then the final type can be sent across the webservice and the polymorphism will be transfered from the web service to the client.
Are you using a JAX-WS web service? Then make sure that you use the #XmlSeeAlso annotation on your base type.

Related

Change Java soap service result element name

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)

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.

Converting Complex Component Interface to Standard Web Service [Java]

I have component that has complex interface with operations accepting non-primitive data or simple POJO.
What is the best practice (ways/methodologies) to convert this component interface to be standard Web Service interface that can be consumed by java and non-java clients, so that the service consumer can generate classes without problem using WSDL.
Can be used as it's? if not, is there a way to minimal change it without affecting operations' behavior?
The component interface has operations like:
/** This is asynchronous method that needs to callback the ResultHandler
interface which has to be implemented by the component user to handle
operationOne result **/
public void operationOne(int id, ResultHandler handler);
/** I think there is no problem with the following operation for Web Services,
when using data contracts. Correct me if I’m wrong! **/
public String operationTwo(int id, MyObject obj);
The ResultHandler interface:
/** Note that this handler interface contains InputStream
and Exception as parameters for the handling methods **/
interface ResultHandler {
void onComplete(InputStream is);
void onFailure(IOException ioEx);
}
You can use your objects in the webmethods, as they are converted to complex WSDL types, but keep in mind that this can only be done to a degree. You should have simple POJO's to transmit the data structures so that you get the benefit of the WSDL/code generation not the complex types you will be using to perform your business duties. Also a peace of advice, should REST/JSON over SOAP Web Services.
UPDATE:
The only way to effectively test your web services is by creating a moke for every call you have on your web service.
Moq - How to mock web service call?
You need to make a method that can invoke the component with the provided arguments and return a complete response. For best results that method should not have side-effects.
Then add #WebService and #WebMethod annotations to it, and use Endpoint.publish(...) to create a small stand alone application publishing that web service. The JAX-WS stack in Java 6 can autogenerate the WSDL from this.
See http://java.dzone.com/articles/jax-ws-hello-world for a full tutorial for doing this.

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