JSTL foreach hidden input submits a null value - java

I'm doing a small JEE5 application similar to an online shop and I need to show the shop products, it can be seen more clearly in the code:
<c:forEach var="product" items="${productsBean.products}">
<div class ="product">
<table>
<td>
<c:out value="${product.id}"/>
</td>
<td>
<c:out value="${product.name}"/>
</td>
<td>
<c:out value="${product.price}"/>
</td>
<td>
<c:out value="${product.description}"/>
</td>
<td>
<form method="post" action="/servlets-war/AddToCart">
<input type="hidden" name="id" value="${product.id}"></input>
<input type="submit" value="add to cart"/>
</form>
</td>
</table>
</div>
</c:forEach>
The problem is that the hidden input value in the form returns null instead of the ${product.id} when the form is submitted.
The associated servlet code is the next:
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
ShoppingCart shoppingCart = (ShoppingCart)request.getSession()
.getAttribute("shoppingCart");
if(shoppingCart == null){
shoppingCart = new ShoppingCart();
}
ProductsBean store =(ProductsBean) request
.getSession().getAttribute("productsBean");
int id = Integer.parseInt((String)request.getAttribute("id"));
Product temp = store.getProduct(id);
shoppingCart.getProducts().add(temp);
request.getSession().setAttribute("shoppingCart", shoppingCart);
this.getServletContext().getRequestDispatcher("/shop.jsp")
.forward(request, response);
}

You are retrieving the id as a request attribute.
int id = Integer.parseInt((String)request.getAttribute("id"));
Form input is sent to the servlet as a request parameter. Change your code appropriately:
int id = Integer.parseInt((String)request.getParameter("id"));

Related

why is my form not passing information in spring boot

Hello i am passing information in a form and everything runs fine but when i fill out the form it doesnt not pass the information and i am getting this error.
There was an unexpected error (type=Internal Server Error, status=500).
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
Caused by: java.sql.SQLIntegrityConstraintViolationException: Column 'movie_id' cannot be null
the code i am using is as folow:
#PostMapping("/save")
public String save(Movie movie) {
savedMovie.save(movie);
return "redirect:/LatestMovies";
}
And
<form th:action="#{/save}" method="post" >
<p><input type="text" id="movie_id" name="movie_id" value="" /></p>
<p><input type="text" id="movie_name" name="movie_name" value="" /></p>
<p><input type="submit" value="save" /></p>
</form>
i belive all other code is correct becuase if i try to render the db information i have no problem.
Update
This is the complete html code.
<div class="container">
<table class="table table-hover">
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<tr th:each="LatestMovies : ${latestMovies}">
<td th:text="${LatestMovies.id}"></td>
<td th:text="${LatestMovies.movieName}"></td>
<td>
<form th:action="#{/save}" method="post" th:object="${newMovie}">
<p><input type="text" id="movie_id" th:field="*{movie_Id}"/></p>
<p><input type="text" id="movie_name" th:field="*{movie_Name}"/></p>
<p><input type="submit" value="save" /></p>
</form>
</td>
</tr>
</table>
Your controller is expecting a Movie object, but it is receiving something else, which then produces a null Movie object. You need to use th:object in your form in order to correctly send the respective class. First, let's add a new #ModelAttribute to your controller, so that your form can automatically map your Movie object in your form.
Controller
// In order to use th:object in a form, we must be able to map a new entity to that form.
// In this case we return a Movie entity.
#ModelAttribute(value = "newMovie")
public Movie newMovie() {return new Movie();}
Now, let's change your form, so that it actually sends a Movie object.
<form th:action="#{/save}" method="post" th:object="${newMovie}">
<p><input type="text" id="movie_id" th:field="*{movie_id}"/></p>
<p><input type="text" id="movie_name" th:field="*{movie_name}"/></p>
<p><input type="submit" value="save" /></p>
</form>
Note that I also changed the name attribute in your inputs, for th:field. Have in mind that in order for this to work, the name of each field must match exactly the names in your objects.
Update
In case you want to set a default value to your form, without using js and since you can't combine th:field with th:value, you could set the object's attribute in your controller.
#ModelAttribute(value = "newMovie")
public Movie newMovie() {
Movie movie = new Movie();
movie.setName("Test");
return movie;
}
Update 2
If what you want is to put the current iteration of a Thymeleaf list in your form, you can do the following.
<div class="container">
<table class="table table-hover">
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<tr th:each="LatestMovies : ${latestMovies}">
<td th:text="${LatestMovies.id}"></td>
<td th:text="${LatestMovies.movieName}"></td>
<td>
<form th:action="#{/save}" th:object="${LatestMovies}" method="post">
<p><input type="hidden" th:value="*{id}"/></p>
<p><input type="hidden" th:value="*{movieName}"/></p>
<p><input type="submit" value="Submit"/></p>
</form>
</td>
</tr>
</table>
You forgot to mark method param with #RequestBody annotation.
This happens because the movie object you are trying to send from the form to the controller is not mapped properly. This has as a result the constraint of the movie_id you have in your movies table (PK not null I guess) to be violated by trying to insert a not null value into it. If you want the object formed in the frontend page form to be binded in a java object you could try this
front page form
<form:form action="save" modelAttribute="movie" method="POST">
<form:label path = "movie_id"> Movie id</form:label>
<form:input path="movie_id" name="movie_id">
<form:label path = "movie_name"> Movie name</form:label>
<form:input path="movie_name" name="movie_name">
<button type="submit">save</button>
</form:form>
(you should import on your page the springframework form taglib
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>)
Save controller code
#PostMapping("/save")
public String save(#ModelAttribute("movie") Movie movie) {
savedMovie.save(movie);
return "redirect:/LatestMovies";
}
Of course I am assuming that your object has a similar structure like shown below
Movie class
public class Movie{
private String movie_id; // or int or long
private String movie_name;
//getters setters constructors ommitted
}

Hidden form in JSP/Servlet

I want to get parameters from my jsp to my servelet.
so i used input form and it works for the name and the last name but it doesn't work for my ID.
Here is the code of my JSP:
<tr>
<td><form method="post" action="ServBddInsa">
<input type="hidden" name="id" id="id" value="testId"/>
<c:out value="${ utilisateur.id }" />
</form>
</td>
<td><c:out value="${ utilisateur.prenom }" /></td>
<td><c:out value="${ utilisateur.nom }" /></td>
<td><form method="post" action="ServBddInsa">
<p>
<label for="prenom"> Prenom :</label> <input type="text"
id="prenom" name="prenom" />
<label for="nom"> Nom :</label> <input type="text" id="nom"
name="nom" />
</p>
<input type="submit" name="editer" value="editer" />
</form></td>
</tr>
</c:forEach>
and this of my servlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BddInsa listU = new BddInsa();
request.setAttribute("utilisateur", listU.recupererList());
this.getServletContext().getRequestDispatcher("/WEB-INF/bddinsa.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Utilisateur utilisateurs = new Utilisateur();
utilisateurs.setNom(request.getParameter("nom"));
utilisateurs.setPrenom(request.getParameter("prenom"));
utilisateurs.setId(request.getParameter("id"));
System.out.println(utilisateurs.getPrenom());
System.out.println(utilisateurs.getNom());
System.out.println(utilisateurs.getId());
BddInsa listU = new BddInsa();
listU.Editer(utilisateurs);
request.setAttribute("utilisateurs", listU.recupererList());
this.getServletContext().getRequestDispatcher("/WEB-INF/bddinsa.jsp").forward(request, response);
}
}
I get NULL when I try to see the value of id
Thank you for your help !
Please can you try to use only one open and one close form tag? I think you problem is because you have two <form method="post" action="ServBddInsa"> . So the submit button is on the second form. In this case the hidden field of the first form is not considered and it is not sent.

Basic request.getParameter not working [duplicate]

This question already has answers here:
NullPointerException, when reading HTML input [duplicate]
(3 answers)
Closed 6 years ago.
home.jsp
<form method="POST" action="Initiater.do">
<table>
<tr>
<td>
Internal Diameter from FlowAss:
</td>
<td>
<input type="text" id="Id" />
</td>
<td>
Depth:
</td>
<td>
<input type="text" id="Depth" />
</td>
<td>
Units:
</td>
<td>
<select>
<option value="ft">feet</option>
<option value="mts">meters</option>
</select>
</td>
</tr>
<tr>
<td>
<input type="submit" />
</td>
</tr>
</table>
</form>
</body>
</html>
Home.java
public class Home extends HttpServlet {
public void doPost(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException
{
System.out.println("in Post");
String id = (String) request.getParameter("Id");
String depth = request.getParameter("Depth");
/*double id =Double.parseDouble(request.getParameter("Id"));
double depth =Double.parseDouble(request.getParameter("Depth"));*/
System.out.println("Id"+id);
System.out.println("Depth"+depth);
}
the servlet Home.java's doPost method is called, the values id and depth are returning nulls when I debug can anyone help me out with this.
Add name attribute to the input tag.
Change
<input type="text" id="Depth" />
<input type="text" id="Id" />
To
<input type="text" id="Depth" name="Depth"/>
<input type="text" id="Id" name="Id"/>
Request.getParameter gets data by name attribute and not id

Reading table html rows values to a servlet to another jsp page for editing

I want to get the values for the rows which is then sent to a Java servlet then read by another page and inserts those values into the text boxes for the user to edit and write it back into the text file.
So it gets read by ProductIO which reads the textfile.
Its then entered into a jsp table
<c:forEach var="product" items="${products}">
<tr>
<td ><c:out value='${product.code}'/></td>
<td ><c:out value='${product.description}'/></td>
<td >${product.priceCurrencyFormat}</td>
<td><form action="editproduct" method="post">
<input type="submit" value = "Edit">
</form>
</td>
<td><form action="deleteproduct" method="post">
<input type="submit" value = "Delete">
</form>
</td>
</tr>
</c:forEach>
The User Clicks either the delete or edit button which will then send action to either the deleteproduct servlet or the editproduct servlet(only asking about the edit for now)
The edit product servlet
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
String url = "/editproduct.jsp";
getServletContext()
.getRequestDispatcher(url)
.forward(request, response);
String action = request.getParameter("action");
if (action == null) {
action = "editproduct"; // default action
} else if (action.equals("editproduct")) {
String productCode = request.getParameter("productCode");
String descString = request.getParameter("description");
//HttpSession session = request.getSession();
Product product = (Product) session.getAttribute("cart");
if (product == null) {
product = new Product();
}
getServletContext()
.getRequestDispatcher(url)
.forward(request, response);
}
}
Which the three Values are put into three text boxes on the editProduct.jsp page(where im having a problem getting the values to insert into the text boxes for it to be written back to the text file with the new information)
<form action="Product" method="post" >
<input type="hidden" name="action" value="add">
<label>Code:</label>
<input type="text" name="code" value='<%=request.getAttribute("code")%>'
required><br>
<label >Description:</label>
<input type="text" name="desc" value='<%=request.getAttribute("description")%>'
required ><br>
<label >Price:</label>
<input type="text" name="price" value='<%=request.getAttribute("price")%>'
required ><br>
<label> </label>
<!--<input type="submit" value="Update Product" class="margin_left">-->
<!--<input type="submit" value="View Product" class="margin_left">-->
<button type="submit">Update</button><br>
I can share more code if needed.
You aren't calling request.setAttribute() with any of the attributes in your Servlet. I assume you meant to add something like
request.setAttribute("code", productCode);
request.setAttribute("description", descString);
request.setAttribute("price", product.getPrice());
Before forwarding the request.

Persisting Data Using Hidden Forms in JSP

I have an input form (index.jsp):
<form action="process-mobile-number.jsp" method="post">
<table>
<tr>
<td>Enter a mobile number:</td>
<td>
<input type="number" name="telco" maxlength="4" style="width: 20%" required title="Please enter your 4-digit prefix."/>
-
<input type="text" name="mobile" maxlength="7" style="width: 70%" required title="Please enter your 7-digit number."/>
</td>
</tr>
<tr><td><input type="submit" value="Submit" style="width: 50%"/></td></tr>
</table>
</form>
This is the servlet that keeps count on how many times the system has been used:
#WebServlet("/process-mobile-number.jsp")
...
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
...
// initialize counters
int smartCtr = 0;
int globeCtr = 0;
int sunCtr = 0;
...
switch(telcoProvider) {
case "SMART":
smartCtr++;
break;
case "GLOBE":
globeCtr++;
break;
case "SUN":
sunCtr++;
break;
}
...
// assemble counter bean
Counter counter = CounterAssembler.getInstance(smartCtr, globeCtr, sunCtr);
// create session
HttpSession session = request.getSession();
// bind objects to session
session.setAttribute("smartCtr", counter.getSmartCtr());
session.setAttribute("globeCtr", counter.getGlobeCtr());
session.setAttribute("sunCtr", counter.getSunCtr());
// redirect to results jsp
response.sendRedirect("mobile-number-result.jsp");
}
This is the output JSP:
<form action="index.jsp" method="post">
<table>
...
<tr><td style="font-weight: bold">Your number of successful attempts are:</td></tr>
<tr><td>SMART: <%=session.getAttribute("smartCtr") %></td></tr>
<tr><td>GLOBE: <%=session.getAttribute("globeCtr") %></td> </tr>
<tr><td>SUN: <%=session.getAttribute("sunCtr") %></td></tr>
<tr>
<td>
<input type="hidden" name="smartctr" value="<%=session.getAttribute("smartCtr") %>"/>
<input type="hidden" name="globectr" value="<%=session.getAttribute("globeCtr") %>"/>
<input type="hidden" name="sunctr" value="<%=session.getAttribute("sunCtr") %>"/>
<input type="submit" value="Go Back" style="width: 18%"/>
</td>
</tr>
</table>
</form>
QUESTION:
However, when I press "Go Back" to return to index.jsp and begin another transaction, the counters are always reset to 0.
How do I make them persist with the hidden form fields?
Thank you.
Because each time your dopost method is called, you're initializing variable with value 0. Instead simply you can check if the session attribute exist, else set the attribute.
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = req.getSession(true);
// get counter variables
Integer smartCtr = session.getAttribute("smart") == null? 0: session.getAttribute("smart");
Integer globeCtr = session.getAttribute("globe") == null? 0: session.getAttribute("globe");
Integer sunCtr = session.getAttribute("sun") == null? 0: session.getAttribute("globe");
//your logic
....
//set incremented values back
session.setAttribute("smart", smartCtr);
.....
}
If you want to count number times the of system usage, I suggest you should use static variable.
private static int smartCtr = 0;
private static int globeCtr = 0;
private static int sunCtr = 0;

Categories