Now, I am using AbstractCommandController instead of MultiActionController.
StationDeleteController does not use SimpleFormController, because the id came from URL link, which created by another controller.
Normally, stationId will not be -1 or "ddd", but end user can enter anything URL from Firefox navigation bar, such as:
http://localhost:8180/arden/df/stati...?stationId=ddd
http://localhost:8180/arden/df/stati...g?stationId=-1
To make my application more robust, I have my validator class below.
To display error message, I have error.jsp.
But spring:hasBindErrors always return false, do you know the reason?
If I remove <spring:hasBindErrors>,
http://localhost:8180/arden/df/stati...?stationId=ddd will show:
Failed to convert property value of type [java.lang.String] to required type [int] for property 'stationId'; nested exception is java.lang.NumberFormatException: For input string: "ddd"
http://localhost:8180/arden/df/stati...g?stationId=-1 will show:
station id should not be negative number.
Code:
<bean id="stationDeleteController" class="arden.springmvc.controller.df.StationDeleteController">
<property name="validator" ref="stationDeleteCommandValidator"/>
<property name="commandName" value="commandBean"/>
<property name="commandClass" value="arden.springmvc.command.StationDeleteCommand"/>
</bean>
Code:
<?xml version="1.0" encoding="UTF-8" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<spring:hasBindErrors name="commandBean">
<ul>
<c:forEach var="errMsgObj" items="${errors.allErrors}">
<li>
<spring:message code="${errMsgObj.code}" text="${errMsgObj.defaultMessage}"/>
</li>
</c:forEach>
</ul>
</spring:hasBindErrors>
</body>
</html>
Code:
package arden.springmvc.controller.df;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractCommandController;
import arden.service.Service;
import arden.springmvc.command.StationDeleteCommand;
public class StationDeleteController extends AbstractCommandController {
private final static Logger logger = Logger.getLogger(StationDeleteController.class);
private Service service;
public Service getService() {
return service;
}
public void setService(Service service) {
this.service = service;
}
@Override
protected ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object object, BindException errors) throws Exception {
if (errors.hasErrors()) {
logger.error("errors.hasErrors() is true");
return new ModelAndView("error", "errors", errors);
}
StationDeleteCommand command = (StationDeleteCommand) object;
service.deleteStation(command.getStationId());
return new ModelAndView("df/listStation");
}
}
Code:
package arden.springmvc.validator;
import org.apache.log4j.Logger;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import arden.springmvc.command.StationDeleteCommand;
public class StationDeleteCommandValidator implements Validator {
private final static Logger logger = Logger.getLogger(StationDeleteCommandValidator.class);
@SuppressWarnings("unchecked")
public boolean supports(Class clazz) {
return StationDeleteCommand.class.isAssignableFrom(clazz);
}
public void validate(Object object, Errors errors) {
StationDeleteCommand command = (StationDeleteCommand) object;
if (command.getStationId() < 0) {
logger.error("negative station id[" + command.getStationId() + "]");
errors.rejectValue("stationId", "station.id.negative");
}
}
}
Code:
package arden.springmvc.command;
public class StationDeleteCommand {
private int stationId;
public int getStationId() {
return stationId;
}
public void setStationId(int stationId) {
this.stationId = stationId;
}
}