I'm trying to create and run a servlet in IntelliJ. The problem I'm having is I'm following an Eclipse tutorial and they seem to work very differently. In Eclipse, a servlet.java class is created and run on Tomcat. In IntelliJ a .java class and .jsp file is created. The browser points to .jsp, not .java. The java class doesn't seem to be doing anything at all.
Why are they so different, and how can I point to the .java class instead of the .jsp?
I've added the .java and .jsp code below, which are both the standard stubs created by IntelliJ when creating a new servlet project.
#WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet {
private String message;
public void init() {
message = "The Tomcat server does not point to this code in IntelliJ";
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
// Hello
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>" + message + "</h1>");
out.println("</body></html>");
}
public void destroy() {
}
}
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<h1><%= "Tomcat points to this .jsp file, not the .java code" %>
</h1>
<br/>
Hello Servlet
</body>
</html>
The servlet class has an annotation indicating what URI to use, so whatever URL your application is accessed using, followed by /hello-servlet.
Kind of weird that they generate these files that'll be useless 99% of the time.
Related
How do I generate an HTML response in a Java servlet?
You normally forward the request to a JSP for display. JSP is a view technology which provides a template to write plain vanilla HTML/CSS/JS in and provides ability to interact with backend Java code/variables with help of taglibs and EL. You can control the page flow with taglibs like JSTL. You can set any backend data as an attribute in any of the request, session or application scope and use EL (the ${} things) in JSP to access/display them. You can put JSP files in /WEB-INF folder to prevent users from directly accessing them without invoking the preprocessing servlet.
Kickoff example:
#WebServlet("/hello")
public class HelloWorldServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String message = "Hello World";
request.setAttribute("message", message); // This will be available as ${message}
request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request, response);
}
}
And /WEB-INF/hello.jsp look like:
<!DOCTYPE html>
<html lang="en">
<head>
<title>SO question 2370960</title>
</head>
<body>
<p>Message: ${message}</p>
</body>
</html>
When opening http://localhost:8080/contextpath/hello this will show
Message: Hello World
in the browser.
This keeps the Java code free from HTML clutter and greatly improves maintainability. To learn and practice more with servlets, continue with below links.
Our Servlets wiki page
How do servlets work? Instantiation, sessions, shared variables and multithreading
doGet and doPost in Servlets
Calling a servlet from JSP file on page load
How to transfer data from JSP to servlet when submitting HTML form
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
How to use Servlets and Ajax?
Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available"
Also browse the "Frequent" tab of all questions tagged [servlets] to find frequently asked questions.
You need to have a doGet method as:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hola</title>");
out.println("</head>");
out.println("<body bgcolor=\"white\">");
out.println("</body>");
out.println("</html>");
}
You can see this link for a simple hello world servlet
Apart of directly writing HTML on the PrintWriter obtained from the response (which is the standard way of outputting HTML from a Servlet), you can also include an HTML fragment contained in an external file by using a RequestDispatcher:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("HTML from an external file:");
request.getRequestDispatcher("/pathToFile/fragment.html")
.include(request, response);
out.close();
}
How do I generate an HTML response in a Java servlet?
You normally forward the request to a JSP for display. JSP is a view technology which provides a template to write plain vanilla HTML/CSS/JS in and provides ability to interact with backend Java code/variables with help of taglibs and EL. You can control the page flow with taglibs like JSTL. You can set any backend data as an attribute in any of the request, session or application scope and use EL (the ${} things) in JSP to access/display them. You can put JSP files in /WEB-INF folder to prevent users from directly accessing them without invoking the preprocessing servlet.
Kickoff example:
#WebServlet("/hello")
public class HelloWorldServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String message = "Hello World";
request.setAttribute("message", message); // This will be available as ${message}
request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request, response);
}
}
And /WEB-INF/hello.jsp look like:
<!DOCTYPE html>
<html lang="en">
<head>
<title>SO question 2370960</title>
</head>
<body>
<p>Message: ${message}</p>
</body>
</html>
When opening http://localhost:8080/contextpath/hello this will show
Message: Hello World
in the browser.
This keeps the Java code free from HTML clutter and greatly improves maintainability. To learn and practice more with servlets, continue with below links.
Our Servlets wiki page
How do servlets work? Instantiation, sessions, shared variables and multithreading
doGet and doPost in Servlets
Calling a servlet from JSP file on page load
How to transfer data from JSP to servlet when submitting HTML form
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
How to use Servlets and Ajax?
Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available"
Also browse the "Frequent" tab of all questions tagged [servlets] to find frequently asked questions.
You need to have a doGet method as:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hola</title>");
out.println("</head>");
out.println("<body bgcolor=\"white\">");
out.println("</body>");
out.println("</html>");
}
You can see this link for a simple hello world servlet
Apart of directly writing HTML on the PrintWriter obtained from the response (which is the standard way of outputting HTML from a Servlet), you can also include an HTML fragment contained in an external file by using a RequestDispatcher:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("HTML from an external file:");
request.getRequestDispatcher("/pathToFile/fragment.html")
.include(request, response);
out.close();
}
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 have troubled with custom error page on Tomcat 5.0.28. Error page written in Japanese become unreadable. (likes ... あいう -> ??????)
My environment.
Java Sun SDK 1.4
Tomcat 5.0.28
I have a Java application what has a servlet to convert extension from .htm to .jsp of any URL request. My JSPs written in Japanese, so requires encoding specified content-Type header, and the servlet provides it. They get along well.
I want to add a customized Japanese 404 error page to this app. But that 404 page's Japanese become unreadable only when access via the servlet. It looks like lose a encoding specified Content-Type header that case(I see a HTTP request header on that page). Normally text/html; charset=Shift_JIS, but when unreadable becomes text/html.
Not through that servlet, Content-Type header is as usual and customized 404 page's Japanese are works. The servlet is only mapped to request that have extension *.htm .
My error page settings on application's web.xml:
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
My servlet source:
public class Converter extends HttpServlet {
public void init() throws ServletException {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
response.setContentType("text/html; charset=Shift_JIS");
ServletContext context = getServletConfig().getServletContext();
PrintWriter out = response.getWriter();
String reqUrl = request.getServletPath();
String jspName = reqUrl.substring(1,reqUrl.indexOf("."));
RequestDispatcher dispatcher = context.getRequestDispatcher("/"+jspName+".jsp");
dispatcher.forward(request,response);
}
public void destroy() {
}
}
error page JSP "404.jsp":
<%# page language="java" isErrorPage="true" %>
<%# page contentType="text/html; charset=Shift_JIS" pageEncoding="Shift_JIS" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
</head>
<body>
test 404<br />
日本語出力テスト<br />
</body>
</html>
Request URL and output (no such JSP/HTM files on server):
http://example.com/nonexisting.htm(through the servlet)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
</head>
<body>
test 404<br />
????????<br />
</body>
</html>
http://example.com/nonexisting.jsp(not through the servlet)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
</head>
<body>
test 404<br />
日本語出力テスト<br />
</body>
</html>
Here's some tests I tried. Each files are written in Shift_JIS and contains Japanese.
Existing file request tests.
mydomain.com/existing.jsp(not through the servlet) -> no problem.
mydomain.com/existing.htm(through the servlet) -> no problem.
Non-existing file request tests(Sure, no such files on my server.).
mydomain.com/nonexisting.jsp(not through the servlet) -> displays custom 404 page with Japanese, and no problem.
mydomain.com/nonexisting.htm(through the servlet) -> displays custom 404 page, but loses Content-Type header and Japanese characters are unreadable.
Additionally I tried:
I tried CharacterEncodingFilter bundled with Tomcat, but it also doesn't work. Configure as to make a request encoded as Shift_JIS when it's /404.jsp, but results same as above.
Thanks for to be patient my terrible English (>_<)
Any help would be very appreciated.
Solved
Just remove never used getWriter(), then the 404 page no more lacks encoding-specified Content-Type header and works.
public class Converter extends HttpServlet {
public void init() throws ServletException {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
response.setContentType("text/html; charset=Shift_JIS");
ServletContext context = getServletConfig().getServletContext();
//PrintWriter out = response.getWriter();
String reqUrl = request.getServletPath();
String jspName = reqUrl.substring(1,reqUrl.indexOf("."));
RequestDispatcher dispatcher = context.getRequestDispatcher("/"+jspName+".jsp");
dispatcher.forward(request,response);
}
public void destroy() {
}
}
There are two general error classes:
the 404 response has a Content-Type header stating it is charset=Shift_JIS but it actually is encoded differently or corrupted. Assuming 404.jsp is encoded correctly on disk, it could be corrupted when it's loaded into a string or converted when the string is written to the HTTP response. Where do you set the encoding of your Reader and/or Writers to Shift_JIS?
the 404 response is encoded as Shift_JIS but the Content-Type header specifies a different charset (or none, defaulting to ISO-8859-1). Your doGet() method appears to do the right thing for 200 responses, but 404 errors are likely to take a different path.
Clearly, looking at the HTTP headers of your 404 response would be very informative. You should also debug the application to inspect how 404 responses are handled.
I'm going through this Spring tutorial online form springsource.org.
http://static.springsource.org/docs/Spring-MVC-step-by-step/part2.html
In Chapter 2, at the end, it has you add a bean to prefix and suffix /WEB-INF/jsp/ and .jsp to responses.
The code so far should basically load index.jsp when you go to localhost:8080/springapp/ which will redirect to localhost:8080/springapp/hello.htm which creates an instance of the HelloController which should in theory send you over to /WEB-INF/jsp/hello.jsp. When I added the prefix/suffix bean and changed all my references to just "hello" instead of the fully pathed jsp file, I started getting the following error:
message Handler processing failed; nested exception is
java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/fmt/LocalizationContext
I've tried going back through the samples several times and checking for typo's and I still can't find the problem. Any tips or pointers?
index.jsp (in the root of the webapp:
<%# include file="/WEB-INF/jsp/include.jsp" %>
<%-- Redirected because we can't set the welcome page to a virtual URL. --%>
<c:redirect url="/hello.htm" />
HelloController.java (minus the imports and package:
public class HelloController implements Controller {
protected final Log logger = LogFactory.getLog(getClass());
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String now = (new Date()).toString();
logger.info("Returning hello view with " + now);
return new ModelAndView("hello", "now", now);
}
}
My hello.jsp file:
<%# include file="/WEB-INF/jsp/include.jsp" %>
<!DOCTYPE html>
<html>
<head>
<title>Hello :: Spring Application</title>
</head>
<body>
<h1>Hello - Spring Application</h1>
<p>Greetings, it is now <c:out value="${now}" /></p>
</body>
</html>
It seems like you are missing the JSTL jar here. Try downloading it and place it in your classpath to see if it works: Where can I download JSTL jar
It seems certain required jar(s) are missing from classpath.
Make sure you have servlet-api-2.x.jar jsp-api-2.x.jar and jstl-1.x.jar on classpath
Please make sure the jstl.jar file is located in your WEB-INF/lib folder.
As a matter of fact, here is what is stated in the tutorial that you linked. I guess you missed this step:
We will be using the JSP Standard Tag Library (JSTL), so let's start
by copying the JSTL files we need to our 'WEB-INF/lib' directory. Copy
jstl.jar from the 'spring-framework-2.5/lib/j2ee' directory and
standard.jar from the 'spring-framework-2.5/lib/jakarta-taglibs'
directory to the 'springapp/war/WEB-INF/lib' directory.