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">
Related
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>
I just started working with JSPs and came across one problem.
As I understand, JSP pages under WEB-INF can be accessed via a browser with the URL in localhost:
localhost:8080/MyProject/MyJSP.jsp
However, if I create another sub-folder within the WEB-INF folder (i.e. 'MyFolder') and try to access the same JSP page through the URL:
localhost:8080/MyProject/MyFolder/MyJSP.jsp
it gives an Error 404 instead. Are JSP file navigation systems treated differently to, say, HTML file navigation system?
EDIT: I am using servlets to display my JSP page as such:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.sendRedirect("MyJSP.jsp");
}
EDIT2: I've changed my redirect to a requestDispatcher as I've been advised to do:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/MyFolder/MyJSP.jsp");
dispatcher.forward(request, response);
}
If my #WebServlet is ("/myjsp"), can anyone still access my MyJSP.jsp page if they type localhost:8080/MyProject/myjsp?
As I understand, JSP pages under WEB-INF can be accessed via a browser with the URL in localhost
No. It's exactly the reverse. Everything under WEB-INF is not accessible by the browser.
It's a good practice to put them there precisely because you never want anyone to access a JSP from the browser directly. JSPs are views, and requests should go through a controller first, which then dispatches (i.e. forwards, not redirects, see RequestDispatcher.forward() vs HttpServletResponse.sendRedirect()) to the right view.
'/WEB-INF/' is considered to be a protected/secured folder and it is not advisable to make it accessible unless really required. If you still want to make these files available, try adding the below servlet mapping in your web.xml. Hope it helps
<servlet>
<servlet-name>MyJSP</servlet-name>
<jsp-file>/WEB-INF/MyFolder/*</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>MyJSP</servlet-name>
<url-pattern>/ViewMyJsp.jsp</url-pattern>
</servlet-mapping>
You can specify the mapping explicitly by declaring it with a element in the deployment descriptor. Instead of a <servlet-class> element, you specify a <jsp-file> element with the path to the JSP file from the WAR root.
I'm working on a web application using Java code, I had changed my code by making each page start from a servlet class.
Java code in servlet "indexServlet":
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
DataGathering dBConnector = new DataGathering();
List<Long> lstDetailVewOID;
lstDetailVewOID = dBConnector.getDetailVewOID();
request.setAttribute("detailVewLst", lstDetailVewOID);
// pass the list to jsp page.
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
Since then the CSS code stopped working, and it gives me this error :
Resource interpreted as Stylesheet but transferred with MIME type
text/html: "http://localhost:8080/firstApplication/Style-Sheet/Template-Style.css".
When tracing the code, I found that by running the doGet() method inside the servlet class, it's call the page and run it, then get back to the servlet again to close the method, I guess the error because of this procedure but am not sure and I can't solve it.
When searching through the internet i figured that the type should be text/css but i already did that, and the same CSS file was working find before changing the code.
calling the CSS file inside the jsp page:
<link href="Style-Sheet/Template-Style.css" rel="stylesheet" type="text/css">
Edit:
web.xml mapping:
<servlet>
<servlet-name>Index</servlet-name>
<servlet-class>com.Teklabz.Servlets.IndexServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Index</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I'm think you return static resources like css and images through your servlet. This is bad itself, but if you do, you need set right mime type in response headers. Actually i'm think you should change servlet-to-url mapping from /* to somewhat like /*.jsp, so, all other static resources will be handled by your tomcat/jetty, they do it right.
<web-app>
<servlet>
<servlet-name>Servlet1</servlet-name>
<servlet-path>foo.Servlet</servlet-path>
</servlet>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/*.jsp</url-pattern> <!-- right here! -->
</servlet-mapping>
</web-app>
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
This question already has answers here:
Calling a servlet from JSP file on page load
(4 answers)
Closed 6 years ago.
I have below servlet. I would like to call the servlet on jsp page load. How can I do that?
servlet: SomeServlet.java
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>SomeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/HelloWorld</url-pattern>
</servlet-mapping>
How can I write corresponding jsp to invoke the servlet on jsp page load. Also I need to get the result from servlet and display in the same jsp. Can I send result back to jsp?
Thanks!
You should do it the other way round. Call the servlet by its URL and let it present the JSP. That's also the normal MVC approach (servlet is the controller and JSP is the view).
First put the JSP file in /WEB-INF folder so that the enduser can never "accidently" open it by directly entering its URL in browser address bar without invoking the servlet. Then change the servlet's doGet() accordingly that it forwards the request to the JSP.
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// ...
request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request, response);
}
Open it by
http://localhost:8080/contextname/HelloServlet
Note that you can of course change the URL pattern in servlet mapping to something like /hello so that you can use a more representative URL:
http://localhost:8080/contextname/hello
See also:
Our Servlets tag info page
<jsp:include page="/HelloWorld"/>
Call a servlet instead get result in request attribute and forward the request to jsp
or make an ajax call to servlet on load and render the response using javascript
In JSP paage you can forward the request to the Servlet
response.sendRedirect(request.getContextPath()+"/SomeServlet");