Double Submit Prevention
Spring MVC에서는 double submit을 방지하기 위해 AbstractFormController를 제공하고, 폼 기능 구현할때 사용하는 SimpleFormController 또한
AbstractFormController를 상속받아 위와같은 처리가 가능하다. Anyframe에서는 이 같은 double submit 방지 기능 시 messageSource에서 추출한 메시지를 지정해주기 위해서
SimpleFormController를 확장한 SessionFormController를 제공한다. 하지만 AbstractFormController를 상속받는 모든 컨트롤러에서는 메소드 이름을 통한 다중 메소드 정의를 사용할 수 없으며
사용 방법 또한 복잡하다. 이러한 SimpleFormController의 제약에 따라 Anyframe Web에서는 SimpleFormController와 MultiActionController의 기능을 합한
AnyframeFormController
를 확장하여 제공한다.
AnyframeFormController를 사용하여 xml 설정을 통해 double submit 방지 기능을 구현할 수 있다.
Annotation을 이용한 double submit 방지 기능 적용 방법은 본 매뉴얼 >> Spring MVC >> Annotation >>
Double Submit
부분을 참고한다.
AnyframeFormController를 이용한 double submit 방지 기능의 적용은 다음과 같은 절차를 따른다.
property 정의하기
double submit 방지 기능의 원리는 기능을 적용할 페이지로 가는 요청을 수행할 때 폼 정보를 세션에 저장하고 페이지 출력 후 submit이 발생하면 session에 폼 정보가
있는지를 확인한 후 없으면 에러메시지를 출력하고 있으면 세션의 form 정보를 없애고 정상 수행을 한다.
이러한 적용을 위해 폼 중복 서브밋을 적용할 페이지의 전 후 요청에 sessionForm 속성을 true로 지정하며, 페이지 출력을 위한 요청에는 폼 정보를 세션에 저장하기 위해
showNewForm 속성을 true로 지정해줘야 한다.

다음은 showNewForm 및 sessionForm 속성 정의가 되어있는
user-servlet.xml
파일의 일부이다.
<!-- 폼 submit 요청 -->
<bean name="/getUser.do"
class="anyframe.sample.springmvc.web.controller.extensions.UserController">
<property name="userService" ref="userService" />
<property name="formView" value="/jsp/user/userForm.jsp"/>
<!-- 다중 메소드 정의를 위한 methodNameResolver-->
<property name="methodNameResolver" ref="paramResolver"/>
<property name="success_get" value="/jsp/user/getUser.jsp"/>
<property name="sessionForm" value="true"/>
</bean>
<!-- 페이지 출력 요청-->
<bean name="/userForm.do"
class="anyframe.sample.springmvc.web.controller.extensions.UserController">
<property name="userService" ref="userService" />
<property name="formView" value="/jsp/user/userForm.jsp"/>
<property name="showNewForm" value="true"/>
<property name="sessionForm" value="true"/>
</bean>
AnyframeFormController를 상속받아 컨트롤러 클래스 구현하기
AnyframeFormController의 사용 방법은 double submit 방지 기능을 적용할 페이지 전, 후의 요청에 따라 구현해야 하는 메소드가 달라진다.
메소드 구현 방법은 다음과 같다.
페이지 출력 요청 (Ex. /userForm.do)
double submit 방지 기능을 구현할 페이지로 이동하기 위해서는 위에서 언급한 바와 같이 sessionForm과 showNewForm 속성을 true로 설정해야한다.
여기서 showNewForm을 true로 설정하게 되면 별도의 method 정의와 상관없이 formBackingObject 메소드를 호출하게 되고
이는 반드시 구현해야한다. 이 메소드 안에는 페이지 출력시 필요한 데이터를 넘겨주며 매핑될 도메인 객체를 생성하여 리턴해 준다. 이 메소드를 정의함에 따라 비로소 세션에
폼 정보를 저장할 수 있고, 리턴된 도메인 객체 값도 넘겨줄 수 있다. 다음은 formBackingObject 메소드가 정의된
UserController.java
파일의 일부이다.
protected Object formBackingObject(HttpServletRequest request)
throws Exception {
//폼에서 필요한 데이터 셋팅
Map address = new HashMap();
address.put("seoul", "서울");
address.put("daegu", "대구");
address.put("busan", "부산");
Map hobby = new HashMap();
hobby.put("reading", "독서");
hobby.put("listeningMusic", "음악감상");
hobby.put("study", "공부");
request.setAttribute("address", address);
request.setAttribute("hobby", hobby);
//commandClass 생성
return new UserVO();
}
폼 submit 요청(Ex. /getUser.do)
폼 submit 후 수행될 요청은 위에서 본바와 같이 sessionForm 속성을 true로 정의해 주면 된다. 기타 구현방법은
MultiActionController
와 같다.
public ModelAndView getUser(HttpServletRequest request, HttpServletResponse response) throws Exception {
UserVO userVO = new UserVO();
// data binding using command object
bind(request,userVO);
// call business service
userVO = userService.getUser(userVO);
// setting view name
ModelAndView mav = new ModelAndView(this.getSuccess_get());
mav.addObject(userVO);
// return a ModelAndView object.
return mav;
}
messageSource 추가하기
AnyframeFormController를 사용하여 double submit이 발생하였을 때 에러메시지를 출력해 줘야하는데 이 메시지는 anyframe.web.springmvc-3.2.0.jar 파일의
anyframe/web/springmvc/messages/springmvc.properties파일에 정의되어 있다. 이 때 사용하는 key값은 common.msg.invalidtoken.error이다.
그러므로 이 resource properties파일을 applicationContext.xml의 messageSource 빈 정의 부분에 해당 properties 파일을 설정해야한다.
<bean
class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
id="messageSource">
<property name="basenames">
<list>
<!-- Anyframe Web. Service message properties files -->
<value>anyframe/web/springmvc/messages/springmvc</value>
</list>
</property>
</bean>
또한 Anyframe에서 제공해주는 기본 메시지가 아닌 다른 문자열을 지정해 주고 싶으면 common.msg.invalidtoken.error 키 값으로 properties 파일을 작성한 후 MessageSource 빈 설정 부분에 위와 같이 파일을 추가하면 된다.
Resources
다운로드
이클립스 프로젝트 형태의 샘플 웹 어플리케이션을 포함하고 있는 anyframe-springmvc-sample-extensions.zip 파일을 다운받은 후, 테스트 환경 설정
을 참조하여
위에서 제시한 예제 코드를 실행해 볼 수 있다.
| Name
|
Download
|
| anyframe-springmvc-sample-extensions.zip |
Download
|
참고자료