I need to create a system oriented around Methods where providers can register for the Methods they handle and consumers can do two things (for now) - either get Metadata for a method or execute it. I'm considering creating a REST style architecture where methods are resources with unique URIs and an interface consisting of two methods - getMetadata and Execute.
I'll need to have an equivalent of #RequestMapping so that the provider that handles specific methods can be located by the central dispatcher. As a result the provider will return either Model or Metadata object.
This looks pretty similar to Spring MVC but I don't want to expose and consume my resources(methods) over the web and use http as this will incur unnecessary overhead. Instead I want to use it like a standard java API where java methods are called and java objects are transferred.
I can do that by writing my own equivalent of #RequestMapping and Dispatcher logic but I was wondering if there's a better way to do this with Spring. Any suggestions?
Thanks!
Kostadin
You are saying you want to do using REST and everything will have a unique URI but not over HTTP?? Sounds like you are looking for RMI or something similar... Chech Burlap or Hessian both of them has excellent support from spring.
There's software out there called NetKernel that might interest you. Its literature says that it is an implementation of Resource-Oriented Computing. It looks like it rigorously separates its logical computing model from the physical details. It's RESTful, defining a resource model, a limited set of verbs, and a naming scheme. Implemented in Java. Comes with HTTP and other transports built in.
It doesn't have a Java in-process transport, but you could probably write one for it pretty easily.
Hmm...if you never need to process requests from out-of-process sources, it's probably overkill for you, but maybe it will show you some useful patterns.
Related
I have a requirement to use Jersey 2 as the Rest interface. I need to adapt this to an existing system which has used CXF to pass in SOAP requests. I know I should use CXF-RS but... it's not what the client wants.
I am auto-generating a WADL from a XML model and using that to autogenerate the resource classes (using CXF, but behind the scenes so to speak), so I really don't want to call a producer template from within the resource class.
So, I have thought that I could wrap the REST resource class in aspects that would capture the necessary information. Looking at it further I realise there are post-processing filters which would give me enough information to fire off a Camel producer template with the appropriate information taken from the resource method in question. That's where I am planning on heading.
And yet: I really want to do something a bit more stasifying and maintainable and reusable by creating a real Camel endpoint to do what I want. A consumer for now. I know this is possible. But my question is - where do I start? How do I map the Jax-RS resource classes to, say an exchange object and the parameters to headers. It seems as if it should be simple but I don't really understand the process by which one can as it were hijack the resource methods into the consumer method in a Camel component. Primarily I want to take advantage of the automatic JAXB conversion from xml to objects that it allows for.
Have a look at this example and see if that helps, basically it exposes a REST endpoint and injects producer template into a bean that calls an activemq endpoint.
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 am working on an application in Java on Google App Engine where we have a concept of RPC, but when should we ideally make use of RPC? The same functionality that I am doing with RPC could be implemented even without it. So in what scenario should ideally RPC be designed.....?
You typically use RPC (or similar) when you need to access a service that is external to the current application.
If you are simply trying to call a method that is part of this application (i.e. in this application's address space) then it is unnecessary ... and wasteful to use RPC.
... when should we ideally make use of RPC?
When you need it, and not when you don't need it.
The same functionality that I am doing with RPC could be implemented even without it.
If the same functionality can be implemented without RPC, then it sounds like you don't need it.
So in what scenario should ideally RPC be designed.....?
When it is needed (see above).
A more instructive answer would be scenarios where there are good reasons to implement different functions of a "system" in different programs running in different address spaces and (typically) on different machines. Good reasons might include such things as:
insulating one part of a system from another
implementing different parts of a system in different languages
interfacing with legacy systems
interfacing with subsystems provided by third party suppliers; e.g. databases
making use of computing resources of other machines
providing redundancy
and so on.
It sounds like you don't need RPC in your application.
RPC is used whenever you need to access data from resources on the server that are not available on the client. For example web services, databases, etc.
RPC is designed for request/response. i.e. you have a self contained request to a service and you expect a response (return value or a success/failure status)
You can use it anywhere you might use a method call except the object you are calling is not local to the current process.
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/
Currently, I only know a way of doing RPC for POJOs in Java, and is with the very complex EJB/JBoss solution.
Is there any better way of providing a similar functionality with a thiner layer (within or without a Java EE container), using RMI or something that can serialize and send full blown objects over the wire?
I'm not currently interested in HTTP/JSON serialization BTW.
EDIT: For clarification: I'm trying to replace an old EJB 2.1/JBoss 4 solution with something more easy to manage at the container level. I need to have entire control over the database(planning to use iBATIS which would allow me to use fairly complex SQL very easily), but the only things I want to keep over the wire are:
Invocation of lookup/data modification methods (automagic serialization goes here).
Transparent session control (authentication/authorization). I still have to see how to accomplish this.
Both items have to work as a whole, of course. No access should be granted to users without credentials.
Because I'm not very fond of writing webapps, I plan to build a GUI (Swing or SWT) that would only manage POJOs, do some reporting and invoke methods from the container. I want the serialization to be as easy as possible.
As is nearly always the case, Spring comes to the rescue. From the reference documentation, you will want to read Chapter 17. Remoting and web services using Spring.
There are several methods to choose from. The beauty of Spring is that all your interfaces and implementations are vanilla POJOs. The wiring into RMI or whatever is handled by Spring. You can:
Export services using RMI:
probably the simplest approach;
Use HTTP invoker: if remote access is an issue, this might be better for firewalls, etc than pure RMI; or
Use Web Services, in which case I would favour JAX-WS over JAX-RPC.
Spring has the additional benefit in that it can do the wiring for both the server and the client, easily and transparently.
Personally I would choose either (2) or (3). HTTP is network friendly. It's easy to deploy in a Web container. Jetty's long-lived connections give you the option over server push (effectively) over HTTP.
All of these methods allow complex objects to be sent across the wire but they are subtly different in this regard. You need to consider if your server and client are going to be distributed separately and whether it's an issue if you change the interface that you need to redistribute the class files. Or you can use a customized serialization solution (even XML) to avoid this. But that has issues as well.
Using a Web container will allow you to easily plug-in Spring Security, which can be a bit daunting at first just because there are so many options. Also, HttpSession can be used to provide state information between requests.
Simple RPC is exactly what RMI was built for. If you make a serializable interface, you can call methods on one app from another app.
If you only need value objects then just ensure the POJOs implement Serializable and write the objects across sockets (using ObjectOutputStream). On the receiving end read the objects using ObjectInputStream. The receiving end has to have a compatible version of the POJO (see serialVersionUID).
Hessian/Burlap 'protocol-ize this: http://hessian.caucho.com/ and http://www.caucho.com/resin-3.0/protocols/burlap.xtp
You could try XStream (http://x-stream.github.io/) over REST. Easy to apply on e pre-existing set of pojos.
Can you give some further information as to what you're trying to achieve, since you're not interested in rest/json ?