Controller

Anyframe Web에서는 정적인 페이지 출력을 위한 ForwardController와 다중 메소드 정의, double submit 방지 기능을 제공하는 AnyframeFormController, MiPlatform과의 연계를 위한 AnyframeMiPController 세 개의 확장 컨트롤러를 제공한다. 각각에 대한 내용은 아래와 같다.

ForwardController

웹 애플리케이션 구성 시 단순히 정적인 페이지 출력만을 위한 요청시에 별도의 컨트롤러 클래스 개발 없이 Anyframe Web에서 제공하는 ForwardController를 사용하여 view 이름 설정만으로 원하는 view를 출력해 줄 수 있다.
<bean id="addUserViewController"
	class="anyframe.web.springmvc.controller.ForwardController">
	<property name="viewName" value="/jsp/adduser.jsp"/>
</bean>
※ Anyframe 3.2.0 이후 버전 부터 해당 클래스는 삭제될 예정이다. 같은 기능의 구현을 위해서는 org.springframework.web.servlet.mvc.ParameterizableViewController로 class를 지정하여 사용한다. ParameterizableViewController의 자세한 사항은 본 매뉴얼 >> Spring MVC >> Controller >> ParameterizableViewController 를 참조한다.

AnyframeFormController

Anyframe Web에서는 Spring MVC의 double submit 방지 기능을 제공하는 SimpleFormController의 기능과 다중 메소드 정의가 가능한 MultiActionController의 기능을 합한 AnyframeFormController를 제공한다. 이 페이지에서는 AnyframeFormController를 사용하는 기본적인 방법을 설명하고 double submit 방지 기능에 대해서는 본 매뉴얼 Spring MVC Extensions >> Double Submit 부분을 참고한다. AnyframeFormController를 상속받아 컨트롤러 클래스를 작성할 때의 사용법은 MultiActionController를 사용하여 구현할 때와 크게 다르지 않다. 하지만 double submit 방지 기능 구현을 위한 showNewForm 속성이 추가되었으며 formBackingObject 메소드 또한 구현해야한다. 다음은 AnyframeFormController의 구현 예인 UserController.java 파일의 일부이다.
public class UserController extends AnyframeFormController {

	UserService userService = null;

	// setter injection of userSerivce
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	public UserController() {
		//commandClass, commandName setting
		setCommandClass(UserVO.class);
		setCommandName("users"); 
	}

	// override onSubmit() method.
  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;
	}

	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);
		return new UserVO();
	}

}
위의 코드에서 볼 수있듯이 bind()메소드를 이용한 data binding, methodNameResolver를 이용한 handle 메소드 정의 부분은 MultiActionController를 상속받아 구현하였을 때와 같다. 그러므로 다음 user-servlet.xml 파일과 같이 methodNameResolver 또한 정의해 줘야한다.
<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"/>
	<property name="methodNameResolver" ref="paramResolver"/>
	<property name="success_get" value="/jsp/user/getUser.jsp"/>
	<property name="sessionForm" value="true"/>
</bean>
또한, 리턴되는 view 이름을 자바 클래스에 넣지 않고 xml 파일에 빼내어 작성하고 있는데 매번 setter injection을 통해 값을 추출해 내야하는 번거로움을 없애기 위해 AnyframeFormController는 success_addView, success_add, success_get, success_update, success_list, success_delete의 attribute에 대해 setter, getter가 정의되어 있다. 이에 사용자는 알맞은 attribute를 사용하여 view 이름을 정의할 수 있으며 다른 이름으로 정의할 시에 setter injection을 통해 추출할 수 있다.
위와 같이 AnyframeFormController는 MultiActionController의 기능을 사용할 수 있으며 SimpleFormController의 double submit 방지 기능도 사용할 수 있다. 새로운 폼을 출력할 때 formBackingObject 메소드를 오버라이드 해서 구현해야 하는데 해당 요청에 대해서는 showNewForm 값을 true로 설정해 준다.
<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>
double submit 방지 기능의 자세한 설명은 여기 를 참고한다.

※ AnyframeFormController를 사용하여 methodNameResolver 사용 없이 하나의 메소드만 사용할 때는 process() 메소드를 오버라이드 하여 구현한다.

AnyframeMiPController

MiPlatform을 사용하여 개발 시, Client UI Component에서 조회/저장 이벤트가 발생하면 호출하는 Controller 클래스는 Business Service를 실행하여 결과값을 XML로 변환하여 전송한다. Anyframe은 개발자 편의를 위하여 AnyframeMiPController를 제공하며 개발자는 복잡한 변환로직을 신경쓰지 않고 개발이 가능하다.
public abstract class AnyframeMiPController extends AnyframeFormController {
<!-- 중략 -->
  public ModelAndView process(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        VariableList inVl = null;
        DatasetList inDl = null;
        VariableList outVl = null;
        DatasetList outDl = null;

        PlatformRequest platformRequest =
            new PlatformRequest(request, defaultCharset);
        PlatformResponse platformResponse =
            new PlatformResponse(response, defaultEncodeMethod, defaultCharset);

        try {

            platformRequest.receiveData();

            inVl = platformRequest.getVariableList();
            inDl = platformRequest.getDatasetList();
            outVl = new VariableList();
            outDl = new DatasetList();
            
            getLogger().debug(this.getClass().getName() + "." + "operate()" + " started");            
            operate(request, inVl, inDl, outVl, outDl);            
            getLogger().debug(this.getClass().getName() + "." + "operate()" + " ended");            
            setResultMessage(outVl, 0, "save successed");

        } catch (Exception e) {
            setResultMessage(outVl, -1, e.getMessage());
        } finally {
            platformResponse.sendData(outVl, outDl);
        }
        return null;
    }
    
    public abstract void operate(HttpServletRequest request, VariableList inVl,
            DatasetList inDl, VariableList outVl, DatasetList outDl)
            throws Exception;     
<!-- 중략 --> 
}
AnyframeMiPController는 AnyframeFormController의 process 메소드를 오버라이드 하고 있고 operate 메소드를 호출한다. 개발자가 AnyframeMiPController를 상속하여 User Defined Controller를 개발 할 경우 실제 코딩은 operate 메소드 내부에 구현하면 된다.
  • operate 메소드 내 이용변수 설명
  • VariableList inVl Client에서 GET방식으로 전송한 parameter를 포함
    VariableList outVl Client로 전송하는 VariableList
    DatasetList inDl Client에서 POST방식으로 전송한 Dataset XML를 포함
    DatasetList outDl Client로 전송하는 DatasetList
  • Page navigation
  • MiPlatform이용 시 화면이동은 발생하지 않으며 조회/저장 이벤트에 해당하는 결과인 Dataset XML만 전송한다.
    개발자가 User Defined Controller에서 operate 메소드 구현 시 화면 이동을 위한 View Name값은 null로 설정한다. 그리고 개발자가 AnyframeMiPController를 상속하여 Controller를 개발할 때는 operate 메소드 내부에 Business Service를 실행하여 결과값을 반환하도록 구현한다.

Resources

  • 다운로드
  • 이클립스 프로젝트 형태의 샘플 웹 어플리케이션을 포함하고 있는 anyframe-springmvc-sample-extensions.zip 파일을 다운받은 후, 테스트 환경 설정 을 참조하여 위에서 제시한 예제 코드를 실행해 볼 수 있다.
    Name
    Download
    anyframe-springmvc-sample-extensions.zip
    Download

  • 참고자료