Reputation: 695
I'm working on a small Servlets & JSP application while learning web development.
I have a question regarding validations and passing values between jsp and servlets.
I have a "Beer" class, with a "rating" property (of type double).
The servlet that loads "edit.jsp" creates a Beer object and loads the current values from the DB.
BeerDAO beerdao = new BeerDAO();
Beer beer = beerdao.getBeer(id);
request.setAttribute("beer", beer);
In the JSP, the object is displayed in the following manner:
...
<td class="left">Beer Name:</td>
<td><input type="text" name="name" value="${beer.name}"/></td>
...
<td class="left">Rating:</td>
<td><input type="text" name="rating" value="${beer.rating}"/></td>
...
Now, when I submit the form to the "update" servlet, each property is validated. In the case of the "rating" property, I convert it to a double.
Should I find an error in the validation (ie: letters, instead of numbers for the rating value), I want to go back to the form with the values that the user typed and an error message. Thing is, I need a Beer object in the request to be displayed in the form, but I can't pass the "rating" value to it, because it's not of the correct type. So right now I'm seeding the user back to a form with an empty rating.
I'm guessing I'm going at it wrong. So, what would be the proper way to validate numbers and get back to the edit form?
Upvotes: 3
Views: 3706
Reputation: 1108642
The most basic approach would be to have a Map<String, String>
in the request scope where the key represents the field name and the value represents the validation error -if any.
BeerDAO beerdao = new BeerDAO();
Beer beer = beerdao.getBeer(id);
request.setAttribute("beer", beer);
// ...
Map<String, String> messages = new HashMap<String, String>();
request.setAttribute("messages", messages);
// ...
String rating = request.getParameter("rating");
if (rating == null) {
messages.put("rating", "Please enter rating");
} else if (!rating.matches("\\d+")) {
messages.put("rating", "Please enter numbers only");
} else {
beer.setRating(Integer.valueOf(rating));
}
// ...
And then in the view
<input name="rating" value="${empty messages.rating ? beer.rating : param.rating}" />
<span class="error">${messages.rating}</span>
The conditional expression will show the beer rating when there is no message (and thus validation has passed) and otherwise the user-submitted value as request parameter.
Unrelated to the concrete problem, redisplaying user submitted data without XML-escaping it is prone to XSS attacks. I strongly suggest to install JSTL and use fn:escapeXml()
function to escape the values.
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
...
<input name="rating" value="${fn:escapeXml(empty messages.rating ? beer.rating : param.rating)}" />
Upvotes: 4