라토님의 이글루

latokor.egloos.com

포토로그 마이가든



springframework springMVC의 MultiActionController비슷한 기능 구현 프로그래밍

springMVC를 보면 MultiActionController를 이용해서 단순히 파라미터에 정의된 메소드를 컨트롤러 내부에서 자동적으로 실행시킬 수 있다.
하지만 이번 프로젝트에서 부딪힌 난관은 http://xxx.xxx.xxx/ttt?method=xxx.yyy.zzz <- 이런 식으로 값이 들어오면 xxx.yyy클래스 내부의 zzz메소드를 호출해야 하는 상황.
현업과 협의 하에 zzz메소드는 전체 패키지 내에서 유일한 값으로 만들어서 앞의 패키지.클래스명을 무시하고 하나의 컨트롤러 내부에 import된 메소드로 호출하는 약간 비정상적으로 처리하기로 합의 했다.
하지만 그런식으로 하더라도 xxx.yyy.명칭을 제외하고 나머지 이름값만으로 메소드를 호출하기 위해 생각해낸 방법은 MultiActionController를 상속받아 오버라이드 시키려고 했지만 MultiActionController내에 오버라이트 할 메소드가 final로 구현되어 있어
재구성할 수가 없다.스프링프레임워크자체를 수정해서 컴파일 후 적용시킬까도 생각해 봤지만 좀 아닌것 같고.
그래서 method invoke기능을 구현하기로 최종 확정 짖고 상위 객체를 구현하고 나머지 호출메소드를 갖게될 Controller들이 상소받아 사용하게 끔 구현하기로 결정.
그래서 모든 controller들이 상속받을 부모 Controller를 DefaultController라고 명칭하고 아래와 같이 구현 했다.


DefaultController.java


package matrix.common.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public abstract class DefaultController implements Controller {
    
    protected final Log log = LogFactory.getLog(this.getClass());
    private String DEFAULT_TARGET_METHOD = "blank";

    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        
        
        String parameter = request.getParameter("method");
        
        if(parameter != null) {
            String [] targetMethodf = parameter.split("[.]");
            if(targetMethodf.length > 0) {
                targetMethod = targetMethodf[targetMethodf.length-1]; //XXX.YYY.ZZZ 전체 경로에서 마지막 메소드 명만 추출.
            } else {
                targetMethod = parameter;                  //메소드 명만 들어올 경우 바로 적용시킴.
            }
        } else {
            targetMethod = DEFAULT_TARGET_METHOD;
        }
        
        return (ModelAndView)RestMethodInvoke.restMethodInvoker(this, targetMethod, new Object[]{request,response});
    }
    
    //메소드 명이 들어오지 않을 때 기본적으로 실행할 메소드 지정.
    public ModelAndView blank(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return new ModelAndView("blank");
    }
}




위의 DefaultController를 상속 받아서 Controller를 구현한다.


UserController.java

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;

public class CollaborationControl extends DefaultController {
    
    public ModelAndView userList(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        
        
        return new ModelAndView("test");
    }




UserController는 현재 어떠한 일도 하진 않는다.
현재 viewResolver에서 surfix인 .jsp를 셋팅해놓은 상태기 때문에 그냥 test.jsp페이지가 호출될 것이다.

한가지 중요한 것은 DefaultController에 어떤 객체가 묵여 있어 사용해야 한다면 UserController의 빈을 xml에 정의 할때 묶어 주어야 한다.

xxx-servlet.xml

<bean id="userController" class="UserController" >
    <property name="defaultService" ref="defaultService" />    
</bead>

위느 현재 DefaultController에 setter메소드를 구현해서 DefaultService라는 것을 혹시 사용하게 되면 UserController빈 설정에 같이 묶어 주어야 한다는 소리다.

외 위와같은 삽질을 하는가 반문하는 사람도 있을 지모르겠다.
나조차도 이것이 좀 억지스러운 구현이라는 생각에 동감하니까.
하지만 프로그램을 하다가 어떠한 일이 벌어질지는 아무도 모르니까.....

트랙백

이 글과 관련된 글 쓰기 (트랙백 보내기)
TrackbackURL : http://latokor.egloos.com/tb/591472 [도움말]

덧글

  • Corund 2008/07/17 17:04 # 답글

    파라미터의 값으로 컨트롤러를 찾아주는 커스텀 HandlerMapping 클래스와 메서드를 찾아주는 MethodNameResolver 를 구현하고, 컨트롤러들은 MultiActionController 를 이용하는 방식도 가능할 것 같은데요.
  • 라토 2008/07/21 16:53 # 답글

    아~ 급하게 대응하느라 아주 간단한 방법을 간과했네요.
    MethodNameResolver만 Override해도 해결되는 거였는데... ㅜ.ㅜ
    님의 충고덕에 놓치고 지나갈 뻔한걸 되집게 되었네요. 정말 감사합니다.
댓글 입력 영역