I have a web form in a jsp that is supposed to get values from a servlet, but it is printing out null values. I am including the code for the jsp and for the servlet below. Can anyone show me how to fix the code below so that it prints out the values from the request object instead of printing null?
Here is the code for my.jsp:
<jsp:useBean id="errors" scope="request" type="java.util.Map" class="java.util.HashMap" />
<form method="post">
<table>
<tr>
<td width=302>
</td>
<td width=250>
<table>
<tr>
<td width=150 align="right">tha: </td>
<td><input type="text" name="tha" value="c3t" size="15" />
<%if (errors.containsKey("tha")) {out.println("<span class=\"error\">" + errors.get("tha") + "</span>");}
else{out.println(request.getParameter("tha"));}%>
</td>
</tr>
<tr>
<td width=150 align="right">min: </td>
<td><input type="text" name="min" value="0" size="15" />
<% if (errors.containsKey("min")) {out.println("<span class=\"error\">" + errors.get("min") + "</span>");}
else{out.println(request.getParameter("min"));}%>
</td>
</tr>
<tr>
<td width=150 align="right">max: </td>
<td><input type="text" name="max" value="2*pi" size="15" />
<% if (errors.containsKey("max")) {out.println("<span class=\"error\">" + errors.get("max") + "</span>");}
else{out.println(request.getParameter("max"));}%>
</td>
</tr>
<tr>
<td></td>
<td align="right">
<input type="submit" name="submit-button" value="Click To Plot" />
</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
And here is the code for the servlet:
public class PlotPolarServlet extends HttpServlet{
private RequestDispatcher jsp;
public void init(ServletConfig config) throws ServletException {
ServletContext context = config.getServletContext();
jsp = context.getRequestDispatcher("/WEB-INF/jsp/my.jsp");
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
jsp.forward(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException{
Map<String, String> errors = validate(req);
if (!errors.isEmpty()){
jsp.forward(req, resp);
return;
}
resp.sendRedirect("my");
}
public static Map<String, String> validate(HttpServletRequest req){
HashMap<String, String> errors = new HashMap<String, String>();
req.setAttribute("errors", errors);
String tha = req.getParameter("tha");
if (tha == null || tha.trim().length() == 0){
errors.put("tha", "tha required.");
}
String min = req.getParameter("min");
if (min == null || min.trim().length() == 0){
errors.put("min", "min required.");
}
String max = req.getParameter("max");
if (max == null || max.trim().length() == 0){
errors.put("max", "max required.");
}
return errors;
}
}
I originally misread your question. The issue is when parameters are input correctly, not when there is an error. The else part of this code
<% if (errors.containsKey("min")) {out.println("<span class=\"error\">" + errors.get("min") + "</span>");}
else{out.println(request.getParameter("min"));}%>
can't print anything but null because, in this request, there are no parameters with those keys.
A HttpServletResponse#sendRedirect(String) returns a 302 HTTP status code which would make your browser send a new HTTP request to the location described by the String parameter. The request parameters would not be in the new request (the request context/scope is cleared once the request is handled). You would need to put them in the session attributes.
/*
for every parameter, put it in the session attributes
*/
req.getSession(true).setAttribute("myParam", req.getParameter("myParam"));
resp.sendRedirect("my");
This is known as flash scope and flash attributes and it can be implemented as explained here with a servlet Filter. You basically store attributes you want to reuse between 2 requests, then delete them.
As for Edit:
Unless you've copy-pasted the code in your edit incorrectly
<td><input type="text" name="yX" value="cx" size="15" />
<%if (errors.containsKey("yX")) { // errors doesn't contain yX as a Key, it contains imageParam1
out.println("<span class=\"error\">" + errors.get("yX") + "</span>");
}else{out.println(request.getParameter("yX"));}%> // will print the value of the request parameter with key yX
</td>
you're POSTing a parameter called yX, but looking for imageParam. Your doPost() method will create an errors request attribute and then forward (instead of sendRedirect).
errors.put("imageParam1", "imageParam1 required.");
...
if (!errors.isEmpty()){
jsp.forward(req, resp);
return;
}
not yX. Therefore, the else gets evaluated and the parameter exists since it's the same request.
MORE EXPLANATION
In your my example:
If you didn't enter a required field, the doPost() method gets called, the errors map is populated and your code does jsp.forward(req, resp); which uses the same request and the parameters are available when the jsp is rendered.
If you entered all the required fields, the doPost() is called and resp.sendRedirect("my"); is executed. This causes your browser to send a new GET HTTP request with new parameters/attributes. This causes the doGet() to be called to process the new request, which forwards to your jsp. The original request parameters aren't included in this request so there is nothing to show, thus null when else{out.println(request.getParameter("min")); gets rendered.
In your myother example, because of the difference between the <input> parameter name in the jsp and the parameter name you're looking for in the servlet, you're getting completely irrelevant results which I've explained above. Disregard this servlet. It is not doing what you thought it was doing correctly.
Related
I'm trying to send a variable from my JSP to my Servlet using the post method. However, the value is continually returning null. I've put in prints and another type of hidden input to check for other errors, but it's just that the inputs are null in the servlet. Why is this?
JSP: (this code is within a table)
<c:set var="counter" value="0"/>
<tbody>
<form id="myForm" action="feedingSchedules" method="post">
<c:forEach var="schedule" items="${feeding_schedules}">
<tr>
<td><c:out value="${schedule.schedule_ID}" /></td>
<td><c:out value="${schedule.feeding_time}" /></td>
<td><c:out value="${schedule.recurrence}" /></td>
<td><c:out value="${schedule.notes}" /></td>
<td><c:out value="${schedule.food}" /></td>
<td><c:out value="${schedule.animalID}" /></td>
<td><button id="myButton" class="btn-danger-stale" name="btn${counter}" value="val${counter}">Delete Schedule</button></td>
<c:set var="counter" value="${counter + 1}"/>
<c:out value="${counter }"/>
</tr>
</c:forEach>
<c:out value="${counter }"/>
<input type="hidden" name="hi" id="hi" value="hi"/>
<input type="hidden" name="numSchedules" id="numSchedules" value="${counter}"/>
</form>
</tbody>
</table>
<script type="text/javascript">
var form = document.getElementById("myForm");
document.getElementById("myButton").addEventListener("click", function () {
form.submit();
});
</script>
Servlet: ('test' variable is null; code crashes at 'count' declaration because parseInt can't parse a null value)
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
FeedingScheduleDAO dao = DAOUtilities.getFeedingScheduleDao();
List<FeedingSchedule> schedules = dao.getAllSchedules();
//Get Parameters
System.out.println("got here");
String test = request.getParameter("hi");
System.out.println(test);
int count = Integer.parseInt(request.getParameter("numSchedules"));
for(int i = 0; i < count; i++) {
String btn = null;
btn = request.getParameter("btn" + i);
if(btn == ("val" + i)) {
System.out.println("got here");
// call delete method from DAO
try {
dao.deleteSchedule(schedules.get(i));
request.getSession().setAttribute("message", "Schedule successfully deleted");
request.getSession().setAttribute("messageClass", "alert-success");
response.sendRedirect("feedingSchedules");
} catch (Exception e) {
e.printStackTrace();
request.getSession().setAttribute("message", "There was a problem deleting the schedule at this time");
request.getSession().setAttribute("messageClass", "alert-danger");
request.getRequestDispatcher("feedingScheduleHome.jsp").forward(request, response);
}
}
}
}
You can try debugging the code by making the form method=GET. This will help you to know the values that are going to Servlet. Then you can just check the URL to see if the data is there or not. Try this if you cannot see the data in the url that means that the form submit is not working properly.
This question already has answers here:
How do I call a specific Java method on a click/submit event of a specific button in JSP?
(4 answers)
How do I pass current item to Java method by clicking a hyperlink or button in JSP page?
(1 answer)
Closed 3 years ago.
The code below is from the jsp file.
<table class="table table-striped table-hover table-responsive ezoo-datatable">
<thead>
<tr>
<th class="text-center">Schedule ID</th>
<th class="text-center">Feeding Time</th>
<th class="text-center">Recurrence</th>
<th class="text-center">Notes</th>
<th class="text-center">Food</th>
<th class="text-center">Animal ID</th>
<th></th>
</tr>
</thead>
<% int counter = 0; %>
<tbody>
<form action="feedingSchedules" method="post">
<c:forEach var="schedule" items="${feeding_schedules}">
<tr>
<td><c:out value="${schedule.schedule_ID}" /></td>
<td><c:out value="${schedule.feeding_time}" /></td>
<td><c:out value="${schedule.recurrence}" /></td>
<td><c:out value="${schedule.notes}" /></td>
<td><c:out value="${schedule.food}" /></td>
<td><c:out value="${schedule.animalID}" /></td>
<td><button class="btn-danger-stale" name="btn${counter}" value="val${counter}">Delete Schedule</button></td>
<% counter++; %>
</tr>
</c:forEach>
<input type="hidden" name="numSchedules" value="${counter}"/>
</form>
</tbody>
</table>
This code builds a table of data. I have a servlet to populate the table by fetching data from a database in a call to a dao method. I need to add buttons to the table to delete the row corresponding to the button. I have the buttons in place, but I'm not sure how to get them to perform the actual deletion.
#WebServlet(description = "This servlet is the main interface into the Feeding Schedules System", urlPatterns = { "/feedingSchedules" })
public class FeedingSchedulesServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Grab a list of Animals from the Database
FeedingScheduleDAO dao = DAOUtilities.getFeedingScheduleDao();
List<FeedingSchedule> schedules = dao.getAllSchedules();
// Populate the list into a variable that will be stored in the session
request.getSession().setAttribute("feeding_schedules", schedules);
request.getRequestDispatcher("feedingScheduleHome.jsp").forward(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
FeedingScheduleDAO dao = DAOUtilities.getFeedingScheduleDao();
List<FeedingSchedule> schedules = dao.getAllSchedules();
//Get Parameters
System.out.println("got here");
int count = Integer.parseInt(request.getParameter("numSchedules"));
for(int i = 0; i < count; i++) {
String btn = null;
btn = request.getParameter("btn" + i);
if(btn == ("val" + i)) {
System.out.println("got here");
// call delete method from DAO
try {
dao.deleteSchedule(schedules.get(i));
request.getSession().setAttribute("message", "Schedule successfully deleted");
request.getSession().setAttribute("messageClass", "alert-success");
response.sendRedirect("feedingSchedules");
} catch (Exception e) {
e.printStackTrace();
request.getSession().setAttribute("message", "There was a problem deleting the schedule at this time");
request.getSession().setAttribute("messageClass", "alert-danger");
request.getRequestDispatcher("feedingScheduleHome.jsp").forward(request, response);
}
}
}
}
}
The above code is the servlet. The print lines I put in the overridden doPost method do not show in the console when I click the buttons, so I do not believe the method is being called properly. Does anyone know what I'm doing wrong? I've spent a few hours staring at this and could use some fresh eyes.
Assign an id to your form e.g.
<form id="myForm" action="feedingSchedules" method="post">
And replace
<button class="btn-danger-stale" name="btn${counter}" value="val${counter}">Delete Schedule</button>
with
<button class="btn-danger-stale" name="btn${counter}" value="val${counter}" onclick="document.getElementById('myForm').submit();">Delete Schedule</button>
Alternatively,
Assign an id to your form as mentioned above and also to your button as mentioned below:
<button id="myButton" class="btn-danger-stale" name="btn${counter}" value="val${counter}">Delete Schedule</button>
and add the following javascript in your jsp file:
var form = document.getElementById("myForm");
document.getElementById("myButton").addEventListener("click", function () {
form.submit();
});
I use a html page with a textfield where you have to enter your name and then click on a login button.
On the same page is a list with all names.
Now I have to send the name by clicking on the login button to a servlet. The servlet have to add the name into the playerlist.
The servlet already receives the entered name but it post it on hole new HTML page. How do I have to change the code so that name will be added to playerlist on the same HTML page not on new page?
#WebServlet("/Playerlist")
public class Playerlist extends HttpServlet {
private static final long serialVersionUID = 1L;
public Playerlist() {
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
PrintWriter out = response.getWriter();
out.println("<html><Body>Hallo" + name + "</body></html>");
out.flush();
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
Textfield:
<div id= "loginFormular" >
<form action="Playerlist" method="get" >
<label>
Name:
<input class="textbox" id="loginbox" type="text" name="name" size="30" maxlength="30">
</label>
<br>
<input id=buttonLogin class="loginbutton" type="submit" value="Login" name="loginname" />
<input id=startButton class="loginbutton" type="submit" value="Start" onclick="showQuestion()" />
</form>
</div>
Playerlist:
<div class="highscore" style="float:right">
<h4>
<span class="glyphicon glyphicon-star" aria-hidden="true"></span>
<span>Highscore</span>
</h4>
<hr/>
<table id="highscoreTable" class="table table-hover">
<thead>
<tr>
<td>Player</td>
<td>Score</td>
</tr>
</thead>
<tbody id="tablePlayerlistBody">
</tbody>
</table>
</div>
I konw there are better ways instead of using a servlet, but I have to it this way.
Your page is too static for what you want to do. I am assuming that you are doing this for practice.
What you are doing is
submitting your name from a static page.
Getting the submitted name on servlet side.
Sending new content to client.
Instead what you need to do is
Create a dynamic page (JSP) with a text field and list.
Submit the field value to servlet.
Receive the value and persist it on server side. Maintain some type of list on server side and add this value to it and set it on either of the servlet contexts.
redirect to the same page using request dispatcher and then iterate over the list of values maintained on server side.
Something as below.
Servlet
String name = request.getParameter("name");
serverSideList.add(name );
JSP
<table id="highscoreTable" class="table table-hover">
<thead>
<tr>
<td>Player</td>
<td>Score</td>
</tr>
</thead>
<tbody id="tablePlayerlistBody">
<% for(int i=0 ; i< serverSideList.size(); i++){ %>
<tr>
<td>
<%=serverSideList.get(i)%>
</td>
<td>Some Score</td>
</tr>
<%}%>
</tbody>
</table>
For persisting you can do two things.
Simple : Maintain server side list in Application Context
Standard : Persist player detail in database.
Please feel free to ask if you have any questions.
I'm trying to link the register information to database mysql. Everything work fine when i exported the data to the text file but when trying to connect with database, it always get this error. Here is my code I have try so far:
Register.jsp:
enter code here
<form action="./Data">
<table>
<tr>
<td> Username </td>
<td><input type ="text" name="uname" size="30"required></td>
</tr>
<tr>
<td>Your email address </td>
<td><input type ="text" name="mail" size="30"></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="pass" size="20"required></td>
</tr>
<tr>
<td>Please re-type your password</td>
<td><input type="password" name="p2" size="20"required></td>
</tr>
<table>
<tr>
<td>Date of Birth</td>
<td><select name="Type">
<%for(int i=1;i<=31;i++) {%>
<option><%=i%></option>
<%}%>
</select></td>
<td>
<select name="Type">
<option>January</option>
<option>February</option>
<option>March</option>
<option>April</option>
<option>May</option>
<option>June</option>
<option>July</option>
<option>August</option>
<option>September</option>
<option>October</option>
<option>November</option>
<option>December</option>
</select>
</td>
<td>
<select name="Type">
<% for (int j=1970;j<=2010;j++) {%>
<option><%=j%></option>
<%}%>
</select>
</td>
<tr>
<td>Gender</td>
<td><input type ="radio" value="r1" checked name="Gender">Male</td>
<td><input type ="radio" value="r2" checked name="Gender">Female</td>
</tr>
<tr>
<td>
</tr>
<tr>
<td><input type="submit" value="Register" name="s4"></td>
<td><input type="reset" value="Reset" name="s5"></td>
</tr>
</table>
</form>
enter code here
Data.java:
enter code here
#WebServlet(urlPatterns = {"/Data"})
public class Data extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException, SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String user = request.getParameter("uname");
String pass = request.getParameter("pass");
String email = request.getParameter("mail");
String gender = request.getParameter("Gender");
String end = ("----------------------");
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
String connectionURL = "jdbc:mysql://localhost:8084/userinfo";
Connection con = DriverManager.getConnection(connectionURL,"root","");
Statement st = con.createStatement();
ResultSet rs;
int i = st.executeUpdate("insert into userinfo (Username, email, password) values('" + user + "','" + pass + "','" + email + "')");
if (i > 0) {
response.sendRedirect("welcome.jsp");
out.print("Registration Successfull!"+"<a href='index.jsp'>Go to Login</a>");
} else {
response.sendRedirect("index.jsp");
}
response.sendRedirect("welcome.jsp");
}
}
Your Data class extends HttpServlet which implements the doGet() method.
When the Servlet container receives any request, it will call your Servlet's service() method. In this case, that is the inherited HttpServlet#service() method which calls the HttpServlet#doGet() method. Since you haven't implemented that method, your class inherits it. In the HttpServlet class, it is implemented like so
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
}
Therefore, when you send a GET request, this method will be invoked and you will get the 405 response code.
Implement your own doGet() which delegates to processRequest.
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
processRequest(req, resp);
}
I created a simple servlet which was printing some message like this:
#WebServlet("/servletExample")
public class ServletExample extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("Hello there");
}
Everything worked well.
Then i created 2 jsp pages like this:
<body>
<form method="post" action="servletExample">
<table border="0">
<tr>
<td>
First name:
</td>
<td>
<input type="text" name="firstname"/>
</td>
</tr>
<tr>
<td>
Last name:
</td>
<td>
<input type="text" name="lastname"/>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit"/>
</td>
</tr>
</table>
</form>
</body>
and
<body>
<%
String firstName = (String)request.getAttribute("firstname");
String lastName = (String)request.getAttribute("lastname");
out.println(firstName+ " "+lastName);
%>
</body>
The servlet looks like this now:
#WebServlet("/servletExample")
public class ServletExample extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String firstName=request.getParameter("firstname");
String lastName=request.getParameter("lastname");
if(firstName == null || lastName==null){
getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);
return;
}
request.setAttribute("firstname", firstName);
request.setAttribute("lastname", lastName);
getServletContext().getRequestDispatcher("/output.jsp").forward(request, response);
}
}
When i run it i see that form but when i submit i see "Hello there" from the example i did 2 days ago. Whatever i do i see that.
What do i have to clean?
What am i missing?
Edit: I use eclipse and tomcat 7
Assuming you are in Eclipse, stop your Tomcat server, select your project, in Eclipse's menu select Project and Clean and then Build Project. Then restart your Tomcat server and try again.
Eclipse uses the last built project version with Tomcat every time you run. You need to clean up the project and rebuild it for Eclipse and Tomcat to refresh the changes.