Valid reason for servlet to override HttpServlet service method - java

I have a few legacy Servlets overriding service method,
According to HttpServlet docs service method shouldn't be overridden, only in specific cases:
There's almost no reason to override the service method. service handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type (the doXXX methods listed above).
I found several answer about service method that calls the do methods
the calls to doGet(), doPost() and the other do-methods are in the HttpServlet class
It's done by default and can be overriden
Since your servlet overrides the service() method and provides a different implementation, it doesn't do that anymore. Instead, it does... what the code in the method does.
and answers that says why not overide it
let servlet handle other methods.
But I didn't any valid reason why to override this method, is there any case(s) ?
It seems that it may correspond to DRY (Don't repeat yourself) rule, so all do methods will execute same method.

You'd have to override service if you need to handle a non-standard HTTP method, i.e. one that hasn't been dispatched to a doXxx method by HttpServlet.
As the RFC 2616 HTTP documentation says:
The set of common methods for HTTP/1.1 is defined below. Although this set can be expanded, additional methods cannot be assumed to share the same semantics for separately extended clients and servers.
Your own quote even says the same, although only implicitly:
There's almost no reason to override the service method. service handles standard HTTP requests by dispatching them to the handler methods for each HTTP request type (the doXXX methods listed above).
Implicit is that non-standard requests must be handled by overriding the method.

Related

Risk of injecting an HttpServletRequest class into a Service class

I am injecting the HttpServletRequest class into a class with the #Service annotation passing the instance of the HttpServletRequest class to a utility class (AuthorizationUtils) to get the authorization header. Is there any risk in this, such as my AuthorizationUtils trying to call the method below and my service class or HttpServletRequest class already being destroyed?
request.getHeader("Authorization")
I would avoid doing that (for architectural reasons), but no, there is no risk.
What would be incorrect would be to pass the request to a separate thread (or an async method, which is executed in a separate thread). Not because the class would be "destroyed" (that doesn't exist), but because the specification says:
Each request object is valid only within the scope of a servlet’s service method. [...] Containers commonly recycle request objects in order to avoid the performance overhead of request object creation. The developer must be aware that maintaining references to request objects for which startAsync has not been called outside the scope described above is not recommended as it may have indeterminate results.
If your service is synchronous, then the service() method of the servlet hasn't returned yet when your service method is executed, so that's fine.

Apache Wink resource lifecycle

I'd like to know what the expected lifecycle behavior is for a class that responds to REST requests.
I have a class that's derived from javax.ws.rs.core.Application that identifies another class for responding to requests.
In that other class, it is annotated with #Path("foo") and methods within this class are annotated with #Path("bar"). When a request is made to foo/bar, I can see that the constructor is executed, then the PostConstruct method is properly called. After the method returns a response to the client, I can see that PreDestroy is called and then the class is squashed. On the next request, the process repeats.
Is this the correct behavior? Or is there a way that this class can remain in memory so that it doesn't need to go through the constructor and PostConstruct each time a request is made? This method relies on JAXB marshalling and various XSL transformations - I would like to cache the compiled XSLT transformation objects as well as the results of some transformations, but if the class is reinstantiated each time it is called, it makes it impossible for local caching.
This is running with Java 7, Wink, and Tomcat 7. Can someone please let me know if this is the expected behavior, or am I missing something that will just keep this class alive?
Thanks.
By JAX-RS specification, the Resources (the classes annotated with #Path) are created per request.
There are several ways to override this behavior.
The simplest way that can be used according to the JAX-RS specification, is to create a resource instance yourself (you are responsible to call the PostConstruct, not sure when and how you call to PostDestroy in this case) and return it using javax.ws.rs.core.Application.getSingletons()
Alternately, you can put #org.apache.wink.common.annotations.Scope(ScopeType.SINGLETON) annotation on your resource.
If you use Spring, Wink has a neat Spring integration module, so the Spring's lifecycle will be used. See http://incubator.apache.org/wink/1.0/html/5.5%20Spring%20Integration.html

How can I pass local variables between doGet and doPost method in Servlet?

I understand that in order to write Thread-Safe servlets one of the easiest thing is to declare all variables locally.
When my program calls doPost it creates an instance of a database lets call it db. I want to pass that instance to the doGet method but securely without having to declare db globally. Is there any way I can do that?
I would recommend that you use a class variable that references a DataSource object from which you could get new fresh connection to your database either in your doGet or doPost methods. This is a tread-safe manner.
But for a better maintainability of your code, you should read about JPA
As you probably know, doGet() and doPost() are called in different situations (when the browser or HTTP client executes a GET or POST HTTP request, respectively).
It sounds like your application has functionality in common between those two requests. My recommendation is that you abstract that shared functionality into another method (or methods) within your servlet that both doGet() and doPost() can call.
Alternatively, if all functionality is shared, you can instead implement the service() method, which the servlet container will call for all request types (instead of doGet() or doPost()).

Methods a subclass of HttpServlet override

I have read in HttpServlet documentation that
A subclass of HttpServlet must override at least one method, usually one of these:
doGet, if the servlet supports HTTP GET requests
doPost, for HTTP POST requests
doPut, for HTTP PUT requests
doDelete, for HTTP DELETE requests
init and destroy, to manage resources that are held for the life of the servlet
getServletInfo, which the servlet uses to provide information about itself
What rule that helps compiler in checking that any one of the above method is overrided in subclass?
Nothing. You (actually, the enduser) will just face a HTTP 405 Method Not Implemented error when requesting the servlet using a non-overridden HTTP method, because that's what the default implementation does.
All of those methods are protected. The compiler can't require that the subclass override "at least one of them".
It just wouldn't make sense not to, because you would have a "not implemented explosion" servlet.

using GWT RPC mechanism with my customized Servlet

I currently have a GWT application which uses the RequestBuilde to
send messages to a servlet I have (using POST and GET), and my servlet
(in doPost and doGet) "pauses" the request (this is done by using
Servlets 3.0 spec) and adds it to a queue.
Additionally I have a
Daemon thread which runs in the background and "plays" the request
when there is new data.
This works great for me apart from the fact that I'm just sending
strings for now and I'd like to utilize the RPC mechanism to send
Objects.
My question is this: If I create my myServiceImpl class which extends
RemoteServiceServlet how should I handle the doPost and doGet if at all? I need to pause my request to utilize the asynchronous support, where should this be accomplished? I though maybe to call this.getThreadLocalRequest() method in my RPC method in myServiceImpl class but I'm not sure how wise that will be. I'm not
sure I even understand how GWT handles the call from the client side
of that asynchronous interface.
Does it by any chance call the doGet for example of the servlet and
makes sure it calls the required RPC method?
I'm sorry if I made a mess of things it's just that I can't find more
detailed technical information as exactly how this RPC business works.
Appreciate any lending hand
Ittai
To understand RPC forget about POST and GET it works differently (that is from a programming perspective. Internally it does use it, but you don't see or need to understand it, unless you want to do something exotic). A good starting point is on RPC is the GWT docs: http://code.google.com/webtoolkit/tutorials/1.6/RPC.html
To give you a summary. When using RPC your servlet myServiceImpl needs to implement the methods of an interface named myService, besides extending the RemoveServiceServlet. The methods get as arguments the data you want to send to the server.
Next to the myService interface you need to create an myServiceAsync interface (both interface's should be in a client subpackage). This myServiceAsync inteface should contain the same methods as the myService interface except each method returns void and has an additional last argument AsyncCallback callback.
In you client you need to instrument GWT to generate the RPC via GWT.create (see the documentation for the details.
To use RPC, call the methods on the myServiceAsync interface in your client code and GWT takes care of sending it to the servlet. The servlet will then call the matching method with the arguments you passed on the client. This is done asynchronous. Thus the client return directly from the call.
When the server sends the result back the callback you passed myServiceAsync is used or OnError or OnSuccess is called. OnError if the method on the server side threw an error, else OnSuccess. The OnSuccess will have as argument the return value from what you returned in the method implemented by your servlet.
I think the main misunderstanding I had at the time was related to the fact that GWT RPC builds on the servlet mechanism (internally) and so trying to use that mechanism with asynchronous servlets was, at the time, impossible since GWT RPC was built on servlets 2.5 (again, at the time).

Categories

Resources