I got a question about servlets and jsp.
Servlet:
public class Servlet extends javax.servlet.http.HttpServlet {
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
Integer i = new Integer(15);
request.setAttribute("var", i);
RequestDispatcher Dispatcher = getServletContext().getRequestDispatcher("/index.jsp");
Dispatcher.forward(request, response);
}
JSP page:
<html>
<head>
<title></title>
</head>
<body>
<form id="id" method="get" action="servlet">
<%= (request.getAttribute("var")) %>
</form>
</body>
</html>
As a result I expect to see 15, but I see null. Why does it happen?
Request parameters are sent from the view to the controller, request attributes are used to pass data in the current request to help build the new response. So, you should not use scriplets and access to the request attributes by using Expression Language:
<body>
<!-- No need to use a form for this page -->
The request attribute: ${var}
</body>
Note that by your current request, you should perform a GET request on your servlet. Since your servlet name is servlet (which I suggest your to change it immediately), you should access to this URL: http://yourServerName/yourApplicationName/servlet
Use request.getAttribute("var");
I don't know in the servlet but in struts 2 you need getter and setter method to sent data from jsp, you try this:
public class Servlet extends javax.servlet.http.HttpServlet
{
private Integer i;
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
i = new Integer(15);
request.setAttribute("var", i);
RequestDispatcher Dispatcher = getServletContext().getRequestDispatcher("/index.jsp");
Dispatcher.forward(request, response);
}
public Integer getI()
{
return i;
}
public void setI(Integer i)
{
this.i = i;
}
}//also lacked this
Related
I am having trouble retrieving any type of parameter from one jsp page to the other using doPost, and a form where my method is post. Note below is a minimal example.
First, I have two pages:
Here is search.jsp:
<%# taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE html>
<html>
<head>
<title>search</title>
<body>
<form name="search" method="post" action="search_results.jsp">
<p>
<input type="text" class="inputTitle" id="inputTitle" value="${fn:escapeXml(param.inputTitle)}">
<button type="submit">Search</button>
<p>
</form>
</body>
</html>
And my search_results.jsp
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<title>search results</title>
<body>
<p>Title: ${movie.title}</p>
</body>
</html>
Now I have a class called SearchServlet.java:
#WebServlet("/search")
public class SearchServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
HttpSession session = request.getSession();
request.getRequestDispatcher("search.jsp").forward(request,response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
HttpSession session = request.getSession();
String title = request.getParameter("inputTitle");
String searchTitle;
try {
if(title != null && !title.isEmpty()) {
searchTitle = "hello";
} else {
searchTitle = "world";
}
session.setAttribute("movie.title", searchTitle);
request.getRequestDispatcher("search_results.jsp").forward(request, response);
} catch(ServletException e) { e.printStackTrace(); }
}
}
No matter what I enter the result (movie.title) always ends up being empty and so I get world on search_results.jsp. Why is my parameter not being passed to search_results.jsp?
It will not happen if you bypass the servlet
Look at your form action
<form name="search" method="post" action="search_results.jsp">
You are sending the post request directly to the search_results.jsp: you should send it to the servlet instead (mapped # /search)
<form name="search" method="post" action="search">
Then from the servlet you should forward the request to the search_result.jsp, which you actually did.
In addition to that when you call request.getParameter you have to keep in mind that what counts is the name of the input field, not the id. You should change the id attribute to name
<input type="text" class="inputTitle" name="inputTitle" value="${fn:escapeXml(param.inputTitle)}">
Lastly, hopefully :) the '.' (dot) might cause issues:
session.setAttribute("movie.title", searchTitle);
When you retrieve the attribute the dot notation indicates that you are accessing a field in a object called movie
<p>Title: ${movie.title}</p> <!-- you are accessing the title property of a movie object !-->
but you do not have that...you have a movietitle, a String presumably. Change the attribute name to something like movietitle without the dot and retrieve it in the jsp the same way. the above lines will become:
session.setAttribute("movietitle", searchTitle);
<p>Title: ${movietitle}</p>
That should solve the issue.
I was trying to forward from doPost to doGet of the ControllerServlet urlPattern = "/remove_person", so I can re-update findAll query inside my doGet method of the ControllerServlet class, and then forward to remove_person.jsp from doGet method, but AS-WEB-CORE-00089 exception is thrown
WARNING: StandardWrapperValve[ControllerServlet]: Servlet.service() for servlet ControllerServlet threw exception
javax.servlet.ServletException: AS-WEB-CORE-00089
at org.apache.catalina.core.ApplicationDispatcher.doInvoke(ApplicationDispatcher.java:863)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:739)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:575)
at org.apache.catalina.core.ApplicationDispatcher.doDispatch(ApplicationDispatcher.java:546)
at org.apache.catalina.core.ApplicationDispatcher.dispatch(ApplicationDispatcher.java:428)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:378)
at server.ControllerServlet.doPost(ControllerServlet.java:130)
where ControllerServlet.java:130 line is in doPost() method:
request.getRequestDispatcher(url).forward(request, response);
Here is the code of servlet class:
#WebServlet(
name = "ControllerServlet",
loadOnStartup = 1,
urlPatterns = {
"/index",
"/search_person",
"/add_person",
"/remove_person"})
public class ControllerServlet extends HttpServlet {
#PersistenceUnit
private EntityManagerFactory emf;
#Resource
private UserTransaction utx;
private EntityManager em;
#Override
public void init() throws ServletException {
assert emf != null;
em = emf.createEntityManager();
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String servletPath = request.getServletPath();
if (servletPath.equals("/index")) {
}
else if (servletPath.equals("/search_person")) {
List persons = em.createNamedQuery("Person.findAll").getResultList();
request.setAttribute("findByNameAndYearBirth", persons);
}
else if (servletPath.equals("/add_person")) {
}
else if (servletPath.equals("/remove_person")) {
List persons = em.createNamedQuery("Person.findAll").getResultList();
request.setAttribute("findAll", persons);
}
String url = servletPath + ".jsp";
request.getRequestDispatcher(url).forward(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String servletPath = request.getServletPath();
if (servletPath.equals("/index")) {
}
else if (servletPath.equals("/search_person")) {
String name = request.getParameter("name");
String yearBirth = request.getParameter("yearBirth");
Query query = em.createNamedQuery("Person.findAll");
if (!name.isEmpty() && !yearBirth.isEmpty()) {
query = em.createNamedQuery("Person.findByNameAndYearBirth");
query.setParameter("name", name);
query.setParameter("yearBirth", Short.parseShort(yearBirth));
}
else if (!name.isEmpty()) {
query = em.createNamedQuery("Person.findByModel");
query.setParameter("name", name);
}
else if (!yearBirth.isEmpty()) {
try {
Short sYearBirth = Short.parseShort(yearBirth);
query = em.createNamedQuery("Person.findByYearBirth");
query.setParameter("yearBirth", sYearBirth);
} catch (NumberFormatException nfe) {}
}
List persons = query.getResultList();
request.setAttribute("findByNameAndYearBirth", persons);
}
else if (servletPath.equals("/add_person")) {
String name = request.getParameter("name");
String hobby = request.getParameter("hobby");
String yearBirth = request.getParameter("yearBirth");
int personsLen = em.createNamedQuery("Person.findAll").getResultList().size();
Person newPerson = new Person(
++personsLen, name, hobby, Short.parseShort(yearBirth)
);
try {
utx.begin();
em = emf.createEntityManager();
em.persist(newPerson);
utx.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
else if (servletPath.equals("/remove_person")) {
String id = request.getParameter("id");
Person person = null;
try {
utx.begin();
person = em.find(Person.class, Integer.parseInt(id));
em.remove(person);
utx.commit();
} catch (Exception e) {
e.printStackTrace();
}
servletPath = "/remove_person";
}
String url = servletPath;
request.getRequestDispatcher(url).forward(request, response);
}
}
Problem is, my line inside doPost method
String url = path;
does not contain a ".jsp" part.
But if I add ".jsp" part to a string url, then how I will update findAll query data inside remove_person.jsp if i don't go to servlet doGet first to collect new data after adding or deleting entities?
remove_person.jsp
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>Remove Person</h1>
<form action="remove_person" method="post">
<table border="3">
<tr>
<th>ID</th>
<th>Name</th>
</tr>
<c:forEach var="person" begin="0" items="${findAll}">
<tr>
<td>${person.id}</td>
<td>${person.name}</td>
</tr>
</c:forEach>
</table>
<strong>Remove person: </strong>
<select name="id">
<c:forEach var="person" items="${findAll}">
<option value="${person.id}">${person.id}. ${person.name} </option>
</c:forEach>
</select>
<input type="submit" id="remove_person" value="Remove" />
</form>
<br>
Home page
</body>
</html>
Actually, is it even possible to forward from doPost to doGet method of the same servlet ? The reason I was trying to do this is because, inside doGet I already use this code:
List persons = em.createNamedQuery("Person.findAll").getResultList();
request.setAttribute("findAll", persons);
So why should I duplicate this code inside doPost method, when I can forward from doPost to doGet method and invoke that code?
UPDATE:
Bad approach:
String url = servletPath;
request.getRequestDispatcher(url).forward(request, response);
Correct approach:
String url = request.getContextPath() + servletPath;
response.sendRedirect(url);
Use redirect instead of forward. The pattern (called Post/Redirect/Get) is:
1) the client calls the post url, which does your update
2) the servlet sends a redirect to the client with the url for the get.
3) the client calls the url from the redirect.
When the response from the GET comes back the browser has the GET url, so the browser ends up with a url that's bookmarkable. Also this way the user can't repost the same data by hitting f5 or clicking multiple times.
For when to use forward vs redirect see this advice:
Forward
a forward is performed internally by the servlet
the browser is completely unaware that it has taken place, so its original URL remains intact
any browser reload of the resulting page will simple repeat the original request, with the original URL
Redirect
a redirect is a two step process, where the web application instructs the browser to fetch a second URL, which differs from the
original
a browser reload of the second URL will not repeat the original request, but will rather fetch the second URL
redirect is marginally slower than a forward, since it requires two browser requests, not one
objects placed in the original request scope are not available to the second request
In general, a forward should be used if the operation can be safely repeated upon a browser reload of the resulting web page; otherwise, redirect must be used. Typically, if the operation performs an edit on the datastore, then a redirect, not a forward, is required. This is simply to avoid the possibility of inadvertently duplicating an edit to the database.
I have the following problem. First of all, I'm send request from jsp to servlet, then I'm doing some operation, and put some data to request, and forward to the same page for rendering new data. But after forwarding, my jsp page doesn't update. Can anyone say me, what I'm doing wrong?
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>File Viewer</title>
<link href="${pageContext.request.contextPath}/resources/css/bootstrap.min.css" rel="stylesheet">
<script src="${pageContext.request.contextPath}/resources/js/bootstrap.min.js"> </script>
<script src="${pageContext.request.contextPath}/resources/js/jquery-1.8.0.min.js"> </script>
<script type="text/javascript">
function showFolderRequest(fileName) {
$.post( "ftp?fileName="+fileName, function( data ) {
});
}
</script>
</head>
<body>
<div class="container-fluid">
<div class="col-md-9 list-group" style="float: none; margin: 20px auto;">
<div class="list-group-item active" style="background-color: darkcyan;">
Ftp server: /
</div>
<c:forEach items="${requestScope.files}" var="fileEntity">
<p class="list-group-item" onclick="showFolderRequest('${fileEntity.name}')">
${fileEntity.name}
</p>
</c:forEach>
</div>
</div>
</body>
</html>
This is my servlet
#WebServlet("/ftp")
public class FileServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
FileManager fileManager = FileManager.getInstance();
String requestedFileName = req.getParameter("fileName");
req.setAttribute("files", fileManager.getAllFilesByPath(requestedFileName));
getServletContext().getRequestDispatcher("/test.jsp").forward(req, resp);
}
}
The problem is that you're firing an ajax request. When handling ajax requests, you need to be aware of some things:
You cannot forward not redirect from your servlet. This is an asynchronous request from the browser and it won't get any content from a forwarding or redirection from the server.
Expression Language (those things inside ${}) and JSP tags like JSTL run on server side when processing the JSP and rendering the HTML. Any ajax request wont update any EL nor any JSP tag content since this code it is not run on server. So, any new attribute you set here won't matter until you fire a non-ajax request.
The only way you can get any data from the server is by writing a response that contains the desired data. Usually, you would write a JSON response, but you can even write an XML or a plain text response, it will depend on your design. Then, in the browser side (Javascript), you handle the data from the response and display some text, update values in your current HTML, and on.
From this case, you can write a list of the desired files into a JSON string and write that string in the server response, then manage it accordingly in client side. This is just a bare example of how to achieve it using Jackson library to convert Java code into JSON string.
In servlet:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
FileManager fileManager = FileManager.getInstance();
String requestedFileName = req.getParameter("fileName");
//not really sure what retrieves, I'm assuming it is a Lis<FileEntity>
//edit this accordingly to your case
List<FileEntity> files = fileManager.getAllFilesByPath(requestedFileName);
String json = new ObjectMapper().writeValueAsString(files);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}
In JavaScript:
<script type="text/javascript">
function showFolderRequest(fileName) {
$.post( "ftp?fileName="+fileName, function( data ) {
//logs the whole JSON string response into browser console
//supported in Chrome and Firefox+Firebug
console.log(data);
//parsing the JSON response
var files = JSON && JSON.parse(data) || $.parseJSON(data);
//since it is an array, you need to traverse the values
for (var fileEntity in files) {
//just logging the files names
console.log(fileEntity.name);
}
});
}
</script>
I've got a jsp file:
... import <%# page import="classPath.ExampleClass" %>
<%
ExampleClass cl = new ExampleClass(request);
%>
The Code of ExampleClass (Java):
private HttpServletRequest req;
public ExampleClass(HttpServletRequest req) {
this.req = req;
}
So I want to receive the complete request to evaluate it in Java. But during deploying the following error appears:
Cannot process HttpRequest to Servlet
Why?
Do not messup.Use of implicit objects of JSP
JSP Implicit Objects are the Java objects that the JSP Container makes available to developers in each page and developer can call them directly without being explicitly declared. JSP Implicit Objects are also called pre-defined variables.
just write
<%
ExampleClass cl = new ExampleClass(request);
%>
Create bean class like.
public class ExampleClass{
HttpServletRequest request;
public HttpServletRequest getRequest() {
return request;
}
public void setRequest(HttpServletRequest request) {
this.request = request;
}
}
Now pass implicit request object with jsp tag
<jsp:useBean id="exampleClass" class="classPath.ExampleClass" scope="request"/>
<jsp:setProperty name="exampleClass" property="request" value="${pageContext.request}"/>
In your jsp add the following directive:
<jsp:useBean id="bean" class="classPath.ExampleClass" scope="request">
<jsp:setProperty name="bean" property="*" />
<jsp:setProperty name="bean" property="request" value="${pageContext.request}" />
</jsp:useBean>
The property "*" means that all attributes coming from the request will be set on the bean (class) e.g. form submission with various input fields.
The property "request" will set the HttpServletRequest as the last parameter so this method can be used as an indicator to start your logic.
Your class could look like:
public class ExampleClass {
private HttpServletRequest request;
private String fieldValue;
public void doLogic() {
// do your controller logic here
}
public HttpServletRequest getRequest() {
return request;
}
public String getFieldValue() {
return fieldValue;
}
public void setRequest(HttpServletRequest request) {
this.request = request;
doLogic();
}
public void setFieldValue(String fieldValue) {
this.fieldValue = fieldValue;
}
}
Notice that the property fieldValue is a custom field that you can add and can be set via form submission as mentioned above:
<form method="post">
<input name="feildValue" type="text" value="${bean.fieldValue}"/>
<input name="btnSubmit" type="submit" value="Submit"/>
</form>
This question already has answers here:
Passing an object from JSP page back to Servlet
(3 answers)
Closed 1 year ago.
How to pass an Object from the servlet to the calling JSP.
I have a JSP calling a servlet. From this servlet, I am setting the properties of a viewBean.
Now, I want to get this property valued set from Servlet on a JSP page.
How to make this ViewBean object available on JSP from Servlet.
Put the object either in session or request in servlet like :
String shared = "shared";
request.setAttribute("sharedId", shared); // add to request
request.getSession().setAttribute("sharedId", shared); // add to session
this.getServletConfig().getServletContext().setAttribute("sharedId", shared); // add to application context
You can read it in jsp like :
<%# taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<body>
<cut value= "${shared}"/>
<cut value= "${requestScope.shared}"/>
<cut value= "${requestScope.request.shared}"/>
${shared}
Or read it using scriptlet with code :
<%
String shared = (String)request.getAttribute("sharedId");
String shared1 = (String)request.getSession().getAttribute("sharedId");
String shared2 = (String)this.getServletConfig().getServletContext().getAttribute("sharedId");
%>
Well, firstly you need to set the value so you can access it from your page, something like:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
// Do some work.
Person value = new Person("Matthew", "Abbott";
request.setAttribute("person", person);
// Forward to to the JSP file.
request.getRequestDispatcher("showValue.jsp").forward(request, response);
}
}
Next thing, you can access the properties of your value, using Expression Language:
<!DOCTYPE html>
<html>
<head>
<title>${person.forename} ${person.surname}</title>
</head>
<body>
<h1>Hello ${person.forename}!!!</h2>
</body>
</html>
Something like this should work
request.setParameter("nameOfmyObjectParam",MyObject); //or request.setAttribute
String yourJSP = "/WEB-INF/pages/yourJSP.jsp";
RequestDispatcher rd = getServletContext().getRequestDispatcher(yourJSP);
rd.forward(request, response);
Set the bean as request attribute in servlet using the Servlet API as follows -
request.setAttribute("viewBean", viewBean);
and retrieve (use) it in the JSP using EL as follows -
${requestScope.viewBean}
Add that ViewBean object in session attribute in servlet. And get that variable in jsp.
in servlet
ViewBean viewbwanObject= new ViewBean()
session.setAttribyte("obj",vi);
in jsp.
<%
ViewBean v= (ViewBean)session.getAttribute("obj")
%>