본문 바로가기

카테고리 없음

Validation in MultiActionController

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

<bean name="empUpdateValidator"
    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

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    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>

위의 내용중 적색으로 표시된 부분은 검증 오류가 있을시에만 해당 검증 메시지가 출력된다.