Why doGet(), doPost() Methods are "protected"? - java

I'm confused about the access modifier of the doGet(), doPost() and other methods of HttpServlet class.
Why are they protected?
As per my understanding, the protected modifier of doGet() means that a client has to be in the same package (or a child - through inheritance) to access doGet(). So how will the invoking JSP or the container access it?

They're protected primarily for two reasons.
So that external classes can't just call them, like you reasoned. Technically, there are ways to get around method visibility modifiers using Java Reflection (if the Security Manager allows it or there is none), but ordinarily, a protected method can only be accessed by classes in the same package or by subclasses, which brings me to point #2.
So that subclasses or concrete implementations of HttpServlet can override them. Well, they can also be overridden if they were public, but see point #1.
Now your other question, "So how will the invoking JSP or the Container access it?"
HttpServlet implements the Servlet interface, which declares a service(ServletRequest, ServletResponse) method. This, of course, by default becomes public in HttpServlet. This is the primary entry point (for containers) to call into HttpServlet implementations.
My guess (I haven't dived into the source) is that the default implementation of HttpServlet checks the ServletRequest object passed in, which is actually an HttpServletRequest and which defines a getMethod() method that returns the HTTP method used. It then dispatches to either doGet() or doPost() depending on the HTTP request method.

Here's from the official javadoc.
Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site. 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
And also
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).
And in the docs for doGet method:
Called by the server (via the service method) to allow a servlet to handle a GET request.
So HttpServlet is designed for inheritance and the entry point is the service method. Hence doGet is protected to enforce clear API.

doGet and doPost are the basic methods in generating and sending the HttpResponse to the client (i.e usually Browser or HttpClient)
Also, The container calls the Servlet.service() method which is public. It then calls the HttpServlet.service() method which is protected and it then call doGet()/doPost() method.

Suppose I am having a class MyClass which is not a servlet, then do I want my class to have methods doGet and doPost? Well if it's not a servlet then how can it respond or capture any web based requests.
Only servlets can capture and respond to web based requets.
So it makes sense that I will be able to capture and respond to web based requests only if my class extends Servlet and and hence I will be able to use doGet, doPost and variuos other methods.

I think you are wondering about how the servlet container calls the protected method doGet and doPost.
Actually there is an interface named javax.servlet.Servlet. A class named GenericServlet implement the interface. And the HTTPServlet class extends this GenericServlet.
When there is an http request to an HTTPServlet, the container simply use the method service(...) declared in the interface. That method is public. Then in the GenericServlet, the service method called doGet and doPost. If your servlet class extends the HTTPServlet class and override the doPost method, then this method will finally get called.

Think of protected as an invitation to override a method. You are deriving a class from HttpServlet so these methods are the ones to override. They all have a default action so you can just override the methods which are of interest to your application.

Related

Life cycle of Servlet and its methods

I know that Servlets consist of the init, service and destroy methods. I also know that there are the doPost and doGet methods available. The question is how the service method relates to the doPost and doGet methods. Are they called from within the service method after the request is being identified? Is the service omitted when the do methods are implemented? I need some clarifications here.
For example in a life cycle of a Servlet that receives a single POST request, I would have guessed that the order would be:
init() is executed
when init() is finished the service() is called
service() identifies the request and calls the doPost() method
when both doPost() and service() finish the destroy() method is executed
Would that be right?
No, it isn't right.
init() and destroy() are called only once. The servlet is instantiated by the container, and its init() method is called. That usually happens at startup, or when the first request for the servlet comes in.
Then all the requests are handled by the service() method, which calls the appropriate doXxx() method based on the request type (as documented).
Then, when the application is undeployed (or the server stopped), the destroy() method is called.
The javadoc is your friend. Read it. It contains all the answers to your questions. The specifications are also freely available.
From the documentation, service is responsible for dispatching to the relevant servlet method, based on the HTTP method called (POST, GET...)
Receives standard HTTP requests from the public service method and
dispatches them to the doXXX methods defined in this class. This
method is an HTTP-specific version of the
Servlet.service(javax.servlet.ServletRequest,
javax.servlet.ServletResponse) method. There's no need to override
this method.
HTTPServlet.service
This is the basic flow,
- The servlet is initialized by calling the init () method.
The servlet calls service() method to process a client's request.
The service method invokes the doGet or doPost based on the request
type came from the client if get request came doGet is invoked if
post request doPost is invoked
The servlet is terminated by calling the destroy() method.
Finally, servlet is garbage collected by the garbage collector of the
JVM.
The service() method is the main method to perform the actual task. The servlet container (i.e. web server) calls the service() method to handle requests coming from the client( browsers) and to write the formatted response back to the client.
Each time the server receives a request for a servlet, the server spawns a new thread and calls service. The service() method checks the HTTP request type (GET, POST, PUT, DELETE, etc.) and calls doGet, doPost, doPut, doDelete, etc. methods as appropriate.
Servlet Life Cycle

what is the type of request and response object generated by container?

As it is written in the book when a request comes for a Servlet, a request and response object is generated by the container and put into the service method as an argument.
HttpServletRequest
HttpServletResponse
ServletRequest
ServletResponse
are Interface so they can't be instantiated.
So
what is the type of the object?
What information does the request and response method contains?
How does the container know it is a get or post request?
Whatever type the container chooses to instantiate, conforming to the interfaces you list.
Whatever information the interface exposes, plus whatever the implementation provides. To access non-interface functionality you must cast, of course.
... By looking at the request. Read the HTTP spec.
You should review the Java EE Tutorial - Chapter 15 Java Servlet Technology and remember that JSP(s) are compiled into Servlet(s). For web based requests,
The container's implementation of the interface.
See the ServletRequest and ServletRepsonse Javadocs.
By calling the Servlet.service(request, response), the container has the default behavior of parsing the request and calling doGet() or doPost() (or one of the other methods from Servlet).
You may need to look into ServletResponseWrapper, HttpServletResponseWrapper, ServletRequestWrapper & HttpServletRequestWrapper under package javax.servlet.http. In addition, the web container implementation may subclass those wrapper classes or implement those interfaces
And look into ServletRequest and ServletResponse interface in above api doc.
Look into service() method as explained in #Elliott Frisch's answer.

Basic on servlet

When do we implement Servlet Class and When do we implement GenricServlet class as both of them are for life cycle methods?
and my sir told me that GenericServlet class is a helper class,so if we have to use GenricServlet class then whats the need of the Servlet interface?
Do we use Servlet class also without the help of GenricServlet?
Servlet is an interface and GenericServlet is a abstract class which implements Servlet, ServletConfig & Serializable.
GenericServlet class provides default implementation for all the methods in Servlet interface except the service method. So if you extends your servlet class from GenericServlet, you can only implements the service method and override those methods that you care about. It saves some time.
And of cause you can implement Servlet class without the help of GenericServlet.
Servlet is an interface defining what a servlet should implement.
GenericServlet is a generic, protocol-independent servlet.
HttpServlet is a servlet tied specifically to the HTTP protocol.
when to use
In general, you'd extend HttpServlet to implement an application's web layer.
You can also implement Servlet if you're writing your own container or handling everything yourself.
You can extend GenericServlet to handle a different protocol,by using the features provided by the container, but you might not.

What is the difference between GenericServlet, HttpServlet and a Servlet?

I was searching for exact difference between javax.servlet.http.HttpServlet
, javax.servlet.GenericServlet and javax.Servlet unable to find it out.
"Exact Difference" means
Usage
Reason behind javax.servlet.GenericServlet existence
"Exact difference" meaning what? The API lists the exact differences.
Servlet is an interface defining what a servlet must implement.
GenericServlet is just that, a generic, protocol-independent servlet.
HttpServlet is a servlet tied specifically to the HTTP protocol.
Are you asking when you'd use any of those?
In general, you'd extend HttpServlet to implement an application's web layer.
You might implement Servlet if you're writing your own container or handling everything yourself. You might extend GenericServlet to handle a different protocol, but you might not.
javax.servlet
Servlet is a server-side web technology. As the name implies, it serves a client request and receives a response from the server. You have to implement javax.Servlet (Interface) to handle a servlet work.
javax.servlet.GenericServlet
Signature:
public abstract class GenericServlet extends java.lang.Object implements Servlet, ServletConfig, java.io.Serializable
GenericServlet defines a generic, protocol-independent servlet.
GenericServlet gives a blueprint and makes writing servlet easier.
GenericServlet provides simple versions of the life-cycle methods
init and destroy and of the methods in the ServletConfig interface.
GenericServlet implements the log method, declared in the
ServletContext interface.
To write a generic servlet, it is sufficient to override the
abstract service() method.
javax.servlet.http.HttpServlet
Signature:
public abstract class HttpServlet extends GenericServlet implements java.io.Serializable
HttpServlet defines a HTTP protocol specific servlet.
HttpServlet gives a blueprint for Http servlet and makes writing
them easier.
HttpServlet extends the GenericServlet and hence inherits the
properties GenericServlet.
javax.servlet.Servlet is interface, it defines methods for all the implementations - that's what interfaces usually do.
javax.servlet.GenericServlet is protocol independent. It is abstract, so it is not to be directly instantiated. It is usable class to extend if you some day have to write servlet for protocol other than HTTP.
javax.servlet.http.HttpServlet is abstract class to be extended if you want to communicate over HTTP protocol. Most likely you only have to care about this one.
More exact information you can find behind the links.
-> One common feature is, both these Classes are Abstract Classes.
-> GenericServlet is a super class of HttpServlet class.
-> The main difference is that, HttpServlet is a protocol dependent whereas GenericServlet is protocol independent. So GenericServlet can handle all types of protocols, but HttpServlet handle only HTTP specific protocols.
-> GenericServlet belongs to javax.servlet package. HttpServlet belongs to javax.servlet.http package
-> GenericServlet is an abstract class which extends Object and implements Servlet, ServletConfig and java.io.Serializable interfaces. HttpServlet is an abstract class which extends GenericServlet and implements java.io.Serializable interface.
-> GenericServlet supports only service() method does not contain doGet() and doPost() methods. HttpServlet support also doGet(), doPost(), doHead() methods (HTTP 1.0) plus doPut(), doOptions(), doDelete(), doTrace() methods (HTTP 1.1).
Servlet:-
The Servlets runs as a thread in a web-container instead of in a seperate OS process.
Only one object is created first time when first request comes, other request share the same object.
Servlet is platform independent.
Servlet is fast.
GenericServlet:-
General for all protocol.
Implements Servlet Interface.
Use Service method.
HttpServlet:-
Only for HTTP Protocol.
Inherit GenericServlet class.
Use doPost, doGet method instead of service method.
HttpServlet is specific to the HTTP protocol and hence it supplies methods for the HTTP verbs: doGet, doPost, etc, and a version of the generic service method that takes HTTP-specific request and response objects. It is a special type of Servlet which is actually a pretty minimal interface.
GenericServlet is the basic, protocol-neutral implementation of the Servlet interface. Often you'll find similar basic implementations of interfaces in an API; in this case GenericServlet adds a bit of functionality to the Servlet API: getServletName, getServletInfo, and pass-through methods for the servlet init parameters. HttpServlet benefits from these additions by extending GenericServlet.
Generally everyone coding against this API is using HttpServlet for implementing HTTP web services, but one can also extend or use GenericServlet for implementing server/service functionality using a custom protocol, or another extant protocol, for example, FTP.
Servlet is an interface which contains five abstract methods in order use servlet we have to provide an implementation for all these five methods, which is a headache. In order to avoid this complexity, we have GenericServlet and HttpServlet for next level.
GenericServlet is protocol independent, it means it can accept any protocol request.
GenericServlet can forward and include a request but we can not redirect the request.
Session Management with cookies and HttpSession is not possible in GenericServlet.
In GenericServlet it is not possible to define separate logic for get and post request.
HttpServlet is protocol dependent. it means, it accepts only HTTP protocol request.
HttpServlet can forward and include and redirect a request.
Session Management with cookies and HttpSession is possible in HttpServlet.
In HttpServlet it is possible to define separate logic for get and post request.
Servlet interface
Its the super interface for GenericServlet and HttpServlet. It contains 5 abstract methods and all inherited by GenericServlet and HttpServlet.
Problem
If you want to create servlet by implementing Servlet interface all the 5 abstract methods of the interface Servlet should be overridden eventhough Programmer is not interested
Usage
Only implement Servlet interface if you like to develop your own container.
GenericServlet
Its the immediate subclass of Servlet interface and super class of HttpServlet. In this class, one abstract method exist: service(). Other 4 abstract methods are implemented in this class.
Problem
All methods are concrete except service() method, So you have to implement it as a callback method.
Usage
It is protocol independent so Can be used with any protocol like FTP, SMTP, HTTP etc.
HttpServlet
Its subclass of both GenericServlet and Servlet interface. Immediate super class of HttpServlet is GenericServlet. HttpServlet does not contain any abstract method. Eventhough the HttpServlet does not contain any abstract methods, it is declared as abstract class by the Designers to not to allow the anyone to create an object directly because a Servlet object is created by the Servlet Container.
Problem
HttpServlet is protocol dependent and used specific to HTTP protocol only.
Usage
service() method need not be overridden. It can be replaced by doGet() or doPost() methods with the same parameters. Its most used method to create servlet.
hierarchy
Reference: way2java.com
-->GenericServlet can process multiple clients request from a single form. Whereas, HttpServlet can process multiple clients requesting from multiple HTML forms.
--> GenericServlet is Stateless and HttpServlet is Stateful.
All classes, interfaces, and methods present in the javax.servlet package are protocol independent (generic to all protocols).
In contrast, all classes, interfaces, and methods present in the javax.servlet.http package are protocol dependent (specific to the HTTP protocol)
http servlet is an class which is specific and allows only http protocol not allowed to other protocol like ftp smtp
generic servlet are allowed all types of protocol only one abstract method that is service method and other four method are concrete method
generic servlet is the superclass of http servlet

Can we replace the purpose of init method to the servlet constructor?

Can we replace the pupose of init method to the servlet constructor?
My question is why does servlet need a separate method int(ServletConfig config) for the pupose of initialization we could have achieve the same thing by having a parameterised constructor let XServlet(ServletConfig config) and the container can invoke the same .
Probably because you cannot specify the parameter signature for constructors in an interface.
It is generally considered a bad practice to perform logic in constructor (it should only initialize the field and create object in consistent state). It also makes testing harder.
Also it is much harder to perform injection - when using init the container can create a servlet, inject dependencies and run init. With constructor you would expect to have all the dependencies already set. Wicket works around this problem by injecting Spring beans into page class from superclass constructor - because superclass constructor runs first. However modifying subclass fields from superclass constructor seems wrong.
That being said using separate init method some things simpler and easier to maintain. Also note that EJB promotes #PostConstruct annotation as well.
I guess this choice was made to simplify the coding of servlets. In the current situation, a servlet having no need for specific initialization can be coded like this:
public class MyServlet extends HttpServlet {
// doGet, doPost, etc.
}
If the servlet was initialized using the constructor, it would need to be coded like this:
public class MyServlet extends HttpServlet {
public MyServlet(ServletConfig config) {
super(config);
}
// doGet, doPost, etc.
}
BTW, they even introduced a no-arg init method that can be used to avoid being forced to call super.init(config).
Short answer: NO.
Long answer:
If a servlet contains a constructor and a init method, you will see the constructor is called first, and then the init method (try it out with sysout statements).
A servlet is a java class, so it must follow the java process, so constructor is called first and then the init method (note that the init method is called by your servlet container like tomcat because that's how servlet's are supposed to be initialized; read the servlet specification).
So, if you need to do some operation that is specific to your business need (say create an DB connection or read a set of user details etc); constructors are not the best place to put these things in.
Usually constructors should never have any complex logic/business processing. They should initialize bare minimum member variables and leave the complex things to later; in case of servlets the heavy lifting can be done by init method.
Also note that by the time the init() is called the servlet container is up and ready with it's system resources, i.e it would have initialized the JNDi name bindings, data sources so on and so forth.
So in a way it guarantees you that when you call the init(), it will have the system resources ready for you to work on.
The servlet 3 spec says this:
2.3.1 Loading and Instantiation The servlet container is responsible
for loading and instantiating servlets. The loading and instantiation
can occur when the container is started, or delayed until the
container determines the servlet is needed to service a request. When
the servlet engine is started, needed servlet classes must be located
by the servlet container. The servlet container loads the servlet
class using normal Java class loading facilities. The loading may be
from a local file system, a remote file system, or other network
services. After loading the Servlet class, the container instantiates
it for use.
2.3.2 Initialization After the servlet object is instantiated, the
container must initialize the servlet before it can handle requests
from clients. Initialization is provided so that a servlet can read
persistent configuration data, initialize costly resources (such as
JDBC APIbased connections), and perform other one-time activities. The
container initializes the servlet instance by calling the init method
of the Servlet interface with a unique (per servlet declaration)
object implementing the ServletConfig interface. This configuration
object allows the servlet to access name-value initialization
parameters from the Web application’s configuration information. The
configuration object also gives the servlet access to an object
(implementing the ServletContext interface) that describes the
servlet’s runtime environment. See Chapter 4, Servlet Context for more
information about the ServletContext interface.
Read this part:
The servlet container loads the servlet class using normal Java class loading facilities.
so, the container will have to use standard java class loading mechanism. Which means it can not do what Duncan have just suggested.
int(ServletConfig config) is a life cycle method of Servlet.and it is being called by servlet container.
We can replace the init method code in parameter constructor of super class servlet.
but we can't force the developer to call super class constructor
for example
/*If generic servlet has a constructor like this*/
public GenericServlet(ServletConfig config){
....
}
/*And Developers servlet is calling only default servlet.*/
public MyServlet(){
super();
}
So in this scenario initialization never happens for that servlet. it cause issues problem. because ServletConfig obj is not initialized.
And we cant force the user to call specifict super class constructor.
The simple answer is that you have to have a no-arg ctor and an init method because that is what the spec requires...
Why the spec is written like that is probably a matter of history. These days I think that we might defer construction until the ServletContext is available and call a ctor with that argument. But looking back there was a ServletContext.getServlet(name) method, so that one servlet could look up another on initialisation and communicate with it. For this to work they would all have had to be created up-front and then init'd.
getServlet was deprecated and now returns null (I think it was a security hole for containers that were running multiple apps).

Categories

Resources