I'm a Jersey / REST newbie and am trying to write a simple web service. The issue I have is the storage of data between requests.
Servlets can access sessions but I didn't believe Jersey / REST allows this.
I am currently writing this service so that an Android app will make RESTful requests to Tomcat.
Now I am not sure yet of the type of request these will be: should they be URLs with parameters, or simply an XML string? The type of data to be transmitted from the app will include addresses of RSS feeds and keywords and sundry metadata.
The XML responses from the server will again consist of RSS feed addresses, keywords, frequencies of the keywords and other metadata.
The idea at the moment is to use JAXB on both app and server to make up and break down the XML into Java objects.
JSON or GSON are not available alternatives here.
But what about storing data between requests? Is it enough to store all the relevant variables in XML if XML forms the request and response actions, where each request will have an ID number referring to the server's database.
Or is it better to use the session context for servlets via REST?
Apologies if the above sounds vague. I am a Jersey / REST newbie.
While as has been said it is generally recommended your WS calls to be stateless, Jersey does rely on Servlet, so you can inject the HttpServletRequest and get the session from there:
#GET
public String getMethod(#Context HttpServletRequest req) {
HttpSession session= req.getSession(true);
...
You can then configure your web server session storage to memory, cookie, cache, db, or whatever.
REST webservices are based on the HTTP protocol which is a stateless protocol.
In my opinion, saving state in your webservice is not a good idea.
You should use cookies to store user data.
JAX-RS services can either be singletons or per-request objects. A singleton
means that one and only one Java object services HTTP requests. Per-request means
that a Java object is created to process each incoming request and is thrown away at
the end of that request. Per-request also implies statelessness, as no service state is held
between requests.
Related
I have recently gone through rest web services(mainly spring). But I did not find much difference between rest based web service and web application.
In rest based web service, we have #RestControllerand in web application we have #Controller. The one difference from dev perspective I know is in rest that we have more
verbs like PUT, DELETE etc. but in web app we mainly use POST/GET . That is from receiver side. Even sender will just sends the http request for rest like sent in web application
Both maps the incoming url with method , mentions return format etc.
Yes there will be difference in authentication as in web application it will be form based authentication but web service it will be different like header based or something else.
So is there any major difference in protocol/sender/receiver or any perspective ?
From spring-frameworkrestcontroller-vs-controller
The key difference between a traditional Spring MVC controller and the RESTful web service controller is the way the HTTP response body is created. While the traditional MVC controller relies on the View technology, the RESTful web service controller simply returns the object and the object data is written directly to the HTTP response as JSON/XML
Rest of the things are more or less same
Web services are typically from application to application or machine to machine to exchange data it and the raw data usually is not human or browser friendly, ( encoded in json or xml or other agreed formats). The encoded data maybe later transformed or wrapped into pretty web pages as an output to view object data to be browser human-friendly for viewing.
A client connects to a JAX-RS Endpoint to retrieve data. This endpoint uses an EJB to access the database and perform logic then returns the data to the endpoint.
Client <----> Rest Endpoint <----> EJB
Before data can be returned to the Client, I need to pass data to another Endpoint instance (another Client that is connected to this Rest Endpoint). I would like to keep this a REST Service but I'm faced with two problems:
REST Endpoints are stateless. So no Sessions are linked with an endpoint. However, this could be fixed with context injection (not as efficient) or passing a userID as a parameter.
No Communication method. There's WebSockets but how would that help me communicate between Sessions on the server? There's JMS but from my understanding that works from application to application not Sessions.
What I'm asking: Is there a way to communicate between different REST (or EJB) instances/sessions? If so, how?
You would have to persist sessions to some external storage (like Redis) and pass the session identifier with each request between various system components. When such request is handled, you could load session state from the storage and proceed accordingly.
Most of the EJB/Servlet containers allow you to turn session persistence on.
I am coming from servlet/web application world and started learning web services(SOAP based). I have gone through some of the webservice
tutorials. I am trying to draw the parallel between normal http request and webservice request. Here are my observations ;-
1)Both are HTTP request. Webservice is a also post request which contains soap envelope as request body. Soap envelope
is just a normal xml which contains the data
2)java Stub internally marshal the XML , creates HTTP request and send it to consumer
3)Servlet at consumer side intercpets that request and unrmashal it to java object and send it to corresponding service.
Is my observation correct ? I know there may be other complexities but i tried to put the comparison in simple manner.
Your assumptions are generally correct. Yet, the subtelties can lead to huge differences.
Claim 1 : both are HTTP.
SOAP is generally used with an HTTP "binding". Yet it does not have to be that way. SOAP is designed to be fairly transport agnostic. It is not uncommon to have SOAP being used over JMS (although one might consider this an overuse of JMS, and an over architected protocol), it is certainly in production in many places. Rarely seen are SOAP/SMTP or SOAP/TCP without HTTP, but these exist too.
Webservice is a also post request which contains soap envelope as request body
A SOAP call over HTTP is a POST request. It may not be of content-type xml, though, as some variants such as SwA (SOAP with attachments) or XOP+MTOM variants may produce HTTP payloads that are MIME/Multipart (the first part of which is the SOAP Enveloppe in its pure XML form).
This use cas is most common when on is to send large binary content over a SOAP Call, and for which binary encoding may add a large weight to the request (base64 is a 1.3x factor in weight).
java Stub internally marshal the XML, creates HTTP request and send it to consumer
That is the usual way it is done, Axis framework and JAXWS frameworks work primarily this way.
The older SAAJ API, a standard EE API, requires you to build your SOAP Message by hand, using the DOM APIs, (see SOAPMessageFactory), and then send it.
If you look at Spring WS, you'll have something close to your claim, but where each part is fairly exposed and in your control (you may elect to build certain calls with a DOM Api, others by using JAXB marshalling, ...).
3)Servlet at consumer side intercpets that request and unrmashal it to java object and send it to corresponding service
Again, this is how things generaly work. But you can also have an implementation that works outside a servlet container. (See Endpoint Service API in JAX WS).
Your assumptions are right:-
Yes, Servlet request and Web service request both are normal HTTP request and yes, SOAP web service internally use HTTP POST.
Yes,java internally marshal the XML. Also, at client end one java web service client(may be a wrapped in servlet) un-marshal it. A SOAP message or SOAP type web service has many characteristics like:-
SOAP message mostly send data using XML format. XMLs are technology independent. So, SOAP can interact with two heterogeneous web applications built in two separate technologies and exchange data using XML.
SOAP web services send XML using HTTP protocol. Data are sent wrapped in an XML using the payload of HTTP.
SOAP web services can be secured. For an example, all the payment related transactions using credit card and bank info are done using secured SOAP web services.
A SOAP web service accepts XML in request and returns XML in response. In case of errors this return XMLs can also contain SOAP faults. SOAP faults contain the description of error and an error code.
Web services can carry attachment document also like PDF, Word etc. with its XML payload. Java provides separate API for this type of web services. There is an API available in java called SAAJ to accomplish this.
I think that you can find a very good response in this blog post by Ben Klopfer.
Mainly the difference between XML/SOAP vs HTTP/REST is that the former is most response verbose while the latter is lighter.
But this is not the only aspect you have to take into account.
REST represents the state of the resource and is a little bit easier to use and to understand, and always remember that it comes afterwards compared to SOAP.
In addition SOAP it is not limited to using HTTP/HTTPS, but can be also used with other transports like SMTP, JMS, etc.
Resuming the post reminds you:
Use SOAP when:
All you need is simple operations, like read only methods
Implementing a one-way or one-object service for something like data exchange or transfer
You want finer control over the specific transport of data, or can’t always use HTTP
Rigid specifications need to be enforced on incoming requests, and you want to minimize additional documentation needed for use
You can rely on client ability to parse XML, or more preferably SOAP itself
You need built-in error handling when things go wrong with requests
Use REST when:
Operations are complex, like create/read/update/delete on objects
Implementing a multi-faceted service for a variety of different objects
You want to easily and quickly target a variety of consumer end user devices as clients
Requests are generally stateless, like call and response compared to a conversation
Your clients may have limited bandwidth or processing power
You can leave it up to the client to get their requests correct and to deal with problems
I have a Java EE application that receives requests over http/s. The requests do not contain any cookies or jsessionid request parameters.
In the request payload I can find a string "sessionid" that should allow me to associate that request to an HttpSession. I've managed to implement a mechanism that stores a map of sessions in memory, but that's not (easily) scalable in a cluster environment.
The standard Java EE mechanism for associating requests to HttpSessions is based on cookies or URL rewriting, which are not available for me, since I don't control the 3-rd party that sends the requests. Also, the HttpServletRequest object does not have a setSession() method.
Is there a straightforward way to associate requests to HttpSessions, without relying on a particular Java EE server or on some distributed cache?
A few statements:
The 3rd party client does not conform to the HTTP spec, and that's not your problem
If you need a custom mechanism, you should implement all of it. That is, do not rely on HttpSession - make a Map<String, Object> for each sessionId and support it yourelf
Any other solution would require plugging your code into the container (for tomcat thay might be a Valve), but there is no standard solution.
I've been on that road before and it was a dead end. You really need to opt other mechanism than HttpSession
It could be as simple as a unique id for each session (which should be stored in database rather than in memory) or something more sophisticated.
Following links might help you
OAuth
HTTP basic authentication
Google's ClientLogin (although deprecated by google, its a good architecture to study)
But yes, changing the mechanism does mean that the third-party has to conform to it.
I have two web applications say App1 and App2. I want to call a servlet which is in App2 from a servlet in App1. I'm using URLConnection for this. I'm able to pass parameters to the servlet in App2 also and I'm also able to receive response from the servlet as string. But I want to send java objects from the servlet in App2 and receive them in servlet of App1. How to achieve this?
Depends.
If those webapplications runs at physically the same webserver in the same servletcontainer, then just set it as a request attribute and forward the request to the other context:
request.setAttribute("name", object);
ServletContext app2 = getServletContext().getContext("app2");
app2.getRequestDispacher("servletUrl").forward(request, response);
The other context will be able to obtain the object as follows:
Object object = request.getAttribute("name");
This only requires a server setting that the contexts are accessible by each other. How to do this depends on the servletcontainer. In Tomcat for example, you just need to set crossContext attribute of the webapp's <Context> element to true.
<Context crossContext="true">
Then it will be available to other contexts. For other servers, consult its documentation.
If those webapplications runs at physically different webserver, then there are several options:
Convert to String and send as parameter. On retrieval, convert back from String. JSON is a nice format for this. Google Gson offers possibilities to convert between fullworthy Java objects and JSON and vice versa. If you're using GET and the request URI gets pretty long, over 2KB, then consider using POST instead of GET, else the URI may be truncated by the server. Pros: better reuseable service. Cons: hard to send binary data.
See also: Converting JSON to Java.
Send a multipart/form-data HTTP POST request using URLConnection or Apache HttpComponents Client as per RFC2388 and process it on the other side using Apache Commons FileUpload. Pros: standard specification, possible to send binary data. Cons: more code.
See also: How to use URLConnection.
Serialize the Java object, write it raw to the URLConnection#getOutputStream() using ObjectOutputStream and retrieve it raw from the HttpServletRequest#getInputStream() and unserialize it using ObjectInputStream. Pros: easy. Cons: not reuseable, tight coupled.
See also: Object Streams and Lesson: Serialization.
Use Serialization
Instead of sending HTML you'll send objects streams.
Just, be aware, to add extra security, you don't want to some external source inject poisoned objects into your calls.