What is called first doGet or doPost? [duplicate] - http

This question already has answers here:
doGet and doPost in Servlets
(5 answers)
Closed 1 year ago.
I have question about doGet doPost priorities (if there are any). Here is my HelloServlet class:
public class HelloServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().println("Hello, World Post!");
}
#Override
public void init() throws ServletException {
System.out.println("Servlet " + this.getServletName() + " has started.");
}
#Override
public void destroy() {
System.out.println("Servlet " + this.getServletName() + " has stopped.");
}
This class is mapped to the /greeting URL. When I try to access this page now, everything is fine. But when I change the doPost and doGet methods I gives me an error: HTTP Status 405 - HTTP method GET is not supported by this URL. Everytime I read about doGet and doPost I assume these methods are interchangeable. So what is the problem with this version of these methods?
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("Hello, World Post!");
}
This of course caused no exception because doGet is present, but it will not do any work. When I remove doGet method it throws the exception.
Can you please tell me what exactly happens in the moment I use my code URL? http://localhost:8080/greeting
Why the client just cannot use the doPost method to obtain the data from the server when doGet is completely missing?
Thank you!
UPDATE WEB.xml file
<display-name>Hello World Application</display-name>
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.wrox.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/greeting</url-pattern>
</servlet-mapping>

If you do not specify the request method by default it will be GET which means doGet() will be called.
example: http://www.anywebsite.com is a default GET request.
But you have to specify your request is a POST request to execute doPost()
example:
<form action="/servlet" method="POST">
<input type="text" name="something"
</form>

if you have not mentioned in then default it call doGet method But if you have to specify your request is a POST in below code as like then tomcat call the service method where service method decide where request should go
<form action="/servlet" method="POST">
<input type="text" name="something"
</form>
The protected service method checks the type of request, if request type is get, it calls doGet method, if request type is post, it calls doPost method, so on. Let's see the internal code:
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
if(method.equals("GET"))
{
long lastModified = getLastModified(req);
if(lastModified == -1L)
{
doGet(req, resp);
}
//rest of the code
}
}

Related

how to execute doGet method of servlet by writing method post in form tag

The form calls the servlet logout.
<form name="fm1" method="post" action="logout">
This is the servlet code:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
request.getRequestDispatcher("index.jsp").include(request, response);
HttpSession session=request.getSession();
session.invalidate();
out.print("You are successfully logged out!");
out.close();
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("index.jsp").include(request, response);
response.setContentType("text/html");
PrintWriter out = response.getWriter();
HttpSession session=request.getSession();
session.invalidate();
out.print("You are successfully logged out!");
out.close();
}
I am unable to understand how to get to the servlet to execute using doGet when I'm using post in my form. How will it be called?
Call doGet(request, response) method in post method of servlet
This probably is not an answer, and I am unable to comment, but why are you not using the doPost method?
Or change the method in the form to get?

Wildcard path mapping /A/* should return 404 when path info is absent like /A

I am new in Servlets. I am trying to map a URL using the wildcard (*), but it's not working the way i expected.
Here is my servlet class.
#WebServlet(urlPatterns = {"/A/*"})
public class TestServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("Working...");
}
}
The above servlet is working for both example.com/A and example.com/A/car.
I want to work the servlet only for the the second option which is example.com/A/whatEver. How can i do that ?
In simple: I just want to work the servlet if there's anything after example.com/A.
Any help will greatly appreciated.
Just invoke HttpServletResponse#sendError() with SC_NOT_FOUND (404) when HttpServletRequest#getPathInfo() is null or empty or equals to /.
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String pathInfo = request.getPathInfo();
if (pathInfo == null || pathInfo.isEmpty() || pathInfo.equals("/")) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// ... (continue)
}

the life cycle of servlet : the calls on service() and doGet() are reversed

when i read book regarding the life cycle of servlet, it says that it first calls the service method, then the service method calls another method to handle specific HTTP request(GET or POST).But when I try this out, I find that the doGet or doPost method are firstly called before the service method being called. My Code and result are as follows, thx a lot!
public class Main extends HttpServlet {
#Override
public void init() throws ServletException {
// TODO Auto-generated method stub
super.init();
System.out.println("init has been called");
}
#Override
protected void service(HttpServletRequest arg0, HttpServletResponse arg1)
throws ServletException, IOException {
// TODO Auto-generated method stub
super.service(arg0, arg1);
System.out.println("service has been called");
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("get has been called");
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("post has been called");
}
}
result:
init has been called
get has been called
service has been called
post has been called
service has been called
Your book is correct. In your overridden service() method you're calling super.service() before the System.out.println() call; doPost() and doGet() are being called from the service() method of the superclass HttpServlet. Try putting the output line before the call to super.service() and you'll see.
If you remove super.service() from your method, neither doPost() nor doGet() will be called at all; this is why it's generally not a good idea to override service() unless you know what you're doing and have a good reason to do so.

Servlet doGet() doPost() method

Generally we specify the doGet and doPost in our HTML code, so that servlet will invoke these methods with respect to the call in HTML code.
Is there any way that whether we call doPost or doGet Servlet doPost method will get called?
I know there is one way that in doGet we can call doPost method , But apart from that is there any other method .
Calling one from the other, or better - calling a 3rd method from both is the best approach.
You can override the service() method as well, but there's more code there that you might not want to loose.
You can create a common method and put it into doGet() or doPost().
protected void processRequest(HttpServletRequest request,HttpServletResponse response)
throws ServletException, IOException {
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

HTTP Status 405 - HTTP method is not supported by this URL

I have the following servlet:
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 16252534;
private static int ping = 3000;
private Thread t;
private static boolean shouldStop = false;
#Override
public void init() throws ServletException {
super.init();
t = new Thread(new Runnable() {
#Override
public void run() {
while(!shouldStop) {
System.out.println("Now:" + System.currentTimeMillis());
try {
Thread.sleep(ping);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doGet(req, resp);
System.out.println("doGet");
PrintWriter out = resp.getWriter();
out.println("<html><h1>It works!!</h1></html>");
}
#Override
public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
super.service(req, resp);
System.out.println("service");
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
System.out.println("doPost");
}
#Override
public void destroy() {
super.destroy();
System.out.println("Destroy servlet");
shouldStop = true;
}
}
Which is mapped as follows in my web.xml:
<display-name>MyServer</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.myserver.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
When I open my browser (Chrome) on http://localhost:8080/MyServer/MyServlet, then I see "service" from doService() being logged on console and my thread works correctly, however I don't see "It Works" from doGet() being logged and I get the following error in the browser:
HTTP method GET is not supported by this URL
How is this caused and how can I solve it?
This is the default response of the default implementation of HttpServlet#doXxx() method (doGet(), doPost(), doHead(), doPut(), etc). This means that when the doXxx() method is not properly being #Overriden in your servlet class, or when it is explicitly being called via super, then you will face a HTTP 405 "Method not allowed" error.
So, you need to make sure that you have the doXxx() method properly declared conform the API, including the #Override annotation just to ensure that you didn't make any typos. E.g.
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// ...
}
And you also need to make sure that you don't ever call super.doXxx() in your servlet method:
super.doGet(request, response);
Your servlet has this. Just get rid of this line and your problem shall disappear.
The HttpServlet basically follows the template method pattern where all non-overridden HTTP methods returns this HTTP 405 error "Method not supported". When you override such a method, you should not call super method, because you would otherwise still get the HTTP 405 error. The same story goes on for your doPost() method.
This also applies on service() by the way, but that does technically not harm in this construct since you need it to let the default implementation execute the proper methods. Actually, the whole service() method is unnecessary for you, you can just remove the entire method from your servlet.
The super.init(); is also unnecessary. It's is only necessary when you override the init(ServletConfig), because otherwise the ServletConfig wouldn't be set. This is also explicitly mentioned in the javadoc. It's the only method which requires a super call.
Unrelated to the concrete problem, spawning a thread in a servlet like that is a bad idea. For the correct approach, head to How to run a background task in a servlet based web application?
you have overridden the service method which is responsible to delegate the call to doGet or doPost. see this for more details
Also get rid of super.doxxx(..) calls from each method.
Don't override the service method and you should see, "It Works" from doGet.

Resources