Why can't i use doGet method in my servlet code? - java

I am new to servlets and i have developed a html page which has a submit button that triggers
my servlet.Everything is working fine .But now i want to use GET method as my html page is not posting anything.Hence i made the following changes:
1)In my page.html file, i replaced method="POST" with method="GET".
2)I changed doPost with doGet in my servlet.
But i'm getting error message that "GET not allowed here".Why is it so?
Here are the original files which work correctly(prior to making changes):
My page.html page:
<html>
<head>
<title>A simple revision of servlets</title>
</head>
<body>
<form method="POST" action="Idiot">
<input type="SUBMIT">
</form>
</body>
</html>
My Deployment Descriptor:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>TangoCharlie</servlet-name>
<servlet-class>Revise</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TangoCharlie</servlet-name>
<url-pattern>/Idiot</url-pattern>
</servlet-mapping>
</web-app>
And finally my servlet file named Revise.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class Revise extends HttpServlet
{
public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException
{
response.setContentType("text/html");
PrintWriter out=response.getWriter();
out.println("<html><body><h3>Hello India</h3></body></html>");
out.println("Hello");
}
}

I don't want to add any input fields.My aim is just to run the servlet without a single button on html page that too called using "POST" method.
Just do the job in doGet() method (don't forget to properly rebuild/redeploy/restart the project after editing servlet code, otherwise you will still face a "HTTP 405: method not allowed" error) and invoke the URL of the servlet directly instead of the URL of the JSP in the browser's address bar.
So, the URL in browser address bar should be
http://example.com/contextname/Idiot
instead of
http://example.com/contextname/page.html
Unrelated to the concrete problem, emitting HTML in a servlet is bad design. It should be done by a JSP. You can use RequestDispatcher#forward() to forward the request to a JSP after finishing the doGet() business logic. Further, packageless classes are also a bad design. You should always put publicly reuseable Java classes in a package. Packageless servlets will only work on certain combinations of Tomcat + JVM versions.
See also:
Our servlets wiki page - contains concrete (and properly designed) Hello World examples

Related

Send data from Servlet for JSP with JSTL [duplicate]

Can I call a servlet from JSP file without using a HTML form?
For example, to show results from database in a HTML table during page load.
You can use the doGet() method of the servlet to preprocess a request and forward the request to the JSP. Then just point the servlet URL instead of JSP URL in links and browser address bar.
E.g.
#WebServlet("/products")
public class ProductsServlet extends HttpServlet {
#EJB
private ProductService productService;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<Product> products = productService.list();
request.setAttribute("products", products);
request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response);
}
}
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...
<table>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.name}</td>
<td>${product.description}</td>
<td>${product.price}</td>
</tr>
</c:forEach>
</table>
Note that the JSP file is placed inside /WEB-INF folder to prevent users from accessing it directly without calling the servlet.
Also note that #WebServlet is only available since Servlet 3.0 (Tomcat 7, etc), see also #WebServlet annotation with Tomcat 7. If you can't upgrade, or when you for some reason need to use a web.xml which is not compatible with Servlet 3.0, then you'd need to manually register the servlet the old fashioned way in web.xml as below instead of using the annotation:
<servlet>
<servlet-name>productsServlet</servlet-name>
<servlet-class>com.example.ProductsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>productsServlet</servlet-name>
<url-pattern>/products</url-pattern>
</servlet-mapping>
Once having properly registered the servlet by annotation or XML, now you can open it by http://localhost:8080/context/products where /context is the webapp's deployed context path and /products is the servlet's URL pattern. If you happen to have any HTML <form> inside it, then just let it POST to the current URL like so <form method="post"> and add a doPost() to the very same servlet to perform the postprocessing job. Continue the below links for more concrete examples on that.
See also
Our Servlets wiki page
doGet and doPost in Servlets
How to avoid Java code in JSP
Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available"
You will need to use RequestDispatcher's Methods forward/include depending on your requirement to achieve same.
In JSP you need to use following tags:
jsp:include :
The element allows you
to include either a static or dynamic
file in a JSP file. The results of
including static and dynamic files are
quite different. If the file is
static, its content is included in the
calling JSP file. If the file is
dynamic, it acts on a request and
sends back a result that is included
in the JSP page. When the include
action is finished, the JSP container
continues processing the remainder of
the JSP file.
e.g.
<jsp:include page="/HandlerServlet" flush="true">
jsp:forward :
The element forwards the
request object containing the client
request information from one JSP file
to another file. The target file can
be an HTML file, another JSP file, or
a servlet, as long as it is in the
same application context as the
forwarding JSP file. The lines in the
source JSP file after the
element are not
processed.
e.g.
<jsp:forward page="/servlet/ServletCallingJsp" />
Check Advanced JSP Sample : JSP-Servlet Communication:
http://www.oracle.com/technology/sample_code/tech/java/jsps/ojsp/jspservlet.html
Sure you can, simply include it in your action in the form. But you have to write the correct doPost or doGet to handle the request!
If you want to call a particular servlet method than you also use Expression Language. For example, you can do something like:
Servlet
ForexTest forexObject = new ForexTest();
request.setAttribute("forex", forexObject);
JSP
<body bgcolor="#D2E9FF">
Current date : ${forex.rate}
</body>

Unable to configure Intellij Web App deployment corrrectly

I'm creating a Java web application using JSP and Servlets, TomCat 9 and IntelliJ. The tutorial I'm following uses Eclipse, where the instructor just runs the project as Run As > Run On Server and everything works seamlessly.
In IntelliJ, things seem all messed up.
This is my project structure -
This is the Run Configuration -
I have the web.xml setup as -
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Archetype Created Web Application</display-name>
<welcome-file-list>
<welcome-file>login.do</welcome-file>
</welcome-file-list>
</web-app>
So, any requests to localhost:8080, or in the case of IntelliJ, http://localhost:8080/jspservlet_war_exploded/ should be redirected to login.do, which is handled by LoginServlet -
package app;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
#WebServlet(urlPatterns = "/login.do")
public class LoginServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String pass = req.getParameter("password");
req.setAttribute("name", name);
req.setAttribute("password", pass);
RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/login.jsp");
requestDispatcher.forward(req, resp);
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
req.setAttribute("name", name);
RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/welcome.jsp");
requestDispatcher.forward(req, resp);
}
}
At first, I was testing the doGet() method in LoginServlet, by just manually adding the ?name=xxx&password=xxx query string in the start page - http://localhost:8080/jspservlet_war_exploded/. These attributes were set in the request and then forwarded to login.jsp, which would just display the attribute values using ${name} and ${password}. Things worked fine until this step.
Then, I changed the login.jsp page to include a simple form that has an input field to enter the user's name, and have it sent to /login.do via the action attribute, using the POST method. This is where things blew up.
Here is login.jsp -
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Login Page</title>
</head>
<body>
<h1>Welcome</h1>
<p>Time on server is <%= new Date()%></p>
<%--<p>Your name is ${name} and password is ${password}</p>--%>
<p>pageContext.request.contextPath: ${pageContext.request.contextPath}</p>
<form action="/login.do" method="post">
<label for="inp">Enter your name </label>
<input id="inp" type="text" name="name"/>
<button>Submit</button>
</form>
</body>
</html>
which results in this page -
Now, as soon as I hit "submit", the request seems to go to localhost:8080/login.do (because that's what the action attribute's value is), and that throws an error -
Based on the other questions I've read here, it looks like that happens because the context path (ie. root of the application) is http://localhost:8080/jspservlet_war_exploded/, and all locations are relative to this path(?). So, the recommended way seems to be ${pageContext.request.contextPath}.
Based on that, if I change the action attribute to action="${pageContext.request.contextPath}/login.do", then things work again.
However, now I'm trying to redirect from the doPost() method in LoginServlet to TodoServlet, like so -
resp.sendRedirect("/todo.do");
This again causes a 404, because the URL becomes http://localhost:8080/todo.do, whereas it should be http://localhost:8080/jspservlet_war_exploded/todo.do.
How do I fix things so that all resources are deployed relative to http://localhost:8080/jspservlet_war_exploded/ by default, and I can just specify the URL pattern directly in action or resp.sendRedirect()?
Change the deployment context in the Run/Debug configuration:
If you want the app to work with any context you should use the relative paths instead like described here.
Instead of resp.sendRedirect("/todo.do"); use resp.sendRedirect("todo.do"); or resp.sendRedirect(req.getContextPath() + "/todo.do");
did you try this :
resp.sendRedirect("todo.do");

grammar and syntax

I've enough knowledge to develop in Java SE/JavaFX (Desktop), but it's my 1st time with Java EE (WEB). I'd like to build a basic app only getting Login and Password in a HTML/JSP, calling a Servlet (in Java) and returning a single message to the HTML/JSP. This time I want to do that the "hard way", without any IDE. So, I've installed Tomcat 7.0 and I have those modules:
Java (this example only receive from HTML/JSP)
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 loginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String userName = request.getParameter("userName");
String password = request.getParameter("password");
out.println("<html>");
out.println("<body>");
out.println("Hello " + " " + userName + "welcome to my blog");
out.println("Your password is : " + " " + password + "<br>");
out.println("</body></html>");
}
}
HTML/JSP
<!DOCTYPE html>
<html lang ="pt-br">
<head>
<title> loginServlet </title>
<meta http-equiv = ”Content-Type” content=”text/html; charset=UTF-8”>
<link rel="stylesheet" type="text/css"
href="c:/java/html/css/estilo.css"/>
</head>
<body>
<h2> Login Page </h2>
<p>Please enter your username and password</p>
<form method="GET" action="loginServlet">
<p> Username <input type="text" name="userName" size="50"> </p>
<p> Password <input type="text" name="password" size="20"> </p>
<p> <input type="submit" value="Submit" name="B1"> </p>
</form>
</body>
</html>
WEB.XML
<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>loginServlet</display-name>
<description>
This is a simple web application with a source code organization
based on the recommendations of the Application Developer's Guide.
</description>
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>java.loginServlet.WebContaint.WEB-
INF.classes.loginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/loginServlet</url-pattern>
</servlet-mapping>
</web-app>
Paths and folders
loginServlet.class is in C://java/loginServlet/WebContaint/WEB-INF/classes/
loginServlet.jsp is in C://java/loginServlet/WebContaint/
web.xml is in C://java/loginServlet/WebContaint/WEB-INF/
loginServlet.war is in C:\Program Files\Apache Software Foundation\
Tomcat 7.0\webapps
When I try to call in my Chrome, using a localhost (http://localhost:8080/loginServlet), I receive a 404 Error.
Your Servlet class name looks wrong:
<servlet-class>java.loginServlet.WebContaint.WEB-
INF.classes.loginServlet</servlet-class>
I'm not even sure it is possible to place user code in the java namespace (it might be protected), regardless I wouldn't recommend it. Also having WEB-INF.classes in the package name is not right. Splitting the name over multiple lines is also not right.
In fact, in your code, you don't even have a package name, so you should be able to write:
<servlet-class>loginServlet</servlet-class>
Read this tutorial on creating servlets, which addresses naming of servlet classes and cross-referencing them from a web.xml file.
Note, you don't even need a web.xml file for a simple example like this, you can just use an #WebServlet annotation.
Aside:
Current version of Tomcat is 9.x, I wouldn't recommend using old versions like 7.x.
Stick to Java naming conventions (e.g. call your class LoginServlet, not loginServlet).
To learn JEE, I recommend using the official JEE tutorial.
A stranger thing happaned: it's seem that only (directly) servlet (loginServlet.class) was called. The HTML (loginServlet.jsp) didn't show the page where Login and Password can be informed. And i saw the msg "Hello userName welcome to my blog" that is generate by Servlet (loginServlet.class). With Login and Password null, of course.
From your earlier question, you say that you are invoking the app like this:
http://localhost:8080/loginServlet
That isn't going to tell the app to use the jsp file you have created, which you have named loginServlet.jsp. The breakdown of the call you made is that you are using the http protocol over port 8080 to access your tomcat server. You provide the path /loginServlet, which is identifying your web application (by default, it gets its name from the war file which you deployed, which you called loginServlet.war). Once in the app it will try to open a welcome file if there is one. But you haven't provided a welcome file or an empty name mapping for the servlet, so, normally, I would just expect a 404 not found error for that url.
The url of your servlet would be
http://localhost:8080/loginServlet/loginServlet
The first loginServlet identifies your app, the second loginServlet identifies the servlet itself. So, accessing that url will directly access the servlet processing.
But, you don't want your user to directly invoke that. Instead, you want your jsp file to show, and then for it to send data to server http://localhost:8080/loginServlet/loginServlet to trigger the servlet processing.
Your two options to access the jsp are either to provide a welcome file or to provide the fully qualified name in your request string.
A fully qualified name request would be:
http://localhost:8080/loginServlet/loginServlet.jsp
If, instead you want to assign a welcome file, you could add the following section to your web.xml:
<welcome-file-list>
<welcome-file>loginServlet.jsp</welcome-file>
</welcome-file-list>
Then the following access string should bring up the loginServlet.jsp page:
http://localhost:8080/loginServlet

My url mapping is diverting my CSS pages

I am working on a Dynamic Web Application with simple Java, Eclipse, and Tomcat 7.
Until I made the below changes, everything worked perfectly.
I recently added a home page Servlet Home.java and home page jsp Home.jsp and mapped the servlet to the URL / in the web.xml like
<servlet>
<display-name>Home</display-name>
<servlet-name>Home</servlet-name>
<servlet-class>my_proj.servlets.Home</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Home</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
The Servlet Home.java looks like:
public class Home extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("Servlet \"Home\" doGet working");
System.out.println("PathInfo: " + request.getRequestURL());
//If logged in, go to home page
request.getRequestDispatcher("/resources/jsp/home.jsp").forward(request, response);
//If not, go to login/register page
// TODO
}
}
And the Home.jsp is quite long, but everything is working except the resources like CSS, images, etc. They are not being loaded by the page. I am referencing them with
<link href="/my_proj/resources/css/custom.css" rel="stylesheet">
The Cause
Because of the code I put in the doGet method above, I can see that the requests to find the CSS page are actually ending up at the Home servlet. For instance this is part of what I see in the console
Servlet "Home" doGet working
PathInfo: http://localhost:8080/my_proj/resources/css/custom.css
So my question is, how to I properly map my pages so as to not to cause this confusion? Or how do I separate my CSS from relying on this mapping system? I don't want web.xml to handle the mapping to these files.
Please give your directory structure, for example If your directory structure like :
Project Name\WebContent\css then just add following line to include css on your page :
<link href="css/fileName.css" rel="stylesheet">
That's it, No need to provide full path : like Project Name\WebContent\css\fileName.css
<link href="/css/fileName.css" rel="stylesheet">

Servlets beginner

I am studying a Java EE course at the moment and I am on the module with servlets.
Included in the course are simple sample servlets.
This may sound dumb but I cant get any of them to work either by themselves or in netbeans on the glassfish server.
I have tried dropiing them in the web pages folder in the project and also I replaced the content of the index.jsp file with WelcomeServlet.html content.
The example I will use her is the first one and the most simple called WelcomeServlet.
The function of the servlet is that when the user pressed the "get html document" button the program should retrieve the document from the .java file.
However when I press the button I get this error
HTTP Status 404 - Not Found
type Status report
messageNot Found
descriptionThe requested resource is not available.
GlassFish Server Open Source Edition 4.0
Here is the code in question.
WelcomeServlet.html
<?xml version = "1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Fig. 17.6: WelcomeServlet.html -->
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title>Handling an HTTP Get Request</title>
</head>
<body>
<form action = "/advjhtp1/welcome1" method = "get">
<p><label>Click the button to invoke the servlet
<input type = "submit" value = "Get HTML Document" />
</label></p>
</form>
</body>
</html>
WelcomeServlet.java
// Fig. 16.5: WelcomeServlet.java
// A simple servlet to process get requests.
package com.deitel.advjhtp1.servlets;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class WelcomeServlet extends HttpServlet {
// process "get" requests from clients
protected void doGet( HttpServletRequest request,
HttpServletResponse response )
throws ServletException, IOException
{
response.setContentType( "text/html" );
PrintWriter out = response.getWriter();
// send XHTML page to client
// start XHTML document
out.println( "<?xml version = \"1.0\"?>" );
out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " +
"XHTML 1.0 Strict//EN\" \"http://www.w3.org" +
"/TR/xhtml1/DTD/xhtml1-strict.dtd\">" );
out.println(
"<html xmlns = \"http://www.w3.org/1999/xhtml\">" );
// head section of document
out.println( "<head>" );
out.println( "<title>A Simple Servlet Example</title>" );
out.println( "</head>" );
// body section of document
out.println( "<body>" );
out.println( "<h1>Welcome to Servlets!</h1>" );
out.println( "</body>" );
// end XHTML document
out.println( "</html>" );
out.close(); // close stream to complete the page
}
}
If anyone out there can get this code running please help me to do the same.
Inside your Web application project, you should have a folder called WEB-INF and in it you should have a file called web.xml. If you don't, create it and put it there. This is known as the Deploymenet Descriptor. You can read about it here.
It should contain at least the following
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5"> // or another version
<servlet>
<servlet-name>welcome</servlet-name>
<servlet-class>com.deitel.advjhtp1.servlets.WelcomeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>welcome</servlet-name>
<url-pattern>/welcome</url-pattern>
</servlet-mapping>
</web-app>
You should then navigate to
localhost:XXXX/welcome
where XXXX is the Glassfish port, to view your page.
You can also do the above with annotations, if your container supports servlet 3.0.
I tried your code. Indeed nothing wrong in the java code. Probably just incorrect action path.
Full project:
Project name: TestServlet
WelcomeServlet.html:
<form action = "MyWelcomeServlet" method = "get">
web.xml:
<servlet>
<description>Welcome Servlet</description>
<display-name>Welcome Servlet</display-name>
<servlet-name>WelcomeServlet</servlet-name>
<servlet-class>com.deitel.advjhtp1.servlets.WelcomeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>WelcomeServlet</servlet-name>
<url-pattern>/MyWelcomeServlet</url-pattern>
</servlet-mapping>
Run it:
http://localhost:8080/TestServlet/WelcomeServlet.html
Click the button and it will run the servlet (you can try running the direct link to the servlet) which is:
http://localhost:8080/TestServlet/MyWelcomeServlet
(I prefix "My" before the servlet url-pattern so that you do not confuse between the servlet and the html link). Normally it is bad practice to give same name to the servlet and the html/jsp file.
You get a 404 not found because simply the form points to an incorrect path. So it can not find the servlet to submit to.
Your servlet class is "WelcomeServlet.java" in the package com.deitel.advjhtp1.servlets
So in the HTML, the path should be:
< form action = "com.deitel.advjhtp1.servlets.WelcomeServlet" method = "get">

Categories