This question already has answers here:
How to call servlet through a JSP page
(6 answers)
Closed 6 years ago.
I want to call a servlet latest_products on load of index.jsp page.This servlet has records in List. I want to pass this List<products> to index.jsp. But I don't want to display the name of servlet in url. Is there any way by which I can do this.
Solution 1
Steps to follow:
use jsp:include to call the Servlet from the JSP that will include the response of the Servlet in the JSP at runtime
set the attribute in the request in Servlet and then simply read it in JSP
Sample code:
JSP:
<body>
<jsp:include page="/latest_products.jsp" />
<c:out value="${message }"></c:out>
</body>
Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("message", "hello");
}
EDIT
but i don't want to display the name of servlet in url.
Simply define a different and meaningful url-pattern for the Servlet in the web.xml such as as shown below that look like a JSP page but internally it's a Servlet.
web.xml:
<servlet>
<servlet-name>LatestProductsServlet</servlet-name>
<servlet-class>com.x.y.LatestProductsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LatestProductsServlet</servlet-name>
<url-pattern>/latest_products.jsp</url-pattern>
</servlet-mapping>
Solution 2
Steps to follow:
first call to the the Servlet
process the latest products
set the list in the request attribute
forward the request to the JSP where it can be accessed easily in JSP using JSTL
Sample code:
Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("message", "hello");
RequestDispatcher view=request.getRequestDispatcher("index.jsp");
view.forward(request,response);
}
index.jsp:
<body>
<c:out value="${message }"></c:out>
</body>
hit the URL: scheme://domain:port/latest_products.jsp that will call the Servlet's doGet() method.
(...) but I don't want to display the name of servlet in url.
You don't need to use the Servlet name at all when accessing to a Servlet. In fact, you can create your servlet to point to the desired URL by defining the right URL pattern:
#WebServlet("/index.jsp")
public class LatestProductServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
List<Product> productList = ...
//all the necessary code to obtain the list of products
//store it as request attribute
request.setAttribute("productList", productLlist);
//forward to the desired view
//this is the real JSP that has the content to display to user
request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
}
}
Then, you will have a folder structure like this
- <root folder>
- WEB-INF
+ index.jsp
+ web.xml
And in WEB-INF/index.jsp:
<!DOCTYPE html>
<html lang="es">
<body>
<!--
Display the data accordingly.
Basic quick start example
-->
<c:forEach items="${productList}" var="product">
${product.name} <br />
</c:forEach>
</body>
</html>
Note that your clients will access to http://<yourWebServer>:<port>/<yourApplication>/index.jsp and will get the desired content. And you don't need to fire two GET requests to retrieve the content for your specific page.
Note that you can go further with this approach: Since the pattern is now defined in servlet, you may choose to not use index.jsp for your clients, but index.html to access to your page. Just change the URL pattern in the Servlet:
#WebServlet("/index.html")
public class LatestProductServlet extends HttpServlet {
//implementation...
}
And the clients will access to http://<yourWebServer>:<port>/<yourApplication>/index.html, which will show the results in WEB-INF/index.jsp. Now both your clients and you will be happy: clients will get their data and you won't show that ugly servlet name in your URL.
Additional
If you have index.jsp as your welcome page in web.xml, this approach won't work because application servlet expects that a real file index.jsp exists. To solve this issue, just create an empty file named index.jsp:
- <root folder>
- index.jsp <-- fake empty file to trick the application server
- WEB-INF
+ index.jsp
+ web.xml
And when accessing to http://<yourWebServer>:<port>/<yourApplication>/, will work as shown above.
Thanks to +Braj, I am able to make an answer using Expression Language. Apparently, this is supposed to be better than jsp scripting/tags.
Servlet -
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ProductList extends HttpServlet {
private static final long serialVersionUID = 1L;
public ProductList() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<String> products = new ArrayList<String>();
products.add("Car");
products.add("Gun");
products.add("Shades");
request.setAttribute("productsList", products);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
JSP -
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<c:import url="/ProductList" />
<c:set var="myProducts" value="${requestScope.productsList}" />
<h1>List of products from servlet</h1>
<c:forEach var="product" items= "${myProducts}" varStatus="i">
${product}<br>
</c:forEach>
</body>
</html>
Related
This question already has answers here:
Generate an HTML Response in a Java Servlet
(3 answers)
Closed 3 years ago.
I'm trying to make a web application using Java Servlets, Tomcat and HTML on Eclipse. My problem is that after I created my Dynamic Web Project, along with my web.xml and my index.html files, the index.html page doesn't show anything.
Servlet:
#WebServlet("/index.html")
public class AppServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String HTML_START = "<html><body>";
private static final String HTML_END = "</body></html>";
public AppServlet() {
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<link rel="stylesheet" type="text/css" href="styling.css">
<title>Test page</title>
</head>
<body>
<h1 style="text-align:center;">Example text</h1>
<div align="center">
<textarea rows="12" cols="120" style="border-radius: 5px"></textarea>
</div>
</body>
</html>
The html page shows up just fine when I open it directly (when I double click on the file in a directory), but when I start up the server from Eclipse and it redirects me to localhost:8080/MyProject/index.html, nothing shows up.
Each URL can be processed by a single component: Either your URL is resolved to the file index.html or to a servlet. In your case servlet has higher priority and this servlet (not the file index.html) creates the result. Your servlet doesn't create any contents in the doGet method. SO it is naturally that the response is empty.
If you want that this URL is resolved to the file index.html, then use some other URL mapping in the servlet, like #WebServlet("/bla"). Then when you call .../MyProject/index.html, you will get the contents of the file index.html.
You grab that PrintWriter but you don't do anything with it. With the first line of your snippet, you've told the Server that you are going to manage /index.html with code, and therefore it shouldn't go get it from the static content. Then your code produces nothing, so you are correctly seeing what your code produces.
Try adding this after PrintWriter out = response.getWriter();
out.println(HTML_START);
out.println("Hello World!");
out.println(HTML_END);
This question already has answers here:
How to call servlet through a JSP page
(6 answers)
Closed 6 years ago.
I want to call a servlet latest_products on load of index.jsp page.This servlet has records in List. I want to pass this List<products> to index.jsp. But I don't want to display the name of servlet in url. Is there any way by which I can do this.
Solution 1
Steps to follow:
use jsp:include to call the Servlet from the JSP that will include the response of the Servlet in the JSP at runtime
set the attribute in the request in Servlet and then simply read it in JSP
Sample code:
JSP:
<body>
<jsp:include page="/latest_products.jsp" />
<c:out value="${message }"></c:out>
</body>
Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("message", "hello");
}
EDIT
but i don't want to display the name of servlet in url.
Simply define a different and meaningful url-pattern for the Servlet in the web.xml such as as shown below that look like a JSP page but internally it's a Servlet.
web.xml:
<servlet>
<servlet-name>LatestProductsServlet</servlet-name>
<servlet-class>com.x.y.LatestProductsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LatestProductsServlet</servlet-name>
<url-pattern>/latest_products.jsp</url-pattern>
</servlet-mapping>
Solution 2
Steps to follow:
first call to the the Servlet
process the latest products
set the list in the request attribute
forward the request to the JSP where it can be accessed easily in JSP using JSTL
Sample code:
Servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("message", "hello");
RequestDispatcher view=request.getRequestDispatcher("index.jsp");
view.forward(request,response);
}
index.jsp:
<body>
<c:out value="${message }"></c:out>
</body>
hit the URL: scheme://domain:port/latest_products.jsp that will call the Servlet's doGet() method.
(...) but I don't want to display the name of servlet in url.
You don't need to use the Servlet name at all when accessing to a Servlet. In fact, you can create your servlet to point to the desired URL by defining the right URL pattern:
#WebServlet("/index.jsp")
public class LatestProductServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
List<Product> productList = ...
//all the necessary code to obtain the list of products
//store it as request attribute
request.setAttribute("productList", productLlist);
//forward to the desired view
//this is the real JSP that has the content to display to user
request.getRequestDispatcher("/WEB-INF/index.jsp").forward(request, response);
}
}
Then, you will have a folder structure like this
- <root folder>
- WEB-INF
+ index.jsp
+ web.xml
And in WEB-INF/index.jsp:
<!DOCTYPE html>
<html lang="es">
<body>
<!--
Display the data accordingly.
Basic quick start example
-->
<c:forEach items="${productList}" var="product">
${product.name} <br />
</c:forEach>
</body>
</html>
Note that your clients will access to http://<yourWebServer>:<port>/<yourApplication>/index.jsp and will get the desired content. And you don't need to fire two GET requests to retrieve the content for your specific page.
Note that you can go further with this approach: Since the pattern is now defined in servlet, you may choose to not use index.jsp for your clients, but index.html to access to your page. Just change the URL pattern in the Servlet:
#WebServlet("/index.html")
public class LatestProductServlet extends HttpServlet {
//implementation...
}
And the clients will access to http://<yourWebServer>:<port>/<yourApplication>/index.html, which will show the results in WEB-INF/index.jsp. Now both your clients and you will be happy: clients will get their data and you won't show that ugly servlet name in your URL.
Additional
If you have index.jsp as your welcome page in web.xml, this approach won't work because application servlet expects that a real file index.jsp exists. To solve this issue, just create an empty file named index.jsp:
- <root folder>
- index.jsp <-- fake empty file to trick the application server
- WEB-INF
+ index.jsp
+ web.xml
And when accessing to http://<yourWebServer>:<port>/<yourApplication>/, will work as shown above.
Thanks to +Braj, I am able to make an answer using Expression Language. Apparently, this is supposed to be better than jsp scripting/tags.
Servlet -
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ProductList extends HttpServlet {
private static final long serialVersionUID = 1L;
public ProductList() {
super();
// TODO Auto-generated constructor stub
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
List<String> products = new ArrayList<String>();
products.add("Car");
products.add("Gun");
products.add("Shades");
request.setAttribute("productsList", products);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
JSP -
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<c:import url="/ProductList" />
<c:set var="myProducts" value="${requestScope.productsList}" />
<h1>List of products from servlet</h1>
<c:forEach var="product" items= "${myProducts}" varStatus="i">
${product}<br>
</c:forEach>
</body>
</html>
First, Please suggest me if my question heading is not correct.
Moving on to question:
Say I am having below components:
search.jsp - A JSP Page with a Form to Submit Data
Search.java - A controller Servlet having both get() and post() defined separately so that it can acts as a dispatcher for path /search.jsp
searchResults.jspf - A Fragment with some JSTL code to show up the Search Results
What I want here is for every POST request the controller servlet has to do its calculation, set results as Request Attributes and than - forward the request to the view search.jsp that should include the Fragment after its own codes.
So that, I can have a View Defined in such a way as:
search.jsp
+
searchResults.jspf
on a single page.
Problem is, I can either do Forward or Include with the dispatcher as I don't know how can i Include a fragment while forwarding to a JSP into it.
Let me know if I need to post some code if necessary, or need any corrections.
In your search.jsp embed your searchResult.jsp using jsp:include:
<jsp:include page="searchResult.jsp"></jsp:include>
Exemple:
1. The servlet:
#WebServlet(name = "Servlet", urlPatterns = "/myForwardTest")
public class Servlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("search.jsp").forward(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
search.jsp:
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>In search resust</title>
</head>
<body>
Search.jsp embed searchResult.jsp
<jsp:include page="searchResult.jsp" />
</body>
</html>
searchResult.jsp
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<body>
in searchResult
</body>
</html>
You can include your jspf in your jsp like below:
<%#include file="searchResult.jspf" %>
you can set a statement to execute a certain section only if a particular test evaluates to true .
Ex:
if(.....==true){
<%#include file="searchResult.jspf" %>
}else{
<%#include file="someOther.jspf" %>
}
I tried several solution even here on StackOverflow but none seems to work:
I want to pass a string from a Servlet to a JSP and show it with EL.
I created a simple plain project on Netbeans and this is the code I added:
Servlet Code:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String message = "Hello";
request.setAttribute("message", message);
RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp");
dispatcher.forward(request, response);
}
JSP Code:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
</head>
<body>
<h1>Hello World!</h1>
<h2 style="border: 2px solid brown; width: 20%"> Message is: ${message} </h2>
</body>
</html>
What get me frustated is that even for the documentation (Oracle Api Reference and a HeadFirst O'Reilly Guide) this should be straightforward, but I simply get no text, even if I use a scriptlet. I tried both Glassfish and TomEE
I am more or less certain your problem is that your Servlet is not being invoked. Put a console(System.out.println) output in your Servlet and see if the output is printing.
Do not try to access the JSP page directly. Rather hit the URL mapped for your Servlet.
Your Servlet can be mapped in two ways:
1. Annotation
2. Deployment Descriptor (web.xml)
#WebServlet("/processForm")
public class UploadServlet extends HttpServlet {
// implement servlet doPost() and doGet()...
}
In the case above if you hit /processForm relative to your webapp the UploadServlet will be called and any processing by the Servlet will be carried out and forwarded if dispatcher is used.
A descriptor equivalent is shown below:
<servlet>
<servlet-name>UploadServlet</servlet-name>
<servlet-class>com.bla.bla.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>UploadServlet</servlet-name>
<url-pattern>/processForm</url-pattern>
</servlet-mapping>
Instead of ${message}, try using ${requestScope.message}
(Based on https://stackoverflow.com/a/4912797/1843508)
My application has the following patterns: a FrontController, Command, Service, and DAO.
The problem im having is that I want to display a list of users (and their avatars) on my homepage. How do I get my jsp page to automatically call the ListMembersCommand upon page load without a get/post request?
You don't. What you do is you call the controller and have if forward to the JSP. You never call the JSPs directly themselves.
So, what you end up with is:
request --- invokes ---> Controller --- forwards to ---> JSP
The Controller can fetch whatever is necessary and populate the request appropriately before called the JSP to render it all.
Addenda -
Here is a simple Servlet, mapped to /MyServlet :
public class MyServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
MemberDAO dao = DAOFactory.getMemberDAO();
List<Member> members = dao.getMembers();
request.setAttribute("members", members);
RequestDispatcher rd = getServletContext().getRequestDispatcher("/WEB-INF/jsp/members.jsp");
rd.forward(request, response);
}
}
And here is an associated JSP placed at /WEB-INF/jsp/members.jsp:
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Members List</title>
</head>
<body>
<h1>Members List</h1>
<table>
<tr>
<td>Member ID</td>
<td>First Name</td>
<td>Last Name</td>
</tr>
<c:forEach items="${members}" var="member">
<tr>
<td>${member.id}</td>
<td>${member.firstName}</td>
<td>${member.lastName}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
In your browser, you hit: http://yourhost/yourapp/MyServlet
The servlet, acting as a controller, takes the request, acts on it (in this case getting a list of all of the members from the database using a simple DAO pattern), and then puts the results in to the request with the tag "members" (the request.setAttribute("members", members) does this).
One the request is properly populated with interesting information, the servlet forward to the JSP.
Note in this case the JSP is located below the WEB-INF directory. JSPs located within WEB-INF are NOT accessible at all from the browser. So a request to http://yourhost/yourapp/WEB-INF/jsp/members.jsp will simply fail.
But they are accessible internally.
So, the Servlet forwards to members.jsp, and members.jsp renders, locating the members value from the request (${members} in the JSTL c:forEach tag), and the c:forEach iterates across that list, populating the member variable, and from there filling out the rows in the table.
This is a classic "controller first" pattern which keeps the JSP out of the way. It also helps maintain that the JSPs only live in the View layer of MVC. In this simple example, Member and the List is the model, the Servlet in the Controller, and the JSP is the view.