robertrv
robertrv

Reputation: 695

Validating numbers with Servlets and JSP

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

Answers (1)

BalusC
BalusC

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

Related Questions