This question already has answers here:
How doGet() or doPost method invokes service() method internally
(3 answers)
Closed 6 years ago.
How does the servlet container know whether to call doGet or doPost method.
When I make a get request doGet is called, When I make a post request doPost is called , but where is the logic to decide this .
You never really call doGet() or doPost() (the service() method will, and it is called by the Web container as you read in the lifecycle).
The service() method detects the HTTP method used and delegates to doGet(), doPost() and other methods which process HTTP requests in a HTTPServlet. It also encapsulates the ServletRequest and ServletResponse objects in HttpServletRequest and HttpServletResponse objects which contain additional context data from the HTTP headers.
Tahnks to #helderdarocha.
For more;
The logic is in the HTTP protocol and its management by the servlet container (Tomcat, Glassfish, Jetty, ...)
The first word of the request (at the TCP level) is the HTTP verb, generally GET or POST but it can be DELETE, PUT, OPTIONS, HEAD, TRACE,...
The servlet container call the service method of the servlet, but the default implementation of HttpServlet.service method contains the logic to dispatch to the proper method. Extract from the Javadoc :
public void service(ServletRequest req,
ServletResponse res)
throws ServletException,
java.io.IOException
Dispatches client requests to the protected service method. There's no need to override this method.
protected void service(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException,
java.io.IOException
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.
javax.servlet.http.HttpServlet.service(HttpServletRequest req, HttpServletResponse resp) contains the logic for that.
Request Method is a standard HTTP/1.1 token, which is sent as part of request headers
Please refer to:-
http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html
Related
How does the Tomcat container calls service(ServletRequest req, ServletResponse res) method?
Where can I look for implementation of this call?
How can I see how this req and res objects (that passed to service() method) are created?
Although the Tomcat Architecture page is in TODO status, there is at least a link to the UML sequence diagram of the request processing. Combining with Tomcat's source code, it is a good starting point.
If you want to know it, first clone apache tomcat source code
git clone https://github.com/apache/tomcat.git
Then inside the cloned repository, launch this command to search where it is invoked service method:
grep -H -n -r "\.service(" --include=*.java
You will find a short file list:
java/javax/servlet/jsp/PageContext.java:107: * in this PageContext until the return from the current Servlet.service()
java/org/apache/catalina/connector/Request.java:3128: // that set towards the start of CoyoyeAdapter.service()
java/org/apache/catalina/core/ApplicationFilterChain.java:231: servlet.service(request, response);
java/org/apache/catalina/servlets/DefaultServlet.java:411: super.service(req, resp);
java/org/apache/catalina/servlets/WebdavServlet.java:349: super.service(req, resp);
java/org/apache/coyote/ajp/AjpProcessor.java:403: getAdapter().service(request, response);
java/org/apache/coyote/AsyncStateMachine.java:41: * been called during a single Servlet.service() method. The
java/org/apache/coyote/AsyncStateMachine.java:58: * been called during a single Servlet.service() method. The
java/org/apache/coyote/http11/Http11Processor.java:498: getAdapter().service(request, response);
java/org/apache/coyote/http2/StreamProcessor.java:257: adapter.service(request, response);
java/org/apache/jasper/Constants.java:41: * HttpJspBase.service(). This is where most of the code generated
java/org/apache/jasper/servlet/JspServlet.java:385: wrapper.service(request, response, precompile);
java/org/apache/jasper/servlet/JspServletWrapper.java:440: servlet.service(request, response);
java/org/apache/jasper/servlet/JspServletWrapper.java:443: servlet.service(request, response);
The most intresting one is java/org/apache/catalina/core/ApplicationFilterChain.java. You wil find more coincidences, but much of them are because there is another interface into Tomcat source code that has a very similar method java/org/apache/coyote/Adapter.java ignore it.
Once you get java/org/apache/catalina/core/ApplicationFilterChain.java, you can edit, got to line 231 and see where the service method is called.
However, both req and res objects are not created in that place. Finding how those are created seems to be a bit more complex and requires more time.
Servlet lifecycle is controlled by the underlying container. Once the servlet has been initialized and there is a request, Tomcat will call the servlet's service method to process the request.
Service method will delegate request to your Servlet class where you can get access to req and res objects in doGet or doPost methods.
public void doGet(HttpServletRequest req, HttpServletResponse res){
}
Update :
1. Upon request from the client, Container creates two objects : HttpServletRequest and HttpServletResponse.
2. Based on the request, Container will find correct Servlet (as per URL mapping), creates new thread for that particular request(one-to-one mapping - new thread for each request) and calls Servlet's service method, passing in created HttpServletRequest and HttpServletResponse objects as arguments.
3. Based on request method (GET or POST) service() method will call doGet() or doPost() method in Servlet, again passing the same HttpServletRequest and HttpServletResponse objects as arguments.
Those are Servlet specifications in a nutshell. How does Tomcat act exactly is implementation specific, it is not controlled by specification. If you need to know how exactly it is implemented in Tomcat, you might check it's source code.
This question already has answers here:
HttpServletResponse sendRedirect permanent
(2 answers)
Closed 7 years ago.
I am making a servlet for attendance. So in the doGet() method all the front end is displayed and if any error is generated ; i.e., something is left blank then the doPost() method should call the doGet() again for completing the blank spaces.
How can I call doGet() method from the same servlet's doPost()?
If I take your question literally (i.e. invoke doGet() from doPost()), you can just invoke the doGet() method... it's a standard method like any other.
Here's a tip: When the doPost() and doGet() methods share a common set of logic, it's a good practice to isolate that logic into a separate (private) method that is to be invoked by all relevant do***() methods. For example:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// GET-based logic
processCommonLogic();
// Other GET-based logic
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// POST-based logic
processCommonLogic();
// Other POST-based logic
}
private void processCommonLogic() /* throws ServletException and/or IOException if needed */ {
// Common logic
}
You can use this pattern to create a processError() method that can be invoked wherever you need it.
However, if the scope your question goes beyond invoking doGet() from doPost(), I suggest you have a look at the references pointed by Alain O'Dea.
You can do that, it's a simple
this.doGet(req, resp);
return;
However, it's not a best practice. Generally better to implement view logic as a JSP, and dispatch to it from the post logic...
this. getServletConfig().getRequestDispatcher("my_view.jsp")
.forward(req,resp);;
return;
Or use include(), or an MVC framework like Struts...
I'm new to Java server-side programming, my question is basically to get to a starting point using Servlets (low level without using spring mvc etc.) and then build my way up from there, coming from node.js background where a route definition would start with a function (app.get(request, response) {}, app.post(request, response) {} etc.), and the function would receive request and response in parameters for one of http methods (GET, POST, PUT, DELETE).
If someone can please help on the starting point of how do I define methods against a route (let's say /users) inside a servlet class that'd map to http methods while providing request and response in it's parameters.
My attempt
public class FirstServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException , IOException {
}
I believe what you want are Servlet mappings. You can also find a bit more info here
But basically this is the way you tell the webserver (e.g. Tomcat) what servlet to use to answer requests sent to a given url pattern. Thus you map the pattern with the servlet you want to use to serve it.
You can also find more info on the inner workings here.
Edit: If you want to handle all verbs you can use a service. From the first link:
You may have seen other servlet examples implement the doPost() and/or doGet() methods. These methods reply only to POST or GET requests; if you want to handle all request types from a single method, your servlet can simply implement the service() method. (However, if you choose to implement the service() method, you cannot implement the doPost() or doGet() methods, unless you call super.service() at the beginning of the service() method.) The HTTP servlet specification describes other methods used to handle other request types, but all of these methods are collectively referred to as service methods.
All the service methods take the same parameter arguments. An
HttpServletRequest provides information about the request, and your
servlet uses an HttpServletResponse to reply to the HTTP client. The
service method looks like the following:
public void service(HttpServletRequest req,
HttpServletResponse res) throws IOException { ... }
I have a servlet that is called from a link on another page. The link actually references the servlet which then SHOULD write xml to the screen (outputting RSS XML information). Right now the link properly references and loads the servlet but because I have the code in the doPost method with nothing actually calling the doPost method nothing happens. (I'm new to Java EE) So how do I make that code execute without actually have a form that references the servlet through the "action =.." tag?
Can I call an init or main method that always executes on page refresh/load?
You can implement that logic in your doGet method. It has the same method signature as your doPost method.
Please see this thread
doGet and doPost in Servlets
For the difference between get vs post please see this article.
http://stevenclark.com.au/2008/01/12/get-vs-post-for-the-beginner/
You can also override Servlet.service method which is entry point for serving requests. This way you will handle both POST and GET requests.
Alternatively, you can implement logic in doGet method and invoke doGet from doPost:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// do request processing
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doGet(request, response);
}
I have few questions.
Can i have a Servlet without these two methods?
Can i call my form directly to Service method... Like
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FormServlet extends HttpServlet {
protected void doService (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
No, it's not mandatory. Since HttpServlet is an abstract class, there are abstract implementations of all doXXX methods, and you don't have to implement them if you don't want to.
Yes, you can have a servlet without either of these methods (they have no implementation). Still having a HttpServlet without having doGet/doPost seems a bit pointless, since servlet can only communicate with the a limited number of request methods such as GET, POST, DELETE, PUT (for more see specification section 5.1.1 ).
HttpServlet don't have doService methods. If you meant void service() then I advise you not to mess with it unless you really know what you're doing.
If all you need is to use doService call it from doGet, doPost (as someone already suggested).
Ok, examples:
public class DoesNothingServlet extends HttpServlet {} //does what the name implies
public class FormServlet extends HttpServlet { //what you want to do
protected doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doService(request,response)
}
protected void doService (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Do something
}
}
Read http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.6/api/javax/servlet/http/HttpServlet.html
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
From your doGet and doPost methods, you can call your doService(..,..) method if you wish.
You will note that the service() method originates from the javax.servlet.GenericServlet and not javax.servlet.http.HttpServlet.
If you want to do something with a servlet which doesn't involve the http protocol, I would say go ahead.
In the Head First Servlets and JSP they explain this in detail. 99% You will make use of the HttpServlet.
By extending GenericServlet, the servlet would run regardless of the content submitted. As long as the URL is fired the service() method will execute.
My understanding, if I got you correct, is you want your HTTP GET, POST, (PUT, DELETE) to call your doService method. If that's the case, you can do this.
protected doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doService(request,response)
}
protected doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doService(request,response)
}
If you extends HttpServlet you don't have to override doGet and doPost as it's already implemented by HttpServlet. Servlet request get handled by the service() method which then (based on the HTTP request method) calls its relevant doXXX method.
I wouldn't mess with the service() method though, unless you know what you're doing.