Spring - SpringMVC + iBatis 사용하기(스프링에서 지원하는 template 사용하기)

Published on: 2009. 9. 13. 16:13 by louis.dev

전체적으로 iBatis의 기본설정은 크게 바뀌지 않는다. 다만 SpringFramework는 DI를 지원하기 때문에 이 설정만 들어가게 되면 다른게 없다.

1.web.xml 의 context-param 부분에 ibatis의 설정이 들어가 있는 xml 파일의 위치를 정해준다.
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
   /WEB-INF/config/applicationContext.xml,
   /WEB-INF/config/applicationContext-iBatis.xml
  </param-value>
 </context-param>

2. applicationContext-iBatis.xml 파일에 DataSource를 설정하고 DataSource를 사용하는 sqlMapClient,sqlMapClient를 사용하는 template를 만든다.
template를 사용하기 위해서는 spring-orm.jar 파일을 라이브러리에 추가해야 한다.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
  <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
  <property name="username" value="user01"/>
  <property name="password" value="user01"/>
  <property name="initialSize" value="10"/>
  <property name="maxActive" value="100"/>
  <property name="maxIdle" value="16"/>
  <property name="maxWait" value="2000"/>
 </bean>
 
 <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="configLocation" value="WEB-INF/config/sqlMapConfig.xml" />
  <property name="dataSource" ref="dataSource" />
 </bean>
 
 <bean id="template" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
     <property name="sqlMapClient" ref="sqlMapClient"/>
 </bean>

위의 Datasource를 구현방법은 DBCP를 사용하는 방법이기 때문에 www.apache.org 에 들어가서 commonms --> dbcp 에서 다운 받은 라이브러리를 추가하여야 사용할 수 있다.


3. sqlMapClient를 사용하기 위해서 로딩한 configLocation인 sqlMapConfig.xml 파일을 설정한다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0 //EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
    <settings
  cacheModelsEnabled="true"
  enhancementEnabled="true"
  lazyLoadingEnabled="true"
  maxRequests="32"
  maxSessions="10"
  maxTransactions="5"
  useStatementNamespaces="true"
 />
 
  <sqlMap resource="kr/co/springboard/dao/sqlmap/sqlMapBoard.xml"/>
</sqlMapConfig>

4. 위의 빨간색의 sqlMapBoard.xml 파일을 생성한다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
      "http://ibatis.apache.org/dtd/sql-map-2.dtd">
      
<sqlMap>
 <typeAlias alias="Board" type="kr.co.springboard.dto.BoardDTO"/>
 <resultMap class="Board" id="boardResult">
  <result property="seq" column="SEQ"/>
  <result property="category" column="CATEGORY"/>
  <result property="title" column="TITLE"/>
  <result property="readCount" column="READ_COUNT"/>
  <result property="writer" column="WRITER"/>
  <result property="regDate" column="REG_DATE"/>
 </resultMap>
 
 <resultMap class="Board" id="boardFullResult">
  <result property="seq" column="SEQ"/>
  <result property="category" column="CATEGORY"/>
  <result property="title" column="TITLE"/>
  <result property="readCount" column="READ_COUNT"/>
  <result property="writer" column="WRITER"/>
  <result property="regDate" column="REG_DATE"/>
  <result property="contents" column="CONTENTS"/>
 </resultMap>
 
 <select id="selectBoardTotalCount" resultClass="int">
  SELECT COUNT(0)
  FROM MY_BOARD
 </select>
 
 <select id="selectBoardList" parameterClass="Board" resultMap="boardResult">
  <![CDATA[
  select
   *
  from
   (
   select *
   from
    ( select * from MY_BOARD order by SEQ ASC )
   where rownum <= #startNum#
   order by SEQ desc
   )
  where rownum <= #countPerPage#
  ]]>
 </select>
 
 <insert id="insertBoard" parameterClass="Board">
  INSERT INTO
   MY_BOARD
   (SEQ,CATEGORY,TITLE,WRITER,REG_DATE,READ_COUNT,CONTENTS)
  VALUES
   (MY_BOARD_SEQ.NEXTVAL,#category#,#title#,#writer#,sysdate,0,#contents#)
 </insert>
 
 <select id="selectBoardItem" parameterClass="int" resultMap="boardFullResult">
  SELECT
   *
  FROM MY_BOARD
  WHERE SEQ=#seq#
 </select>
 
 <update id="updateBoardReadCount" parameterClass="int">
  UPDATE
   MY_BOARD
  SET
   READ_COUNT = READ_COUNT + 1
  WHERE SEQ = #seq#
 </update>
 
 <update id="updateBoardItem" parameterClass="Board">
  UPDATE
   MY_BOARD
  SET
   CATEGORY = #category#,
   WRITER = #writer#,
   TITLE = #title#,
   CONTENTS = #contents#
  WHERE SEQ = #seq#
 </update>
 
 <delete id="deleteBoardItem" parameterClass="int">
  DELETE
  FROM MY_BOARD
  WHERE SEQ = #seq#
 </delete>
</sqlMap>

Spring - Spring FrameWork 과 Log4J 사용해서 Log출력하기

Published on: 2009. 9. 13. 14:29 by louis.dev


위 그림과 같이 Log4J를 사용하면 무슨 Sql문을 사용하는지 무슨 데이터가 parameter로 넘어오는지 DB를 갔다 왔을때 어떤 데이터를 불러오는지를 이클립스의 Consol창을 통해 한번에 알 수 있다.
스프링에서는 Log4J를 설정하는 방법이 있어서 소개해 본다.

1. http://logging.apache.org/log4j/1.2/download.html 
다음 사이트에서 apache-log4j-1.2.15.zip를 다운 받고 압축을 푼다.
그 안에 있는 log4j-1.2.14.jar 파일을 압축 풀고 이클립스의 lib폴더에 넣는다.

2. log4j.properties 파일을 생성한다.
log4j.properties 파일은 콘솔에 로그가 어떻게 형태로 찍힐 것인지를 세팅하는 레이아웃을 잡아준다. 이런 설정은 구글 검색을 통해서 쉽게 얻을 수 있다. 물론 아래의 내용처럼 해도 된다.
properties파일은 #으로 시작하면 주석으로 처리한다.

# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
log4j.rootCategory=DEBUG, stdout

log4j.debug=false

#Console log
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.ImmediateFlush=true
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout.ConversionPattern=[%p] (%F) - %m%n


3. web.xml 파일에 log4j를 로딩할 Listener와 log4j.perperties 파일위치를 정해주는 설정을 해준다.

<listener> 
   <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<context-param>
  <param-name>log4jConfigLocation</param-name>
  <param-value>/WEB-INF/config/log4j.properties</param-value>
</context-param>

Spring - Spring 초기 설정

Published on: 2009. 9. 13. 14:08 by louis.dev
                                                                   <그림출처 : 웹개발자를 위한 Spring 2.5 프로그래밍: 저자 최범균>

SpringFrameWork는 웹을 개발하는데 있어 Full Spec을 지원하는 프레임 웍이다.
SpringMVC로 웹개발을 할때 작동 순서는 위의 그림과 같다.

1. 클라이언트로 부터 URL이 요청되어 들어오면 제일먼저 web.xml 파일을 로딩하여 스프링에서 지원하는 DispatcherServlet이 실행된다.
(이름에서 알수 있듯이 SpringFramework는 Servlet 기반임으로 스프링에서 지원해주는 Controller에서는 HttpServletRequest,HttpServletResponse 인터페이스를 이용해서 request, response 인스턴스를 사용 할 수가 있다.)

2. DispatcherServlet은 클라이언트로부터 들어온 URL을 HandlerMapping 이라는 곳으로 전송후에 URL을 분석해서 알맞은 컨트롤러 이름을 DispatcherServlet 으로 보낸다.

3. HandlerMapping이라는 것을 통해서 실행될 Controller의 이름을 입력받은 DispatcherServlet은 전달받은 Controller를 실행 시킨다. 이렇게 실행된 Controller는 스프링에서 제공하는 ModelAndView 객체에 뷰페이지에 전달할 객체와 뷰페이지 이름 정보를 담고 DispatcherServlet으로 보낸다.

4. ViewResolver를 통해 보여질 View페이지를 탐색한후 View페이지를 보여준다.

SpringMVC 의 웹개발은 위와같은 루틴으로 움직이기 때문에 스프링 초기 설정을 할때는 다음과 같이 순서를 생각하면서 셋팅을 하면 잊어 버리지 않는다.

<스프링 설정>
1. web.xml 세팅
① DispatcherServlet을 세팅해 준다.
<servlet>
   <servlet-name>dispatcher</servlet-name>
   <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
   <!-- 기본 위치는 [servlet name]-servlet.xml 은 WEB-INF에서 불러 오지만 기타 다른위치에 있을때는 위치를 지정한다 -->
   <init-param>
    <param-name>contextConfigLocation</param-name>
     <!-- 클래스 패스에 위치한 파일로부터 설정정보를 읽으려면 "classpath:" 를 붙이고 경로를 써준다 -->
     <!-- ex) classpath:kr/co/springboard/config.xml -->

    <param-value>/WEB-INF/config/dispatcher-servlet.xml</param-value>
   </init-param>
  </servlet>


<servlet-mapping>
   <servlet-name>dispatcher</servlet-name>
   <url-pattern>*.do</url-pattern>
</servlet-mapping>

Url pattern이 ~~.do 로 들어오게 되면 위에 설정에 servlet name이 dispatcher인 servlet을 실행해서 Spring의 핵심인 DispatcherServlet을 실행한다.

② DI 를 선언할 applicationContext 파일을 로딩하기 위해서 알맞은 리스너와 Context Param을 설정해 준다.

<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
   /WEB-INF/config/applicationContext.xml
  </param-value>
 </context-param>

ContextLoaderListner는 기본적으로 /WEB-INF/applicationContext.xml 을 설정 파일로 로딩한다.
다른위치에 있을때 위와같이 context-param설정을 통해 위치를 정해 준다. 그리고 context파일이 많을때는 ,(콤마)를 찍고 다른 경로를 또 입력하면 된다.
context파일 이름이 applicationContext.xml 과 applicationContext-ibatis.xml 이라면 applicationContext*.xml 이라고 설정하면 한번에 두가지 파일을 불러 들인다.

③ encoding 설정을 해준다.
jsp에서 response.setCharactorEncoding() 메소드를 사용해서 페이지에 맞는 케릭터셋을 지정할 수 있으나 스프링에서는 위와 같은 설정 없이 케릭터 셋을 지정해 줄 수 있다.

<filter>
   <filter-name>encodingFilter</filter-name>
   <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
   <init-param>
    <param-name>encoding</param-name>
    <param-value>EUC-KR</param-value>
   </init-param>
  </filter>
 
  <filter-mapping>
   <filter-name>encodingFilter</filter-name>
   <url-pattern>/*</url-pattern>
  </filter-mapping>

2. 위에서 선언한 dispatcher-servlet.xml 파일을 생성한다.
① urlHandlerMapping을 설정한다.
<bean id="springBoardUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
     <property name="mappings">  <!-- mappings는 바뀌면 안된다. -->
      <props>
       <prop key="/boardList.do">listAbstractCommandController</prop>
       <prop key="/boardWrite.do">writeSimpleFormController</prop>
       <prop key="/boardReadDelete.do">readDeleteMultiActionController</prop>
      </props>
     </property>
    </bean>

boardList.do 라는 url로 들어오면 listAbstractCommandController 클래스를 실행 시킨다. 물론 이 이름은 나중에 설정할 applicationContext.xml 에 선언되어있는 bean의 id와 같아야 한다.

② ModelAndView객체를 받아 View페이지로 이동시켜줄 View Resolver를 구현한다.

<bean id="viewResolver"
       class="org.springframework.web.servlet.view.InternalResourceViewResolver">
       <property name="prefix" value="/WEB-INF/view/"/>
       <property name="suffix" value=".jsp"/>
</bean>

위와 같은 설정으로 만약에 ModelAndView 에 ViewName 이 boardList 라는 String 값이 들어 있으면 /WEB-INF/view/boardList.jsp 라는 파일을 부르게 된다. prefix는 경로의 앞에 붙는 것, 즉 viewName의 앞쪽에 붙는 것, subffix는 viewName뒤에 붙는것, 즉 확장자라고 생각하면 되겠다.


3.스프링에서 사용할 DI를 applicationContext.xml에 설정한다.

4. 기능에 맞게 각종 Controller를 사용해서 구현한다.

struts2 - struts 2의 Exception 처리

Published on: 2009. 8. 9. 15:47 by louis.dev


struts 2에서는 action mapping이 되어있는 xml파일에 익셉션을 선언하여 Exception을 처리 할 수 있다.

exception의 선언 방법에는 두가지가 있는데.

1. mapping된 xml 파일의 상단에 선언하여(package 아래 action 태그 위에 선언) global-exception을 처리 하는 방법
2. mapping된 xml 파일의 중간(action 태그 내부에 선언) 하여 특정한 action에서의 exception을 처리 하는 방법

이렇게 두가지 방법을 들을 수가 있다.

1. mapping xml파일의 상단에 선언하는 global-exception처리방법

다음과 같이 Action Mapping을 수행하는 xml 파일의 상단에 선언한다.
위에서 말했듯이 Global-exception은 그림과 같이 <package/> 태그의 시작부분 그리고 <action/>태그보다 위에 위치해 있어야 한다.

<global-exception-mapping/> 에서 선언한 종류의 익셉션이 발생했을 경우 result ="exception" 이 실행이 되는디 이 exception이란 result는 상단에 <global-result/>라고 선언된 곳의 result name을 따라가게 된다. 그리고 선언된 page를 요청하여 사용자에게 보여주게 된다.

물론 <global-result/>에서 여러가지 종료의 exception result를 선언하여 다양한 Exception에 마춰 다양한 에러페이지로 이동할 수도 있다.
당연히 <global-exception-mapping/>도 여러개가 선언되어 있어야 할 것이다.


2. 특정 action 에 대한 Exception을 처리 하는 방법


다음과 같이 <action/>태그 내에 <excpetion-mapping/>을 선언한다. 위와 같은 코드는 NullPointerException이 발생되었을때 <action/>태그내에 선언되어 있는 result name="exception" 인 에러 페이지로 이동하게 된다.(exception-mapping result와 result name="exception" 이 같아야 한다.)

<공통>
Exception이 발생하였을때 보여지는 jsp페이지에서는 struts2에서 제공하는 태그라이브러리를 통해 에러 내용을 출력 할 수 있다.

<%@ taglib prefix="s" uri="/struts-tags" %>

tag lib을 추가 하고
<s:actionerror/>
<s:actionmessage/>
<s:fielderror/>
다음과 같은 테그로 에러 내용을 표시 할 수 있다. 또한
${exception.message}
이렇게 선언할 수 도 있고

예외 상세 정보를 확인 하려면
${exceptionStack}

선언하여 exceptionStack에 쌓여있는 에러 정보를 확인 할 수도 있다

'Framework > STRUTS 2' 카테고리의 다른 글

struts 2 - 스트러츠2 + spring 연동하기  (2) 2009.07.12
struts 2 - JFree Chart plugin  (0) 2009.07.08
struts 2 - Tiles Plug in  (6) 2009.07.08
struts 2 - Interceptor  (3) 2009.07.06
struts 2 - properties 파일  (1) 2009.07.05

struts 2 - 스트러츠2 + spring 연동하기

Published on: 2009. 7. 12. 17:33 by louis.dev


우리나라에서는 struts 1 또는 spring 프레임웍을 사용하여 프로젝트를 구성하는 일이 많다고 한다.

물론 두 프레임웍은 뛰어난 프레임웍들이며 특히 스프링 같은 경우는 풀 스펙을 지원하는 프레임웍으로서 MVC모델을 기반으로 확장을 용의하게 하는 장점이 있다.

하지만 이같은 풀스펙의 스프링은 컨트롤러 부분이 약하다는 평가를 받고 있으며 실제 프로젝트 수행중에 스프링을 이용하면 스프링에서 지원하는 Controller를 사용해서 개발 하다 보면 불편한 점이 많다.

그래서 스트럿츠2는 Controller역할을 하고 spring은 iBatis와 연계하여 템플릿으로 DB에 접근하는 model을 사용하면 단일 프레임웍을 써서 개발하는 것보다 훨씬 수월하고 견고하게 개발을 할 수 있게 된다.


▶ Spring FrameWork Library 파일 추가

www.springsource.org 로 이동하여 FrameWork 라이브러리를 다운받는다.

- spring-framework-2.5.6-with-dependencies.zip   : 실제 SpringFrameWork을 사용할때 필요한 library파일이다.
- spring-framework-2.5.6-with-docs.zip  : SpringFrameWork의 Document 이다. 필요할때 참고하기 위해서 다운 받는다.   

다운받은 라이브러리 압축파일을 풀면 하위 폴더의 \dist 안에 있는 library파일을 모두복사하여 추가한다.(스프링의 핵심적인 라이브러리)

그리고 \dist\modules 로 이동하여 다음과 같은 라이브러리를 복사한다.
 - spring-aop.jar
 - spring-beans.jar
 - spring-core.jar
 - spring-jdbc.jar
 - spring-orm.jar
 - spring-tx.jar
 - spring-web.jar
 - spring-webmvc.jar
 - spring-webmvc-struts.jar

마지막으로 \lib\log4j 로 이동하여 log4j-1.2.15.jar를 추가한다.

struts2의 플러그인에는 struts2-spring-plugin-2.0.14.jar 를 추가 한다.

▶application-context.xml(spring과 iBatis 템플릿을 사용하기 위함)을 web.xml파일과 동일한 위치에 생성한다.

----------------------------------------------------------------------------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 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.5.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
      
 
  <!-- DataSource JDBC type -->
<!-- dataSource를 선언한 부분 --> 
<bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource"
        p:driverClassName="oracle.jdbc.driver.OracleDriver"
        p:url="jdbc:oracle:thin:@localhost:1521:XE"
        p:username="user01"
        p:password="user01" />
 
  <!-- iBatis SQL-Map config -->

<!--
    위에 선언한 dataSource를 정의해 주고 iBatis 설정이 들어간 SqlMapConfig 파일의 위치를 설정해 준다.
    SqlMapConfig.xml파일의 default는 src(classes)폴더이고 classpath를 써주게 되면 아무데나 놓아서 검색하여 찾아낸다..
-->

  <bean id="sqlMapClient"
        class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"
        p:dataSource-ref="dataSource"
        p:configLocation="classpath:SqlMapConfig.xml" />
  
<!-- ibatis의template를 사용하기 위한 bean 설정이다. -->
  <bean id="template"
        class="org.springframework.orm.ibatis.SqlMapClientTemplate"
        p:sqlMapClient-ref="sqlMapClient"/>     
                 
  <bean id="scheduleDao"
        class="com.myhome.schedule.model.ScheduleDAOImpl"
        p:template-ref="template" />
   <!--
           p:template-ref="template" 이것은
           <property name="template" ref="template"/>
           이런식으로 설정해도 된다.
    -->     
  <bean id="service"
        class="com.myhome.service.ScheduleServiceImpl"
        p:scheduleDao-ref="scheduleDao"/>
       
  <bean id="dto"
        class="com.myhome.schedule.model.ScheduleDTO"/>
  
  <bean id="scheduleModel"
        class="com.myhome.schedule.api.ScheduleModel"/>    
 
  <bean id="mc" class="com.myhome.schedule.api.MyCalendar"/>
       
</beans>

 ----------------------------------------------------------------------------------------------------

DB와 연동하기 위해 SqlMapClientTemplate 사용하는데 bean객체의 주입으로 데이터가 이동한다.

<bean id="scheduleDao"
        class="com.myhome.schedule.model.ScheduleDAOImpl"
        p:template-ref="template" />
이렇게 선언되어 있으면 위에서 선언한 class(ScheduleDAOImpl)에서는 setter injection으로 bean객체를 생성없이 사용할 수 있다.

즉 위와 같이 scheduleDao가 선언되어 있으면 이 bean을 사용할 ScheduleDAOImpl 에서는 다음과 같이 객체생성 없이 사용 할 수 있다는 말이다.

/*setter injection*/
 private SqlMapClientTemplate template;
 public void setTemplate(SqlMapClientTemplate template){
  this.template = template;
 }

이렇게 되면 바로 template.~~ 로 insert나 update의 method를 호출하여 사용할 수가 있다.
중요한 점은 위의 appication-context.xml파일에서 설정한 scheduleDao bean에서 선언한 ref의 이름과 실제 setter injection으로 받을 property이름이 같아야 한다는 점이다.

▶ struts.properties 파일에 spring과 연동하겠다고 선언해주어야 함

struts.objectFactory=org.apache.struts2.spring.StrutsSpringObjectFactory
//applicationContext.xml을 가지고 있는게 factory다.
여기서 스트럿츠가 스프링으로 간다는 것을 알려주고 연결한다. objectFactory를 설정해 주면 applicationContext를 이 factory가 갖게 된다. id를 할 때, 인위적으로 applicationContext를 로드해서 리소스를 읽어 id를 참조해서 만들지 않는다.

struts.objectFactory.spring.autoWire=type
// applicationContext.xml에 들어있는 각각의 bean 들을 설정하는데 그 bean은 autoWire 라는 뜻으로 우리가 설정하는 타입데로 알아서 처리하라는 뜻.

▶ web.xml에 설정
<!-- spring 설정파일인 appicationContext.xml의 위치를 선언한다.  -->

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
  </context-param>
 
  <listener>
     <listener-class>
        org.springframework.web.context.ContextLoaderListener
     </listener-class>
  </listener>







'Framework > STRUTS 2' 카테고리의 다른 글

struts2 - struts 2의 Exception 처리  (2) 2009.08.09
struts 2 - JFree Chart plugin  (0) 2009.07.08
struts 2 - Tiles Plug in  (6) 2009.07.08
struts 2 - Interceptor  (3) 2009.07.06
struts 2 - properties 파일  (1) 2009.07.05