Spring의 MultiActionController는 파라미터를 검증할 수 있는 Validator가 자동으로 지원되지 않기 때문에 개발자가 Validator클래스를 작성하고 주입(DI)하고 호출하여 커맨드 객체의 데이터를 검증하는 모든 작업에 관여해야 한다.
EmpUpdateValidator.java
package validator;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import db.Employee;
public class EmpUpdateValidator implements Validator {
@Override
public boolean supports(Class clazz) {
if(Employee.class.isAssignableFrom(clazz))
return true;
else return false;
}
@Override
public void validate(Object command, Errors errors) {
//System.out.println("사원정보 업데이트전 검증");
Employee emp = (Employee)command;
int deptno = emp.getDeptno();
int sal = emp.getSal();
if(deptno<10 || deptno>40)
errors.rejectValue("deptno", "deptno-invalid", "deptno:10~40");
if(sal<500 || sal>8000)
errors.rejectValue("sal", "sal-invalid", "sal:500~8000");
}
}
WEB-INF/dispatcher-servlet.xml
class="validator.EmpUpdateValidator"/>
<bean name="/emp/empMultiActionCont.htm"
class="spring.test.controller.EmpMultiActionController"
p:cacheSeconds="-1"
p:validator-ref="empUpdateValidator"
p:sqlDateFormat-ref="sqlDateFormat"
p:empDao-ref="empDao"
p:methodNameResolver-ref="methodNameResolver"/>
EmpMultiActionController.java
package spring.test.controller;
import java.util.List;
import javax.servlet.http.*;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import validator.*;
import dateutil.SQLDateFormat;
import db.*;
public class EmpMultiActionController extends MultiActionController {
private EmpDAO empDao;
private SQLDateFormat sqlDateFormat;
private EmpUpdateValidator validator;
public void setEmpDao(EmpDAO empDao) {
this.empDao = empDao;
}
public void setSqlDateFormat(SQLDateFormat sqlDateFormat) {
this.sqlDateFormat = sqlDateFormat;
}
public void setValidator(EmpUpdateValidator validator) {
this.validator = validator;
}
public ModelAndView inputForm(HttpServletRequest request, HttpServletResponse response){
ModelAndView mav = new ModelAndView("emp/inputForm");
return mav;
}
public ModelAndView insert(HttpServletRequest request, HttpServletResponse response,
Employee command){
boolean ok = empDao.insert(command);
ModelAndView mav = list(request,response);
String msg = null;
if(ok) msg = "정상적으로 정보를 저장했습니다";
else msg = "저장도중에 오류가 발생하여 저장에 실패했습니다";
mav.addObject("insertResult", msg);
return mav;
}
public ModelAndView list(HttpServletRequest request, HttpServletResponse response){
ModelAndView mav = new ModelAndView("emp/empList");
mav.addObject("list", empDao.getList());
return mav;
}
public ModelAndView getEmpByEmpno(HttpServletRequest request, HttpServletResponse response,
Employee command){
//int empno = Integer.valueOf(request.getParameter("empno"));
int empno = command.getEmpno();
ModelAndView mav = new ModelAndView("emp/empView");
mav.addObject("emp", empDao.getEmpByEmpno(empno));
return mav;
}
public ModelAndView updateForm(HttpServletRequest request, HttpServletResponse response,
Employee command){
ModelAndView mav = getEmpByEmpno(request,response,command);
mav.setViewName("emp/updateForm");
return mav;
}
public ModelAndView update(HttpServletRequest request, HttpServletResponse response,
Employee command){
//////////////// 데이터 검증 결과를 확인하여 검증오류가 있을시, 검증결과 메시지를 뷰에 전달하기 위한 작업
BindException bindErr = this.bindObject(request, command, "emp", this.validator);
if(bindErr.hasErrors()){//만약 에러가 존재한다면?
//System.out.println("검증오류 발견");
List errList = bindErr.getAllErrors();
ModelAndView mav = new ModelAndView();
for(int i=0;i<errList.size();i++){
FieldError fe = (FieldError)errList.get(i);
String field = fe.getField();
if(!fe.isBindingFailure() &&
(field.equals("deptno") || field.equals("sal"))){
mav.addObject(field, fe.getDefaultMessage());
}
}
mav.addAllObjects(bindErr.getModel()); // 커맨드 객체를 다시 뷰에 전달할 필요가 있다.
mav.setViewName("emp/updateForm");
return mav;
}
//////////////// 검증오류가 없을 경우에 실행할 부분
boolean ok = empDao.update(command);
ModelAndView mav = getEmpByEmpno(request,response,command);
String msg = null;
if(ok) msg = "정상적으로 정보를 변경했습니다";
else msg = "변경도중에 오류가 발생하여 변경에 실패했습니다";
mav.addObject("updateResult", msg);
return mav;
}
public ModelAndView delete(HttpServletRequest request, HttpServletResponse response,
Employee command){
boolean ok = empDao.delete(command);
ModelAndView mav = list(request,response);
String msg = null;
if(ok) msg = "정상적으로 정보를 삭제했습니다";
else msg = "삭제도중에 오류가 발생하여 변경에 실패했습니다";
mav.addObject("deleteResult", msg);
return mav;
}
/* command 객체에 할당될 파라미터의 타입을 편집할 수 있도록 오버라이드한다.
* 여기서는 hiredate 문자열을 java.sqlDate형으로 변환하는 내용이다.
* @see org.springframework.web.servlet.mvc.multiaction.MultiActionController#initBinder(javax.servlet.http.HttpServletRequest, org.springframework.web.bind.ServletRequestDataBinder)
*/
@Override
protected void initBinder(HttpServletRequest request,
ServletRequestDataBinder binder) throws Exception {
//MyDateFormat sdf = new MyDateFormat("yyyy-MM-dd");
//System.out.println("initBinder()");
CustomDateEditor cde = new CustomDateEditor(sqlDateFormat, false);
binder.registerCustomEditor(java.sql.Date.class, "hiredate",cde );
}
/* 커맨드 객체에 대해 Validator를 사용하여 커맨드객체의 데이터를 검증하는 부분 */
protected BindException bindObject(HttpServletRequest req, Object command,
String modelName, Validator validator) {
//1.ServletRequestDataBinder를 이용하여 데이터를 바인딩함.
try {
ServletRequestDataBinder dataBinder = createBinder(req, command);
dataBinder.bind(req);
} catch (Exception e) {
e.printStackTrace();
}
//2. 에러 객체 생성.
BindException err = new BindException(command, modelName);
if(validator.supports(command.getClass())){
ValidationUtils.invokeValidator(validator, command, err); // validator의 validate()를 실행한다
}
return err;
}
}
updateForm.jsp
pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>사원정보 변경 폼</title>
<style>
table{border: 2px double black; }
th{ text-align: right; }
td{ text-align: left; }
.btn { text-align: center; }
</style>
</head>
<body><br/><br/><center>
사원정보 수정 폼<p/>
<form action="empMultiActionCont.htm" method="post">
<input type="hidden" name="mode" value="update"/>
<input type="hidden" name="empno" value="${emp.empno}" />
<input type="hidden" name="ename" value="${emp.ename}" />
<table border="1" cellspacing="0" width="400" height="150" rules="none" cellpadding="5">
<tr><th>이름</th><td> ${emp.ename}</td></tr>
<tr><th>사번</th><td> ${emp.empno}</td></tr>
<tr><th>부서</th><td> <input type="text" name="deptno" value="${emp.deptno}"/>
<font color="red">${deptno}</font></td></tr>
<tr><th>급여</th><td> <input type="text" name="sal" value="${emp.sal}"/>
<font color="red">${sal}</font></td></tr>
<tr><td> </td><td> </td></tr>
<tr><td colspan="2" class="btn">
<input type="submit" value="저 장"/>
<input type="reset" value="취 소"/>
</td></tr>
</table>
</form>
<p/>
<hr width="400"/>
<input type="button" value="리스트"
onClick="location.href='empMultiActionCont.htm?mode=list'"/>
<hr width="400"/>
</center>
</body>
</html>
위의 내용중 적색으로 표시된 부분은 검증 오류가 있을시에만 해당 검증 메시지가 출력된다.