2013년 7월 27일 토요일

(오라클자바개발자실무교육,오엔제이프로그래밍실무교육센터)_struts, struts2, spring 연동

Struts2 Spring의 결합


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷  실무전문 강의)



IoC/AOP 프레임워크 중 가장 널리 쓰이는 프레임워크는 Spring이다. Opensymphony WebWork 2.1까지는 프레임워크 내부에 IoC  컨테이너를 포함했지만 2.2부터는 자신의 컨테이너를 버리고 Spring과의 통합으로 가고 있다. WebWork의 장점을 받은 Struts2 역시 Spring과의 유연하고 강력한 통합을 제공한다.
Struts2에서 Spring과의 통합은 ObjectFactory SpringObjectFactory를 이용하는 것인데 SpringObjectFactory를 이용하면 모든 Interceptor Action 인스턴스가 Spring Bean으로 올라간다. 인터셉터는 적용한 Action 별로 SingleTon으로 Action Prototype으로 생성된다(요청시 마다 빈을 생성). 따라서 StrutsObjectFactory를 사용할 때와 마찬가지로 인터셉터는 미리 로딩된 상태에서 모든 요청에 대한 선처리, 후처리를 하며 Action은 요청이 올 때마다 새로 인스턴스가 생성된다.
Struts2 Spring과 결합시키면 많은 장점이 있는 데 그 중에서도 인터셉터와 액션이 Spring의 빈으로 관리 되므로 인터셉터와 액션에 다른 Spring(Spring IoC 컨테이너가 관리하는 빈)들을 간편하게 주입(Dependency Injection)할 수 있다. DAO나 비즈니스 오브젝트를 Action에 주입하기 위해 인터셉터를 만들 필요가 없으며 세션을 사용하기 위해 servletConfig 인터셉터와 SessionAware도 필요없으며 단지 세션 빈을 주입하면 된다.
본 예제에서는 SpringObjectFactory Action 인스턴스를 생성하고 LoginAction LoginInterceptor, LoginActionAware를 사용하지 않고 Spring의 빈으로 loginActionDAO을 주입해 보자.
1. 필요한 라이브러리는 다음과 같다.
- spring 라이브러리 (dist 디렉토리의 spring.jar)
- Struts2-Spring 플러그인(struts2-spring-plugin-2.0.14 , struts2 배포판의 lib 폴더에 있다.)
2. web.xml
<?xml version="1.0" encoding="euc-kr"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"
           version="2.5">
           <display-name>Struts2 examples</display-name>
           <!-- 컨텍스트 로더 리스너에서 읽는 applicationContext 설정파일 위치 지정 -->
           <context-param>
                     <param-name>contextConfigLocation</param-name>
                     <param-value>classpath:struts-spring.xml</param-value>
           </context-param>
           <!-- Struts2의 필터 디스패처 -->
           <filter>
                     <filter-name>struts2</filter-name>
                     <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
           </filter>
           <filter-mapping>
                     <filter-name>struts2</filter-name>
                     <url-pattern>/*</url-pattern>
           </filter-mapping>
           <!-- 컨텍스트 로더 리스너 지정 -->
           <listener>
                     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
           </listener>
           <jsp-config>
                     <jsp-property-group>
                                <url-pattern>/*</url-pattern>
                                <page-encoding>euc-kr</page-encoding>
                     </jsp-property-group>
           </jsp-config>
</web-app>
2. struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
     
<struts>
    <package name="struts2" extends="struts-default">
      <!-- spring IoC에서 id=loginAction으로 LoginAction
           로딩 했으므로 Struts에서는 주입받으면 된다. -->
      <action name="login" class="loginAction">
        <interceptor-ref name="prepare"/>
        <interceptor-ref name="modelDriven"/>
        <interceptor-ref name="params"/>
        <result>/login/login_ok.jsp</result>
        <result name="login">/login/login.jsp</result>
      </action>   
    </package>
</struts>
3. struts-spring.xml(/WEB-INF/src)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
           <bean id="loginDAO" class="login.dao.LoginDAO"> </bean>
           <bean id="loginAction" class="login.action.LoginAction">
               <property name="loginDAO">
                     <ref local="loginDAO"/>
</property>
           </bean>
</beans>
4. struts.properties
이 파일에서는 Spring과 관련된 설정이 3가지 있는 데 objectFactory Spring으로 지정하는 것이 가장 중요하다. 나머지 두 가지 설정은 default 설정 파일인 org/apache/struts2/default.properties에 설정되어 있다. autoWire name이 아닌 다른 것으로 설정하고자 하거나 useClassCache false로 할 경우에만 지정하면 된다. 당연히 나머지 두 설정은 struts.objectFactory=spring인 경우에만 유효하다.
# spring integration
struts.objectFactory = spring
#autoWire룰을 정한다.
#name, type, auto, constructor를 지정할 수 있으며 default name
Struts.objectFactory.spring.autoWire=name
#클래스 인스턴스를 캐시할지 여부
#default값은 true
Struts.objectFactory.spring.useClassCache=true
5. Action 클래스
package login.action;
import login.dao.LoginDAO;
import login.model.UserInfo;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.interceptor.NoParameters;
public class LoginAction implements Action, Preparable, ModelDriven  {
    //도메인 오브젝트
           UserInfo userInfo;
           LoginDAO dao;
                    
           public String execute() throws Exception {
                     //LoginDAO dao = new LoginDAO();                                        
                     if (dao.loginChk(userInfo)) {
                                return SUCCESS;
                     }
                     else {
                                return LOGIN;
                     }
           }
          
           //Preparable인터페이스의 prepare 구현
           public void prepare() throws Exception {
                     userInfo = new UserInfo();
           }
          
           //ModelDriven 인터페이스의 getModel 구현
           public Object getModel() {
                     return userInfo;
           }
          
           //Spring IoC 컨테이너에서 LoginDAO를 주입한다.
           public void setLoginDAO(LoginDAO loginDAO) {
               this.dao = loginDAO;
           }
}
6. 도메인 모델 Class
package login.model;
public class UserInfo {
           private String id;
           private String pwd;
           private String name;
          
           public String getId() {
                     return id;
           }
           public void setId(String id) {
                     this.id = id;
           }
           public String getPwd() {
                     return pwd;
           }
           public void setPwd(String pwd) {
                     this.pwd = pwd;
           }
           public String getName() {
                     return name;
           }
           public void setName(String name) {
                     this.name = name;
           }
}
7. DAO 클래스
package login.dao;
import login.model.UserInfo;
public class LoginDAO {
           public boolean loginChk(UserInfo userInfo) {
                     //DB연결 후 넘어오는 사용자 정보를 가지고 로그인 체크
                     //본 예제에서는 id test이면 로그인 성공
                     if ("test".equals(userInfo.getId())) {
                         return true;
                     }
                     else {
                         return false;
                     }
           }
}
8 JSP파일
[/login/login.jsp]
<%@ page pageEncoding="euc-kr" %>
<html>
    <body>
    <form action="login.action">
                       아이디 : <input type="text" name="id"/><br>
                       비밀번호 : <input type="text" name="pwd"/>
                <input type="submit"/>
    </form>
    </body>
</html>
[/login/login_ok.jsp]
<%@ page pageEncoding="euc-kr" %>
로그인 OK!!!

댓글 없음:

댓글 쓰기