In my experience, most distributed object technologies (RMI, CORBA, etc.) work something like this:
define a service interface
write an implementation of the interface
use a tool (rmic, IDL compiler, etc.) that generates code which enables a client to get a reference to an implementation of the interface given some endpoint (URL).
The important point is that the service interface is a shared contract that both the client and service must adhere to. I've had a look at metro, and it doesn't seem to follow this pattern.
I'm looking for alternative suggestions that do support this kind of interface-based web service development. Unfortunately, I'm required to use SOAP, so libraries that only support RESTful services are no good to me.
Ideally, I would like to follow a code-first, rather than a contract-first appeoach, i.e. I define the (Java) service interface and the WSDL is generated from that, rather than the other way around.
Solutions that support defining or implementing the service using Groovy (instead of Java) are particularly welcome.
Metro allows you to annotate a given method, put a hint or two about the endpoints in the servlet container configuration files, and then have the WSDL generated automatically on request.
This is very nice, and save you all the trouble of having to create a full WSDL for just exposing a method or two.
Metro is good (+1), but Apache CXF's Simple Frontend goes one step further: you don't have to annotate anything. It generates WSDLs, clients and servers from plain Java interfaces.
Related
In spring-ws reference documentation, they say that it uses a contract-first approach (i.e. WSDL comes first), and that spring-ws even doesn't support a contract-last approach. But then, in the first example (page 15), a Java class is created, annotated with #Endpoint, and the WSDL is generated afterwards.
So, isn't it contract-last approach?
It's always a discussion if it's first or last. But you've got to start somewhere. I don't know exactly what you are referring to, but mostly the WSDL is generated based on the XSD. You might even have used the XSD to generate Java classes based on the elements in it. Those classes can be used for your endpoint mappings.
Spring-WS stands for Spring Web Services. Spring-WS focuses on document driven Web Services i.e. Contract-first development approach. Spring-WS aims at providing the best features of Web services along with the proven features of Spring like dependency injection, powerful mappings, support to ws-security etc..Spring-WS, the service contract can usually be generated automatically. But you must create the data contract yourself
I am early on in a REST implementation and have recently learned that we could be putting our JAX-RS annotations on our Java service interfaces rather than the class implementations.
To me it seems like this could result in a clean class file, but might also result in developers have to constantly muddle between files.
What are the pros and cons of each approach?
You should put it in an interface. Rather, my practice requires me to put it into an interface, because my client and server sides are sharing the same jax-rs definition.
I am inclined to use jax-rs for REST-RPC.
The reason for REST is to allow an web service URL API to be serviceable and "clientable" by any programming framework.
The use of jax-rs restricts us to using java on the server side.
The use of jax-rs for REST-RPC restricts us to using java on both server and client sides.
What is REST-RPC?
In a not too convoluted attitude of explanation, RPC is a way of calling a function/method on the client, which when sent over the wire is serviced by the server such that the same function/method exists on the server side.
RestEasy allows you to use the jax-rs definition on the client-side to call the same function serviced on the server side.
RestyGWT, too, with some modification to the interface to specify a callback method would allow you to (somewhat) use the jax-rs definition on both client and server side. You simply have to write a script to move the return type to the type argument of the callback method.
You might question why restrict ourselves to performing java on both sides? Would that not defeat one of the purposes in life of REST? I think jax-rs REST-RPC is a convenient route to implementing and testing a jax-rs service. If you wanted to implement a jax-rs service, you probably would do it initially in Java on both sides anyway. And then when your service gets off the ground, you could start writing PHP or python clients.
Writing your jax-rs in interface files would allow you to publish your interface for client side operations. This is especially true for REST-RPC. However, you could run enunciate over your jax-rs definition to publish your web service API to non-java programmers.
I have some ongoing rambling on this subject...
http://h2g2java.blessedgeek.com/2011/11/gwt-with-jax-rs-aka-rpcrest-part-0.html.
I think I have to respectfully partially disagree with Blessed Geek here. What is mentioned is a very specific use case which requires the usage of annotations on the interface.
In my own experience, I have encountered cases where the framework either by design or by bug does not respond properly to placing annotations on the interface. For example, Apache CXF does not properly process #PUT requests with #PathParams defined in the path when you place the annotations on the interface. Don't ask me why. CXF is not alone in this; Spring Security suffers from similar limitations in placing annotations on interfaces. So this is a counterpoint to the one mentioned above.
In cases where you are free to choose where to place the annotations, I would urge you to consider what makes sense from a standpoint of intention, design, and ease of development.
As a philosophical argument, some folks say that placing annotations on interfaces is another form of contract programming- you are saying that implementations will abide by certain rules.
The other side of that coin (depending on your definition of interfaces) is that interfaces should not care about what steps their implementors take in achieving the goal defined in the method contract. For example, why place a #Transactional annotation on an interface when you might have two implementations, one of which has no idea what a "transaction" might be?
In practice, the lines blur. In the case of defining a restful endpoint, you may prefer to place the proper annotations on the interface. I think this makes sense in most cases; you probably won't have multiple implementations where the same method signature responds to different HTTP verbs. However you could come up with a situation where different implementations prefer to consume and produce different media types.
So, the big idea here is "it depends." But hopefully this is some food for thought for those who may stumble upon this question.
I had a similar question when using JAX-RS with JAX-B. My hope was to use JAX-B annotations on interfaces not classes. This doesn't work as I expected, the reason is due to the unmarshaller. To solve my issues, I ended up using classes. Here is a description of why and what I found.
I want to access an external RESTFul Web service via Java, and use an open source package that processes the returned XML or Json result and creates object(s) from this data.
I know that there are many solutions out there for this, and I'd like to get your feedback on which one I should use.
For accessing the web services, I know that I can use packages such as apache HttpClient etc. but I'm sure that there are packages that wrap this and also take care of processing the returned data (i.e. creating java objects from the result).
Thanks,
Nina
Spring is great, but this is one case where there are higher-level libraries out there that make it even easier. See for example the clients that come along with JAX-RS implementations like the Jersey client and the CXF client. Some implementations can even provide clients through dynamic proxying if you have a service interface and resource classes available. This way, you hardly have to write any code at all.
Spring Rest Template is your friend.
Spring MVC has something called "RestTemplate" which can be used exactly for this.
http://aruld.info/resttemplate-the-spring-way-of-accessing-restful-services/
http://blog.springsource.com/2009/03/27/rest-in-spring-3-resttemplate/
I recently wrote some data access methods (plain old Java) that use immutable objects for both the request objects and the resulting data objects. I like the immutable objects because they prevent a good deal of confusion from appearing in the client code which I've seen in the past when people attempt to mutate and reuse objects.
Anyway, that was months ago. Now a colleague is having trouble with some web service generation stuff (attempting to expose my methods) which expects everything everywhere to be a JavaBean.
My question is: does web service stuff generation stuff always mandate use of JavaBeans? Is there another way?
Most web service frameworks provide some way for you to supply custom serializers/deserializers for types. Sounds like that is what you need here.
If it isn't clear why that's necessary, it is because the framework needs to know how to translate your Java class into XML and vice versa. Serializing and deserializing JavaBeans (classes with get and set properties) is easy if you follow the naming strategy, but you should also be able to supply your custom type serializers for classes that do not follow the bean pattern.
There are two general approaches to Web service development: top-down and bottom-up.
In the top-down approach, a Web service is based on the Web service interface and XML types, defined in WSDL and XML Schema Definition (XSD) files. The developer first designs the implementation of the Web service by creating a WSDL file. From this skeleton Java classes can be created to which the developer can add the required code. This skeleton implementation serves as an interface with the business logic. This process is also one of the J2EE standard - JAX-RPC based API for Web services which defines standard mappings between Java classes and XML types.
In the bottom-up approach, a Web service is created based on the existing business logic in Java beans or EJBs. A WSDL file is generated to describe the resulting Web service interface. Seems like your colleague is using this approach.
I would recommend a top-down rather than a bottom approach as you would have more control on the interface definitions and naming. Also your colleague could use your existing classes through the tooling generated skeleton interface.
i have an ASP.NET web service that returning a custom entity object (Staff):
[WebMethod]
public Staff GetStaffByLoginID(string loginID){}
how would i consume this in Java?
thanks!
ASP.NET automatically generates a WSDL that contains the interface definitions for your web methods and the types they consume/return.
Apache Axis provides a tool called WSDL2Java that will generated the all of the code you need to consume the webservice. Simply point it to:
http://yoursite.com/YourWebService.asmx?WSDL
If you browse directly to the .ASMX file, you'll get a nice test harness that you can use to explore the various methods you can call.
Once Axis reads your WSDL, it will generate some proxy classes, one of them will be based on the interface of Staff.
However, I would not use this class as your actual business object, and instead would wrap access to the web service through a service layer. This service layer would use the proxy Staff class to populate your real business object.
This protects your consuming code from any interface changes that may happen to the web service in the future, keeping the actual area of code that would be modified as small as possible.
I do this for a living, interopping between Java and .NET on many platforms using SOAP.
EDIT: Why the is this downvoted? It's the only correct answer here.
Just use Standard WSDL as mentioned by flyswat if you are using traditional asmx web services.
other solutions if not using standard ASP.NET Web Services:
Use REST
http://www.infoq.com/articles/REST-INTEROP
http://www.codeproject.com/KB/XML/WSfromJava.aspx
Make sure the objects are serializable and as long as the you can cast it to a similar class on the Java side, you are good. Else, you might have to write some custom class mappers in Java.
You may be able to do this by running Java on IKVM.