akushi
119
2016-01-13 22:53:10
6
1860

doFilter 에서 action bean 인스턴스 얻는 방법 질문


안녕하세요.


환경은 아래와 같습니다.

struts 1.2

spring 1.3


struts 와 spring 버전이 모두 낮아서 Form, SelectCondition, Dto 등 반복적으로 만들어야하는 것이 너무 많아서 필터에서 수행될 액션 인스턴트에 직접 값을 설정하려고 합니다. (@Autowired 와 유사 효과)


각 설정은 아래와 같습니다.


struts-config.xml

<action

      path="/shop/Cart"

      type="org.springframework.web.struts.DelegatingActionProxy"

      scope="request"

      unknown="false"

      validate="true"

    >

    </action>


spring.xml

<bean

      name="/shop/Cart"

      class="com.interpark.action.newmobile.shop.NMCartAction"

      singleton="false"

      lazy-init="default"

    >

</bean>


CommonFilter.java

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {

    // Spean bean (Action 인스턴스) 가져오기

  Object bean1 = WebApplicationContextUtils.getRequiredWebApplicationContext(this.filterConfig.getServletContext()).getBean("/shop/Cart");

  Object bean2 = WebApplicationContextUtils.getWebApplicationContext(this.filterConfig.getServletContext()).getBean("/shop/Cart");

  Object bean3 = WebApplicationContextUtils.getRequiredWebApplicationContext(httpRequest.getSession().getServletContext()).getBean(beanName);

  Object bean4 = WebApplicationContextUtils.getWebApplicationContext(httpRequest.getSession().getServletContext()).getBean(beanName);

   

  try {

  bean1.getClass().getField("name").set(bean1, "John");

  bean2.getClass().getField("name").set(bean2, "John");

  bean3.getClass().getField("name").set(bean3, "John");

  bean4.getClass().getField("name").set(bean4, "John");

  } catch(Exception e) {

  System.out.println(e.getMessage());

  }

}


위와 같이 해보았지만, bean1, bean2, bean3, bean4 모두 NMCartAction의 인스턴스는 맞지만,

실제 수행하게될 NMCartAction 클래스의 인스턴스는 아닙니다. getBean(..) 을 수행할 때, 새로운 스프링 빈을 하나 만드는 것으로 보입니다.


제가 뭔가 잘못된 관점을 가지고 있는 것 같아서 아래와 같이 문의 드립니다.


질문1. filter 에서 수행될 Action 클래스의 인스턴스를 얻을 수 있나요?

질문2. Action 클래스의 name 이라는 필드에 "John"이라는 값을 filter에서 삽입할 수 있나요?

질문3. 위와 같이 하려면 non-singletone으로 가는게 맞지요?


부디 잘못된 제 개념을 잡아주시어요.

고맙습니다.

1
  • 답변 6

  • 커비
    2k
    2016-01-13 23:39:49

    싱글턴이 아니라서 안되는 것 같습니다.

    일단 스트럿츠1에서 이런형태로 구체적으로 사용해보지 못해서 답변 남기기 조심 스러운데

    소스만 살펴보니 

    DelegatingActionProxy 를 상속 받아서 랩핑하면 될 것 같습니다.

    https://github.com/ndimiduk/spring-framework/blob/master/org.springframework.web.struts/src/main/java/org/springframework/web/struts/DelegatingActionProxy.java

    여기 소스 보니 


    	protected Action getDelegateAction(ActionMapping mapping) throws BeansException {
    		WebApplicationContext wac = getWebApplicationContext(getServlet(), mapping.getModuleConfig());
    		String beanName = determineActionBeanName(mapping);
    		return (Action) wac.getBean(beanName, Action.class);
    	}
    

    이 것을 상속받아서 중간에 캐치 하면 될 것 같긴한데 직접 테스트 해보셔야 될 듯합니다.

  • akushi
    119
    2016-01-14 00:44:26

    커비님 답변 고맙습니다.

    DelegatingActionProxy 는 Filter 구현 클래스가 아닌 Action구현 클래스에서 상속받으라는 말씀이신거죠?

    Action구현 클래스의 경우 시스템이 공통적으로 상속받는 CommonAction이 존재해서 상속구조를 만들기는 어려울 것 같아요. 그리고 singleton="true"로도 시도해보았으나, 위에서 제가 한 방식으로는 수행할 Action의 인스턴스를 획득할 수 없었습니다. 요청별로 Action 인스턴스 내에 값을 설정해야하는 상황인데 singleton을 사용해도 괜찮나요? 우선 DelegatingActionProxy 에 대해서 조금 더 자세히 알아보도록 할께요. 그 밖에 도움이 될만한 조언도 부탁드립니다. 다시 한번 답변 감사드립니다. :)

  • 커비
    2k
    2016-01-14 00:48:04

    저의 말은 

    <action

          path="/shop/Cart"

          type="org.springframework.web.struts.DelegatingActionProxy"

          scope="request"

          unknown="false"

          validate="true"

        >

        </action>

    이부분에서  org.springframework.web.struts.DelegatingActionProxy 클래스를 상속해서 얘를 들면 x.y.z.CustomDelegatingActionProxy 이름이라면 


    <action

          path="/shop/Cart"

          type="x.y.z.CustomDelegatingActionProxy "

          scope="request"

          unknown="false"

          validate="true"

        >

        </action>

    이런식으로 커스터마징한 클래스를 사용해서 하시라는 뜻이 였습니다. 

    	protected Action getDelegateAction(ActionMapping mapping) throws BeansException {
    		WebApplicationContext wac = getWebApplicationContext(getServlet(), mapping.getModuleConfig());
    		String beanName = determineActionBeanName(mapping);
    		return (Action) wac.getBean(beanName, Action.class);
    	}

    이 메소드를 오버라이딩 하셔서 위에 필터에서 하고자 하는 형태를 만드시면 될 듯합니다. 

  • akushi
    119
    2016-01-14 00:59:20

    오! 그런 의미였군요! 내일 바로 시도해봐야겠네요! 답변 고맙습니다!

  • akushi
    119
    2016-01-14 01:24:16

    앗 제가 중요한 정보를 빼먹었네요.

    DelegatingActionProxy는 action bean 설정에서 사용하고, filter 는 DelegatingFilterProxy를 사용합니다.

  • 커비
    2k
    2016-01-14 10:42:35

    필터는 사용 안해도 됩니다.

  • 로그인을 하시면 답변을 등록할 수 있습니다.