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">
Related
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");
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
This question already has answers here:
Change default homepage in root path to servlet with doGet
(2 answers)
Closed 7 years ago.
I am trying to redirect to an HTML page from a servlet. For debugging, I have minimal amount of code in my servlet, HTML page and in web.xml
I can load HTML page fine in browser without the servlet. But when I try to redirect to the same page from a servlet, only a blank page is rendered. No error is displayed.
Following is the relevant code.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>name</display-name>
<listener>
<listener-class>net.semandex.salsa.webapp.SalsaWebApp</listener-class>
</listener>
<servlet>
<description>
</description>
<display-name>SalsaValidationServlet</display-name>
<servlet-name>SalsaValidationServlet</servlet-name>
<servlet-class>net.semandex.salsa.validationServlets.SalsaValidationServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SalsaValidationServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>20</session-timeout>
</session-config>
</web-app>
Servlet
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SalsaValidationServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = request.getPathInfo();
if(path == null) return;
String []p = path.split("/");
if( !path.endsWith("licenseValidation.html") )
//request.getRequestDispatcher("/auth/licenseValidation.html").forward(request, response);
response.sendRedirect( request.getContextPath() + "/auth/licenseValidation.html" );
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doGet(req, resp);
}
}
HTML Page - licenseValidation.html
<html>
<head>
<title>License upload page</title>
</head>
<body>
<form>
<input type="text" name="name"/><br>
<input type="text" name="group"/>
<input type="text" name="pass"/>
<input type="submit" value="submit">
</form>
</body>
</html>
Why is this code loading a blank page and not an HTML page?
Redirection does happen but to a blank page. Status code for the new URL in browser is 200 but the response is empty in debugger.
Edit:
The problem was "/*" URL pattern as stated by BalusC. Found more useful information in his another answer.
Difference between / and /* in servlet mapping url pattern
The request URL that you are using doesn't have any extra path information associated. So the request.getPathInfo() is returning null and the redirection is not getting triggered.
If you want to redirect to any page, even if there are no extra path info, you need to remove the null check. Just redirect it :
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//String path = request.getPathInfo();
//if(path == null) return;
//String []p = path.split("/");
//if( !path.endsWith("licenseValidation.html") )
//request.getRequestDispatcher("/auth/licenseValidation.html").forward(request, response);
response.sendRedirect( request.getContextPath() + "/auth/licenseValidation.html" );
}
request.getPathInfo returns null if there are no extra path info : getPathInfo
Suppose you have defined the servlet-mapping as this:
<servlet-mapping>
<servlet-name>SalsaValidationServlet</servlet-name>
<url-pattern>/salsadb/*</url-pattern>
</servlet-mapping>
And you are sending the request to this URL:
http://localhost:8080/<appName>/salsadb/some_text
This time pathInfo will not be null; it will have the value as /some_text, which is the extra path info associated with the URL.
EDIT:
The SalsaValidationServlet is mapped to serve all the requests to the application. The first request that is coming is this :
http://localhost:8080/salsadb/
The doGet method of SalsaValidationServlet gets invoked and the value of pathInfo is /. It redirects the request to /auth/licenseValidation.html.
Now the browser will send a new request to the redirect URL, which in this case is : /auth/licenseValidation.html. Again the doGet method of SalsaValidationServlet is getting invoked, because it is mapped with this /* : execute for any request to the application. This time the value of pathInfo is /licenseValidation.html, which is not satisfying this if condition:
if( !path.endsWith("licenseValidation.html") )
and because of this the redirection is not getting triggered this time.
I think this will clarify the problem. If possible, change the servlet-mapping to serve only the required requests to the application.
I think your url-pattern tag is the problem please change it to something other than /*.
I didn't understand why you are trying to redirect to a image?
However if you still want to see the image then add the salsa-icon.png in a HTML/jsp page and redirect to it.
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">
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