<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://wiki.dev.daewoobrenic.co.kr/mediawiki/skins/common/feed.css?63"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>JCFWiKi - 새 문서 [ko]</title>
		<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%8A%B9%EC%88%98%EA%B8%B0%EB%8A%A5:Newpages</link>
		<description>From JCFWiKi</description>
		<language>ko</language>
		<generator>MediaWiki 1.10.0</generator>
		<lastBuildDate>Tue, 07 Sep 2010 19:16:30 GMT</lastBuildDate>
		<item>
			<title>JCF edu 200905</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/JCF_edu_200905</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 5일차 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF 2009년 5월 정기교육 자료&lt;br /&gt;
* 최초작성일 : 2009/05/07&lt;br /&gt;
* 최종작성일 : 2009/05/11&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{경고|이 곳은 2009년 5월에 진행되는 JCF 정기교육에 대한 강의자료가 있는 방입니다. }}&lt;br /&gt;
  [[Category:JCF 정기교육]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=1일차=&lt;br /&gt;
*[[JCF framework|JCF프레임워크 소개]]&lt;br /&gt;
*개인 개발환경 설치&lt;br /&gt;
**[http://152.149.47.87/jcf-starterkit-1.1.0.zip 스타트 킷 다운받기]&lt;br /&gt;
{{주의사항|jcf 스타트킷 사용하지 않을 경우 아래의 가이드를 참조}}&lt;br /&gt;
**[[교육용 개발환경 (개인)|개인 개발환경 설치하기]]&lt;br /&gt;
**[[Eclipse Plugin Management|Eclipse Plugin 사용하기]]&lt;br /&gt;
**[[JCF IssueTracker through Mylyn| Mylyn를 통한 JCF IssueTracker 사용가이드]]&lt;br /&gt;
*JCF 맛보기&lt;br /&gt;
**[[QuickStart:Struts2SpringIBatis|QuickStart로 JCF sample받아오기]]&lt;br /&gt;
**[[QuickStart Eclipse Proejct|QuickStart로 받아온 샘플 예제를 Eclipse에 돌려보기]]&lt;br /&gt;
** [[Media:jcf_arch.pdf|JCF 아키텍쳐]]&lt;br /&gt;
*형상관리시스템&lt;br /&gt;
**[[Subversion using|Subversion 사용가이드]]&lt;br /&gt;
*코딩 표준과 명명 표준&lt;br /&gt;
**[[Naming Convention | Naming Convention ]]&lt;br /&gt;
*1일차 리뷰&lt;br /&gt;
&lt;br /&gt;
=2일차=&lt;br /&gt;
*USER CRUD 개발 Hands on Lab&lt;br /&gt;
**[[EDU USER DEV|사용자 CRUD 개발]]&lt;br /&gt;
**[[진행1일]]&lt;br /&gt;
* Struts2&lt;br /&gt;
**[[struts basic|struts2 이해하기]]&lt;br /&gt;
**[[Struts2 Configuration|Struts2 설정하기(Configuration)]]&lt;br /&gt;
**[[Struts2 Taglibary]]&lt;br /&gt;
*Spring 심화과정&lt;br /&gt;
**[[스프링 핵심 개념 - Ioc|Spring IOC]]&lt;br /&gt;
**[[스프링 핵심 개념 - Aop|Spring AOP]]&lt;br /&gt;
**[[트랜잭션|트랜잭션 처리]]&lt;br /&gt;
*2일차 리뷰&lt;br /&gt;
&lt;br /&gt;
=3일차=&lt;br /&gt;
*IBatis Framework&lt;br /&gt;
**[[IBatis|IBatis Framework 소개]]&lt;br /&gt;
**[[iBatis Cache|iBatis Cache 적용하기]]&lt;br /&gt;
**[[iBatis Dynamic Query|iBatis Dynamic Query 사용하기]]&lt;br /&gt;
*[공통]코드연동&lt;br /&gt;
**[[사용자주소 코드처리|코드연동하기]]&lt;br /&gt;
**[[블로그 분류 코드 TDD 개발하기]]&lt;br /&gt;
*[[JCF3_id|[공통]채번 관리]]&lt;br /&gt;
*3일차 리뷰&lt;br /&gt;
* [[Media:조회하기.word|조회하기txt]]&lt;br /&gt;
&lt;br /&gt;
=4일차=&lt;br /&gt;
*[IDE]이클립스 활용법&lt;br /&gt;
**[[Eclipse debugging guide|Eclipse Debugging하기]]&lt;br /&gt;
**[[10_Easy_Ways_of_Navigation_in_Eclipse|이클립스 단축키]]&lt;br /&gt;
**[[Eclipsetemplates|이클립트 템플릿]]&lt;br /&gt;
*[공통]검색&lt;br /&gt;
**[[Search Module|검색기능 구현하기]]&lt;br /&gt;
*[공통]로깅&lt;br /&gt;
**[[로깅|log4j를 이용한 로깅처리하기]]&lt;br /&gt;
*[공통]에러처리&lt;br /&gt;
**[[에러처리|예외처리하기]]&lt;br /&gt;
*[공통]파일처리&lt;br /&gt;
**[[File attaching|파일 처리하기]]&lt;br /&gt;
*[공통]페이징처리&lt;br /&gt;
**[[paging| 페이징 처리하기]]&lt;br /&gt;
*4일차 리뷰&lt;br /&gt;
&lt;br /&gt;
=5일차=&lt;br /&gt;
*[[Spring_security|Spring_security 개요]]&lt;br /&gt;
* [[Spring security2.0]]&lt;br /&gt;
* [[Spring security 2.0 따라하기]]&lt;br /&gt;
*통합개발환경(ALM)&lt;br /&gt;
*5일차 리뷰&lt;br /&gt;
*테스트 및 설문&lt;br /&gt;
&lt;br /&gt;
=BLOG WORKSHOP=&lt;br /&gt;
*[[Table Schema]]&lt;br /&gt;
&lt;br /&gt;
=POM=&lt;br /&gt;
*[[POM]]&lt;br /&gt;
&lt;br /&gt;
=개발환경=&lt;br /&gt;
{{경고|개발환경은 사내 인트라넷에서 교육 중에 개발 및 테스트를 위해 사용할 수 있습니다. }}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*개발DB&lt;br /&gt;
**URL:&lt;br /&gt;
**ID:&lt;br /&gt;
**PW:&lt;br /&gt;
&lt;br /&gt;
*CI서버&lt;br /&gt;
**URL:&lt;br /&gt;
**계정:&lt;br /&gt;
&lt;br /&gt;
*SVN서버&lt;br /&gt;
**URL: http://152.149.47.86/edu/trunk/edu001~edu010&lt;br /&gt;
**계정(id/pw): edu001 ~edu010 (pw 동일)&lt;/div&gt;</description>
			<pubDate>Thu, 07 May 2009 01:11:53 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:JCF_edu_200905</comments>		</item>
		<item>
			<title>Spring EJB Integration</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_EJB_Integration</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* Spring의 applicationContext에 SLSB 설정하기 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : Spring 2.5와 EJB 2.0 연동&lt;br /&gt;
*작성자: 서경진&lt;br /&gt;
*작성일 : 2009/04/17&lt;br /&gt;
*버전 : 1.0&lt;br /&gt;
*개정이력 : &lt;br /&gt;
'''Copyright © 2007 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== EJB 2.0 Maven 프로젝트 생성하기 ==&lt;br /&gt;
&lt;br /&gt;
=== EJB 구현을 위한 기본 라이브러리 (아키텍트용, 개발자 단순참고) ===&lt;br /&gt;
* m2eclipse 플러그인을 적용한 메이븐 아키타입으로 EJB 프로젝트를 재구성하였다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;plugins&amp;gt;&lt;br /&gt;
      &amp;lt;plugin&amp;gt;&lt;br /&gt;
        &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;
        &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
        &amp;lt;version&amp;gt;2.0.2&amp;lt;/version&amp;gt;&lt;br /&gt;
        &amp;lt;configuration&amp;gt;&lt;br /&gt;
          &amp;lt;source&amp;gt;1.4&amp;lt;/source&amp;gt;&lt;br /&gt;
          &amp;lt;target&amp;gt;1.4&amp;lt;/target&amp;gt;&lt;br /&gt;
        &amp;lt;/configuration&amp;gt;&lt;br /&gt;
      &amp;lt;/plugin&amp;gt;&lt;br /&gt;
      &amp;lt;plugin&amp;gt;&lt;br /&gt;
        &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;
        &amp;lt;artifactId&amp;gt;maven-ejb-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
        &amp;lt;version&amp;gt;2.1&amp;lt;/version&amp;gt;&lt;br /&gt;
        &amp;lt;configuration&amp;gt;&lt;br /&gt;
          &amp;lt;ejbVersion&amp;gt;2.0&amp;lt;/ejbVersion&amp;gt;&lt;br /&gt;
          &amp;lt;generateClient&amp;gt;true&amp;lt;/generateClient&amp;gt;&lt;br /&gt;
        &amp;lt;/configuration&amp;gt;&lt;br /&gt;
      &amp;lt;/plugin&amp;gt;&lt;br /&gt;
    &amp;lt;/plugins&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 프로젝트에 있는 pom.xml에 정의하여 라이브러리와 빌드를 관리한다.&lt;br /&gt;
* 해당 라이브러리는 JCF 공용 메이븐 저장소(http://repo.expertvill.net/nexus/)에서 조회하여 다운로드 받을 수 있다.&lt;br /&gt;
* Stateless Session Beans 라이브러리&lt;br /&gt;
[[그림:SessionBeansLibrary.JPG|700px|center|thumb|Stateless Session Beans 필수 라이브러리]]&lt;br /&gt;
여기에서 EAdjustAnnounce.jar, EAdjustLand.jar, EAdjustCatalog.jar는 세션빈이 사용하는 각 엔티티빈을 패키징한 라이브러리이다. 세션빈의 구동을 위해 엔티티빈을 패키징한 라이브러리가 필요하다.&lt;br /&gt;
* Entity Beans 라이브러리&lt;br /&gt;
[[그림:EAdjustCatalogLibrary.JPG|600px|center|thumb|EAdjustCatalog Entity Beans 필수 라이브러리]]&lt;br /&gt;
&lt;br /&gt;
[[그림:EAdjustLandLibrary.JPG|700px|center|thumb|EAdjustLand Entity Beans 필수 라이브러리]]&lt;br /&gt;
&lt;br /&gt;
=== Maven 기반 EJB 프로젝트 구성하기 (아키텍트용, 개발자 단순참고) ===&lt;br /&gt;
&lt;br /&gt;
* JCF 스타트킷을 사용하여 메이븐 기반의 개발환경을 구성한다.&lt;br /&gt;
* SAdjust 세션빈과 EAdjustAnnounce, EAdjustCatalog, EAdjustLand 엔티티빈 소스 샘플을 참고하여 프로젝트를 구성하고 JCF와 EJB 연동을 개발한다.&lt;br /&gt;
&lt;br /&gt;
== Stateless Session Beans (SLSBs) 개발 및 빌드 ==&lt;br /&gt;
&lt;br /&gt;
=== SLSB 개발 ===&lt;br /&gt;
* 메이븐 기반 EJB 프로젝트에서 기존 소스 코드 임포트&lt;br /&gt;
&lt;br /&gt;
=== SLSB 빌드 ===&lt;br /&gt;
* 메이븐 빌드 (maven-ejb-plugin 적용)&lt;br /&gt;
* maven ejb:ejb 실행&lt;br /&gt;
&lt;br /&gt;
=== Spring의 applicationContext에 SLSB 설정하기 ===&lt;br /&gt;
* 원격시스템 (Remote System)에서 웹로직서버에 디플로이된 SLSB를 사용하기 위해 다음과 같이 applicationContext.xml에 설정한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=xml&amp;gt;&lt;br /&gt;
    &amp;lt;jee:remote-slsb id=&amp;quot;ejbRemoteAdjust&amp;quot; jndi-name=&amp;quot;ejb/mp.SAdjustHome&amp;quot;&lt;br /&gt;
		business-interface=&amp;quot;onbid.ejb.adjust.sadjust.SAdjust&amp;quot;&lt;br /&gt;
    	cache-home=&amp;quot;true&amp;quot;&lt;br /&gt;
    	lookup-home-on-startup=&amp;quot;true&amp;quot;&lt;br /&gt;
    	resource-ref=&amp;quot;true&amp;quot;&lt;br /&gt;
    	home-interface=&amp;quot;onbid.ejb.adjust.sadjust.SAdjustHome&amp;quot;&lt;br /&gt;
    	refresh-home-on-connect-failure=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
    	&amp;lt;jee:environment&amp;gt;&lt;br /&gt;
    		java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory&lt;br /&gt;
			java.naming.provider.url=t3://대상서버 IP주소:포트&lt;br /&gt;
			java.naming.security.principal=웹로직서버 사용자ID&lt;br /&gt;
			java.naming.security.credentials=패스워드&lt;br /&gt;
    	&amp;lt;/jee:environment&amp;gt;&lt;br /&gt;
    &amp;lt;/jee:remote-slsb&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 로컬에서 웹로직서버에 디플로이된 SLSB를 사용하기 위해 다음과 같이 applicationContext.xml에 설정한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=xml&amp;gt;&lt;br /&gt;
	&amp;lt;jee:local-slsb id=&amp;quot;ejbSAdjustHome&amp;quot; jndi-name=&amp;quot;ejb/mp.SAdjustHome&amp;quot;&lt;br /&gt;
		business-interface=&amp;quot;onbid.ejb.adjust.sadjust.SAdjustLocal&amp;quot;&lt;br /&gt;
		cache-home=&amp;quot;true&amp;quot;&lt;br /&gt;
		lookup-home-on-startup=&amp;quot;true&amp;quot;&lt;br /&gt;
		resource-ref=&amp;quot;true&amp;quot;&lt;br /&gt;
		expose-access-context=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Entity Beans (CMP) 개발 및 빌드 ==&lt;br /&gt;
&lt;br /&gt;
=== maven-ejb-plugin으로 EJB 빌드하기 ===&lt;br /&gt;
&lt;br /&gt;
== EJB 2.0 모듈 웹로직 8.1 서버에 디플로이하기 ==&lt;br /&gt;
&lt;br /&gt;
* startWebLogic.cmd 스크립트 수정하기&lt;br /&gt;
&lt;br /&gt;
== Spring 2.5 기반의 테스트케이스로 EJB 테스트하기 ==&lt;/div&gt;</description>
			<pubDate>Fri, 17 Apr 2009 09:05:08 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Spring_EJB_Integration</comments>		</item>
		<item>
			<title>RoleGuide</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/RoleGuide</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF3.0 공통모듈 -권한관리 사용가이드 &lt;br /&gt;
*작성자:김민아&lt;br /&gt;
*작성일 : 2008/09/19&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
*권한관리는 시스템에서 쓰이는 권한에 대해서 관리하는 화면이다.}}&lt;br /&gt;
*메뉴의 공통모듈&amp;gt;권한관리를 클릭하면 다음과 같은 화면이 나타난다.&lt;br /&gt;
*시스템 코드는 코드관리에서 등록한 데이터로 권한이 많을 경우 시스템 별로 조회할 수 있다.&lt;br /&gt;
*입력과 수정은 그리드 내에서 이루어지고, 삭제는 왼쪽의 checkbox를 선택한 후 행삭제 버튼을 누른다. 수정과 입력, 삭제가 다 이루어졌으면 저장버튼 클릭으로 데이터가 최종 반영된다.&lt;br /&gt;
[[그림:RoleMng.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
*권한관리에서 반영된 데이터는 밑에와 같이 사용자 추가/수정부분과 메뉴관리에서 선택할 수 있도록 보여진다.&lt;br /&gt;
*사용자 추가/삭제에서의 권한은 사용자에 권한을 지정하는 것이고,&lt;br /&gt;
*메뉴관리에서의 권한은 해당메뉴에 접근 가능한 권한을 지정하는 것이다.&lt;br /&gt;
[[그림:Roleex1.jpg|500px]][[그림:Roleex2.jpg|500px]]&lt;/div&gt;</description>
			<pubDate>Fri, 19 Sep 2008 08:09:43 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:RoleGuide</comments>		</item>
		<item>
			<title>CommonModule CodeUserGuide ext-js</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/CommonModule_CodeUserGuide_ext-js</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF3.0 공통모듈- 코드모듈 사용가이드 -ext-js를 사용 할 경우&lt;br /&gt;
*작성자:김민아&lt;br /&gt;
*작성일 : 2008/09/17&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
*combox박스가 두개 이상이여서  상위코드 클릭 시 해당되는 하위코드가 바인딩되어야하는 경우  ext-js를 사용하였다.&lt;br /&gt;
*예) 코드관리에서 상위코드 가져오기   &lt;br /&gt;
&lt;br /&gt;
= code.js파일=&lt;br /&gt;
*findCodes()&lt;br /&gt;
&amp;lt;code lang=&amp;quot;javescript&amp;quot;&amp;gt;&lt;br /&gt;
Ext.onReady(function(){&lt;br /&gt;
     findCodes();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
**화면이 로딩될 때 코드값을 가져오는 메소드(findCodes)를 onReady메소드 안에 넣는다.  &lt;br /&gt;
&amp;lt;code lang=&amp;quot;javescript&amp;quot;&amp;gt;&lt;br /&gt;
 /*&lt;br /&gt;
     * 로딩시 combox 값 가져오기&lt;br /&gt;
   */&lt;br /&gt;
	function findCodes() {&lt;br /&gt;
		var params = '{' &lt;br /&gt;
			+ 'parentId:\&amp;quot;' + &amp;quot;0&amp;quot; + '\&amp;quot;,'&lt;br /&gt;
           	+ '}'&lt;br /&gt;
       		Ext.Ajax.request({&lt;br /&gt;
		   url: '/jcf-common/comCode/findComCodeList.action',&lt;br /&gt;
		 jsonData: params,&lt;br /&gt;
		    headers:{&lt;br /&gt;
		    	'Content-Type' : 'application/json'&lt;br /&gt;
		    },	 &lt;br /&gt;
		    success: function( r, o ) {&lt;br /&gt;
		    	try {&lt;br /&gt;
      	    		cbUpwCodeStore.loadData(Ext.decode(r.responseText));&lt;br /&gt;
      	    		cbwCodeStore.loadData(Ext.decode(r.responseText));	    	&lt;br /&gt;
		    	} catch(e) {&lt;br /&gt;
		    	}&lt;br /&gt;
	    	},&lt;br /&gt;
			failure: function( r, o ) {&lt;br /&gt;
				alert(&amp;quot;find Error! &amp;quot;+r.responseText);&lt;br /&gt;
			}&lt;br /&gt;
		})&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
**parentId가 0인 코드값을 가져오기 위해서 위에 같이  params을  지정한다.(Action참고)&lt;br /&gt;
**Ext.Ajax.request라는 메소드 사용하여 서버에 request를 보낼 url 과 위에서 정의한 params을 jsonData에 넣는다.  &lt;br /&gt;
**서버로부터 값을 제대로 받아왔는지 확인하기 위해 success 와 failure을 지정해주고 success  function 안에는 try /catch 문을 선언한다.  &lt;br /&gt;
**alert(r.responseText)을 통해 받아온 JSON 데이터값을 alert창으로 확인한다.&lt;br /&gt;
**cbUpwCodeStore.loadData, cbwCodeStore.loadData 로  JsonStore 에  받아온 데이터를  담는다.  &lt;br /&gt;
*JsonStore&lt;br /&gt;
&amp;lt;code lang=&amp;quot;javescript&amp;quot;&amp;gt;&lt;br /&gt;
var Code = Ext.data.Record.create([&lt;br /&gt;
           	{name: 'id',      type: 'string'},&lt;br /&gt;
           	{name: 'name',    type: 'string'}      	&lt;br /&gt;
      ]);&lt;br /&gt;
  &lt;br /&gt;
    //상의 업무 시스템 Store 정의&lt;br /&gt;
    var cbUpwCodeStore = new Ext.data.JsonStore({&lt;br /&gt;
		root:'upwCodeList',&lt;br /&gt;
         fields: [ 'id', 'name']      		 &lt;br /&gt;
    });&lt;br /&gt;
    &lt;br /&gt;
        // 업무 시스템 Store 정의 &lt;br /&gt;
    var cbwCodeStore = new Ext.data.JsonStore({&lt;br /&gt;
		root:'workCodeList',&lt;br /&gt;
          fields: [ 'id', 'name']        		 &lt;br /&gt;
    });&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
**cbUpwCodeStore과 cbwCodeStore 는 findCodes에서 받아온 데이터를  저장하기  위한   JsonStore 이다.&lt;br /&gt;
**New Ext.data.JsonStore 로 cbwCodeStore 라는 JsonStore 를 생성한다. root에는 action의 OutChannel에서 지정한 값을  fields에는 받은 값의 각 Object들을 넣는다. &lt;br /&gt;
*ComboBox 생성 &lt;br /&gt;
&amp;lt;code lang=&amp;quot;javescript&amp;quot;&amp;gt;&lt;br /&gt;
     	// 상위업무시스템 combox&lt;br /&gt;
	cbUpwCode = new Ext.form.ComboBox({  &lt;br /&gt;
				store: cbUpwCodeStore,&lt;br /&gt;
				valueField: 'id',			&lt;br /&gt;
				displayField:'name',&lt;br /&gt;
				typeAhead: true,&lt;br /&gt;
			        mode: 'local',&lt;br /&gt;
				triggerAction: 'all',&lt;br /&gt;
				editable:false,&lt;br /&gt;
	                	emptyText:'시스템  코드를 선택하세요',&lt;br /&gt;
				selectOnFocus:true,&lt;br /&gt;
				listeners:{select:{fn:function(combo, value) {&lt;br /&gt;
					var comboNext = Ext.getCmp('cbUpwCode');   &lt;br /&gt;
                                        //클릭한 시스템코드에 따라 상위업무코드 필터링 		&lt;br /&gt;
	                	       cbwCodeStore.filter('parentId', this.getValue());&lt;br /&gt;
				}}},&lt;br /&gt;
				applyTo: 'upwCombo'&lt;br /&gt;
	});&lt;br /&gt;
	&lt;br /&gt;
       var cbworkCodeId;	&lt;br /&gt;
// 상위업무코드 combox&lt;br /&gt;
	cbworkCode = new Ext.form.ComboBox({&lt;br /&gt;
				store: cbwCodeStore,&lt;br /&gt;
				valueField: 'id',			&lt;br /&gt;
				displayField:'name',&lt;br /&gt;
				typeAhead: true,&lt;br /&gt;
				editable:false,&lt;br /&gt;
				mode: 'local',&lt;br /&gt;
				triggerAction: 'all',&lt;br /&gt;
				emptyText:'업무를 선택하세요',&lt;br /&gt;
				selectOnFocus:true,&lt;br /&gt;
		        	listeners:{select:{fn:function(combo, value) {&lt;br /&gt;
				    cbworkCodeId=this.getValue();&lt;br /&gt;
				}}},&lt;br /&gt;
				applyTo: 'workCombo'&lt;br /&gt;
	});&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
**new Ext.form.ComboBox 로  cbUpwCode 와 cbworkCode 라는 ComboBox를 생성한다 &lt;br /&gt;
**Preperty 설명)&lt;br /&gt;
***	Store:  바인딩할  store 지정,&lt;br /&gt;
***	displayField : 화면에 보여지는 text 값&lt;br /&gt;
***	valueField:  실제  저장되는  value 값&lt;br /&gt;
***	Editable: combox 수정여부(ombox에서 선택하기 않고  직접입력이 가능하도록 설정하고 싶다면 true로 지정)&lt;br /&gt;
***	Mode: local  data를 로당할지  server에서  data를 가져와  로딩할지 여부 (local은 local  data를 로드한다는 뜻이고 remote는  server로부터 data를 로드한다는 뜻이다)&lt;br /&gt;
***	triggerAction:   이미 선택된 값 외의  코드값도 선택할 수 있게할지  여부( triggerAction을 all이라고 지정하지 않는다면  이미  값이 있거나,  한번 선택된 코드값은 수정할 수 없음)&lt;br /&gt;
***	emptyText :  combox에 값이 바인딩이 되지 않았을 때 기본으로 보여지는 텍스트&lt;br /&gt;
***	selectOnFocus: combox를 클릭했을 때, combox에 바인딩된  데이터를 Focus 할지 여부이다. (True로 설정해놓았으면, combox를 클릭했을 때, combox에 바인딩된  데이터가  파란네모박스  안에  흰글씨로 Focus 됨)&lt;br /&gt;
***listeners 클릭시 선택된 데이터를 읽어서 다른곳에서 참조할 때 사용&lt;br /&gt;
***	applyTo:  실제 바인딩 할 jsp파일의 id&lt;br /&gt;
=CodeAction.java=&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public  String findComCodeList(){&lt;br /&gt;
		&lt;br /&gt;
	private CodeService codeService;&lt;br /&gt;
	private Code code;&lt;br /&gt;
	private List upwCodeList; &lt;br /&gt;
	private List workCodeList;&lt;br /&gt;
	private List codeDivList;&lt;br /&gt;
	private List codeList;&lt;br /&gt;
	&lt;br /&gt;
		Map searchMap = (Map) InChannel.getVariables();	 &lt;br /&gt;
	       upwCodeList=codeService.findCodes(searchMap);&lt;br /&gt;
		workCodeList=new ArrayList();&lt;br /&gt;
		for (int i = 0; i &amp;lt; upwCodeList.size(); i++) {&lt;br /&gt;
			System.out.println(upwCodeList.size());&lt;br /&gt;
			code = (Code) upwCodeList.get(i);&lt;br /&gt;
			System.out.println((code.getId()));&lt;br /&gt;
	     	List tmpcodeList =codeService.findCodes(code.getId());&lt;br /&gt;
	    	if (null == tmpcodeList)&lt;br /&gt;
				continue;&lt;br /&gt;
	     	workCodeList.addAll(tmpcodeList);&lt;br /&gt;
		}&lt;br /&gt;
		OutChannel.setDataSet(&amp;quot;upwCodeList&amp;quot;, upwCodeList);&lt;br /&gt;
		OutChannel.setDataSet(&amp;quot;workCodeList&amp;quot;, workCodeList);&lt;br /&gt;
&lt;br /&gt;
		OutChannel.send();&lt;br /&gt;
		&lt;br /&gt;
		return null;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*InChannel.getVariables을 통해 js파일에서 param으로 넘긴 값을 Map 유형의 searchMap에 받아온다. (parentId는 key, 0은 value로 받아옴)&lt;br /&gt;
*OutChannel.setDataSet을 통해  js파일에 JsonData 유형으로 변환해서 보낸다. &lt;br /&gt;
**여기서 &amp;quot;upwCodeList&amp;quot;은 js파일에서 선언한  JsonStore의 root와 일치되어야하고  upwCodeList는 위에서 선언한 값이다.&lt;/div&gt;</description>
			<pubDate>Thu, 18 Sep 2008 09:45:17 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:CommonModule_CodeUserGuide_ext-js</comments>		</item>
		<item>
			<title>CommonModule CodeUserGuide struts2</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/CommonModule_CodeUserGuide_struts2</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF3.0 공통모듈- 코드모듈 사용가이드 -struts기반의 표준웹일 경우&lt;br /&gt;
*작성자:김민아&lt;br /&gt;
*작성일 : 2008/09/17&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
*에)사용자 조회화면에서 직급코드가져오기 &lt;br /&gt;
=UserAction=&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package jcf.biz.user.action;&lt;br /&gt;
..&lt;br /&gt;
public class UserAction extends BaseAction {&lt;br /&gt;
..&lt;br /&gt;
	private List usrPosCode;&lt;br /&gt;
...	private CodeService codeService;&lt;br /&gt;
	/**&lt;br /&gt;
	 * @return&lt;br /&gt;
	 * addUser창으로 이동 &lt;br /&gt;
	 */&lt;br /&gt;
	public String addUser(){&lt;br /&gt;
&lt;br /&gt;
		return SUCCESS;&lt;br /&gt;
	}&lt;br /&gt;
..&lt;br /&gt;
	public List  getUsrPosCode() {&lt;br /&gt;
		usrPosCode=codeService.findCodes(&amp;quot;4&amp;quot;);&lt;br /&gt;
		return usrPosCode;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*CodeService codeService : 코드값을 가져오기 위한 서비스 프라퍼티. &lt;br /&gt;
*List usrPosCode: 직급 코드값 리스트를 저장하기 위한 프라퍼티. &lt;br /&gt;
*addUser(..) 액션 메소드에서는 사용자 등록 화면으로 가기전에 getUsrPosCode를 호출하여 codeService를 통해서 직급 코드 값을 가져와 usrPosCode에 담는다.(결과 페이지에서는 여기서 추가된 usrPosCode를 JSP에서 참조하여 코드 값을 보여주게 된다.) &lt;br /&gt;
* getUsrPosCode: codeService의 findCodes 메소드를 직급코드의 id값을 넘겨 호출하여 직급데이터를 가져온다. &lt;br /&gt;
=editUsr.jsp=&lt;br /&gt;
&amp;lt;code lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;td class=&amp;quot;Mnns_label&amp;quot; nowrap width='10%'&amp;gt;직급&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td class=&amp;quot;Mbox_bg&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;s:select name='user.usrPos' list=&amp;quot;usrPosCode&amp;quot; listKey=&amp;quot;id&amp;quot; listValue=&amp;quot;name&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;s:select /&amp;gt; 태그를 사용하여 액션 클래스의 코드 리스트(usrPosCod)를 보여주고, 선택값은 액션의 user 모델 객체의 usrPos' 프라퍼티(user.usrPos)로 저장되도록 설정한다&lt;/div&gt;</description>
			<pubDate>Thu, 18 Sep 2008 09:41:30 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:CommonModule_CodeUserGuide_struts2</comments>		</item>
		<item>
			<title>MenuGuide</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/MenuGuide</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF3.0 공통모듈 -메뉴관리 사용가이드 &lt;br /&gt;
*작성자:김민아&lt;br /&gt;
*작성일 : 2008/09/01&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
*메뉴관리는 로그인 시 제일 상위에 있는 메뉴트리에 대해서 관리하는 화면이다.&lt;br /&gt;
}}&lt;br /&gt;
*메뉴관리는 상위의 '''메뉴카테고리 추가''', '''메뉴추가''', '''메뉴삭제'''로 추가.삭제 후 오른쪽 저장 버튼 클릭으로 최종 반영된다.&lt;br /&gt;
* 메뉴괸리는 다른 모듈과 달리 수정이나 추가 시 전체 데이터가  한 번 삭제되었다가 다시 입력되는 것이므로 만약을 대비하여 작업 전에 데이터를 백업해놓는 것이 좋다. &lt;br /&gt;
&lt;br /&gt;
*메뉴카테고리에는 메뉴이름만 입력하고,&lt;br /&gt;
*메뉴에는 메뉴명, 화면 소스경로(상대경로로 지정), 그리고 그 메뉴에 접근가능한 권한들을 지정한다.&lt;br /&gt;
*만약에 여기서 접근권한을 지정하기 않은 권한을 가진 사용자가 로그인했다면 그 메뉴는 트리에 보이지 않을 것이다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[그림:menuMng.jpg|900px]]&lt;/div&gt;</description>
			<pubDate>Thu, 18 Sep 2008 07:00:36 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:MenuGuide</comments>		</item>
		<item>
			<title>UsrGuide</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/UsrGuide</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF3.0 공통모듈 -사용자관리 사용가이드&lt;br /&gt;
*작성자:김민아&lt;br /&gt;
*작성일 : 2008/09/01&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
*사용자관리는 시스템을 사용하는 사용자들에 대해 관리하는 모듈이다.&lt;br /&gt;
*공통모듈의 사용자 관리는 모든 시스템에서 공통적으로 쓰이는 부분에 대해서만 구현하였다. 필요한 부분은 확장해서 사용하길 바란다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=사용자리스트보기=&lt;br /&gt;
*메뉴의 공통모듈&amp;gt;사용자 관리를 클릭하면 밑에와같이 사용자 리스트가 있는 화면을 볼 수 있다.&lt;br /&gt;
*상세보기를 할 때는 사용자 리스트의 id를 클릭하고 사용자 추가를 할 때는 상위의 '''추가'''버튼을 누른다.&lt;br /&gt;
*삭제는 왼쪽의  삭제 체크박스를 클릭한 후 상위의 '''삭제''' 버튼을 누른다.&lt;br /&gt;
[[그림:userList.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
=사용자 수정/추가=&lt;br /&gt;
*사용자 리스트에서 '''추가'''버튼을 클릭하거나, 상세보기를 하면 밑에와 같이 검은색 바탕화면에 추가/수정 창이 나올 것이다.&lt;br /&gt;
*여기서 권한은 사용자에게 권한을 할당하는 것으로 add, del 버튼으로 왼쪽박스에 있는 권한을 오록쪽 박스로 추가하여 사용자에게 권한을 부여한다. **한 사용자는 여러개의 권한을 가질 수 있다,&lt;br /&gt;
*입력 및 수정이 끝났으면 상위의 '''저장'''버튼을 누른다. &lt;br /&gt;
[[그림:editUser.jpg|700px]]&lt;/div&gt;</description>
			<pubDate>Thu, 18 Sep 2008 05:19:49 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:UsrGuide</comments>		</item>
		<item>
			<title>CodeUserGuide</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/CodeUserGuide</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 코드데이터 사용하기 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF3.0 공통모듈- 코드 가이드&lt;br /&gt;
*작성자:김민아&lt;br /&gt;
*작성일 : 2008/09/17&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{정보|&lt;br /&gt;
*코드관리란 전체 시스템에서  쓰이는 코드성 데이터에 대해서 관리하는 화면이다.&lt;br /&gt;
*코드관리는 4개의 레벨로 되어있으며, 상위 2개의 코드(업무시스템코드, 상위업무코드)는 상위코드관리에서 관리하고. 하위 2개의 코드(업무코드,코드)는 코드관리 화면에서 관리한다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=상위코드관리=&lt;br /&gt;
*메뉴의 공통모듈&amp;gt;공통코드관리&amp;gt;상위코드관리를 클릭하면 밑에와 같은 화면을 볼 수 있다.&lt;br /&gt;
*왼쪽의 그리드는 업무시스템코드로 최상위코드이다.&lt;br /&gt;
*오른쪽 그리드는 상위업무코드로 업무시스템 하위에 있는 코드를 등록한다.&lt;br /&gt;
*그리드 상단의 추가, 삭제 버튼으로 데이터를 입력, 삭제할 수 있으며, 수정은 그리드에서 직접하며 작업이 끝났으면 최종적으로 상단의 저장버튼을 누름으로써 실제 수정된 데이터가 반영된다. &lt;br /&gt;
*업무시스템코드의 코드ID는 한자리 숫자로 등록하고,&lt;br /&gt;
*상위업무 코드의 코드아이디도 숫자로 등록하되 '''첫번째자리에는 상위코드의 ID'''를 넣는다. &lt;br /&gt;
**예)인사시스템의 코드ID --&amp;gt; 1 임직원관리의 코드ID --&amp;gt; 11&lt;br /&gt;
*상위업무 코드의  상위코드ID는  상위 업무시스템 코드의 ID로 자동 등록된다.올바른 상위코드ID를 넣기 위해서는  입력 시에는 상위코드 ID로 가져갈 업무시스템이 미리 선택되어 있어야한다. &lt;br /&gt;
[[그림:uCode.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
=코드관리=&lt;br /&gt;
*메뉴의 공통모듈&amp;gt;공통코드관리&amp;gt;코드관리를 클릭하면 밑에와 같은 화면을 볼 수 있다.&lt;br /&gt;
*위의 콤보박스는 상위코드관리에서 등록한 코드 업무시스템과 상위업무에 대한 코드들로 상위코드를 선택하고 조회버튼을 클릭한다.&lt;br /&gt;
*왼쪽그리드는 업무코드 오른쪽 그리드는 실제 사용되는 코드들이 관리된다.&lt;br /&gt;
*업무코드의 ID 규칙은  맨 앞에는 알파벳 g가 들어가며 ,가운데에는 상위코드의 ID, 그 다음에 일련의 숫자이다. 예)g21(상위코드ID)01&lt;br /&gt;
*코드ID규칙은  맨 앞에는 알파벳 c가 들어가며 ,가운데에는 알파벳을 뺀 상위코드의 ID,그 다음에 일련의 숫자이다 예)c2101(상위코드ID)001&lt;br /&gt;
*나머지 사용법은 상위업무코드와 동일하다&lt;br /&gt;
[[그림:code.jpg|800px]]&lt;br /&gt;
&lt;br /&gt;
=코드데이터 사용하기=&lt;br /&gt;
*[[commonModule_CodeUserGuide_struts2|struts2기반의 표준웹에서 코드 사용하기]]&lt;br /&gt;
*[[commonModule_CodeUserGuide_ext-js|ext-js 기반에서  코드 사용하기]]&lt;/div&gt;</description>
			<pubDate>Wed, 17 Sep 2008 08:22:08 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:CodeUserGuide</comments>		</item>
		<item>
			<title>BoardUserGuide</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/BoardUserGuide</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 목록보기 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF3.0 공통모듈  -게시판 관리 사용 가이드&lt;br /&gt;
*작성자: 송희정, 김민아&lt;br /&gt;
*작성일 : 2008/09/17&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
=목록보기=&lt;br /&gt;
&lt;br /&gt;
*목록보기에서는 글제목, 작성자, 작성일, 조회수를 나타낸다.&lt;br /&gt;
*글 검색 – 제목, 내용, 작성자, tag 로 검색할 수 있다.&lt;br /&gt;
*글 제목을 클릭하면 글 상세보기를 할 수 있고, 새로운 글을 등록할 때는 쓰기 버튼을 누른다.&lt;br /&gt;
* 답글이 있는 경우 “re” 이미지가 있고, 들여쓰기가 되어있다.&lt;br /&gt;
*오늘 등록한 글인 경우 “new” 이미지가 추가된다.&lt;br /&gt;
[[그림:boardList.jpg|750px|center]]&lt;br /&gt;
&lt;br /&gt;
=글등록하기=&lt;br /&gt;
*목록보기에서 '''쓰기''' 버튼을 클릭하면 다음과 같은 화면이 나타난다.&lt;br /&gt;
*필독해야 하는 글이나 공지성 글의 경우 항상 제일 첫 페이지 앞 줄에 위치해야 하므로 그것에 대한 설정을 '''중요도 여부'''로 선택한다. &lt;br /&gt;
*태그 클리우딩을 하기 위해 태그입력을 한다. 여러 개의 태그를 입력할 경우 쉼표로 구분하여 입력한다.&lt;br /&gt;
[[그림:boardeditex.jpg|750px|center]]&lt;br /&gt;
&lt;br /&gt;
=글상세보기=&lt;br /&gt;
*게시판 목록의 하나를 클릭하면 다음과 같은 화면이 나타난다.&lt;br /&gt;
*추가로 글에 관련된 기능 버튼(수정, 삭제, 답변, 목록 등)이 있다.&lt;br /&gt;
*'''덧글쓰기'''에 덧글을 왼쪽 그림과 같이 입력할 수 있고, 입력을 하면 오른쪽 그림과 같이 덧글이 등록된 것을 볼 수 있다.&lt;br /&gt;
[[그림:boardComment.jpg|500px|]]&lt;br /&gt;
[[그림:boardComment2.jpg|500px]]&lt;/div&gt;</description>
			<pubDate>Wed, 17 Sep 2008 01:19:17 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:BoardUserGuide</comments>		</item>
		<item>
			<title>CommonModule user guide</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/CommonModule_user_guide</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF3.0 공통모듈 upgrade버전 사용가이드&lt;br /&gt;
*작성자:김민아&lt;br /&gt;
*작성일 : 2008/09/01&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
*공통코드&lt;br /&gt;
**상위코드&lt;br /&gt;
[[그림:upcode.jpg|left|800px]]&lt;/div&gt;</description>
			<pubDate>Tue, 09 Sep 2008 09:43:46 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:CommonModule_user_guide</comments>		</item>
		<item>
			<title>Database Spec</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Database_Spec</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 게시판테이블 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF3.0 공통모듈 upgrade 버전 가이드 -테이블 명세서&lt;br /&gt;
*작성자:김민아&lt;br /&gt;
*작성일 : 2008/09/08&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|JCF 웹버전 공통모듈에 대한 테이블 명세서가 있는 곳입니다.}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=공통 코드 테이블=&lt;br /&gt;
*공통코드 테이블은 어플리케이션에서 코드성으로 쓰이는  데이터를  공통으로 관리하는 테이블이다. &lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;rigth&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;background:#ffdead;&amp;quot; colspan=&amp;quot;8&amp;quot; align=&amp;quot;rigth&amp;quot; width=&amp;quot;500&amp;quot;|CODE&lt;br /&gt;
|-&lt;br /&gt;
|No||PK, FK || Column Name || Type || Length || description || null || Default Value&lt;br /&gt;
|-&lt;br /&gt;
|1||PK || ID || varchar2 || 50|| 아이디 ||NN ||-&lt;br /&gt;
|-&lt;br /&gt;
|2||FK ||PARENTID  || varchar2 || 50|| 상위코드아이디 ||NN ||-&lt;br /&gt;
|-&lt;br /&gt;
|3|| - || NAME || varchar2 || 50|| 이름 ||  -||-&lt;br /&gt;
|-&lt;br /&gt;
|4|| -|| DESCRIPTION || varchar2 || 200|| 설명 || - ||-&lt;br /&gt;
|-&lt;br /&gt;
|5||- || CRT_ID || varchar2 || 40|| 생성자 아이디 ||  -||-&lt;br /&gt;
|-&lt;br /&gt;
|6|| -|| CRT_DATE || date || 40|| 생성 일시 || -||sysdate  &lt;br /&gt;
|-&lt;br /&gt;
|7|| -|| UPT_ID|| varchar2|| 40|| 수정자 아이디 || -||-&lt;br /&gt;
|-&lt;br /&gt;
|8|| -|| UPT_DATE|| date || 40|| 수정자 일시 || - ||sysdate  &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=메뉴 테이블=&lt;br /&gt;
*메뉴테이블은 공통모듈 상위에 있는 메뉴트리부분을 관리하는 테이블이다. &lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;rigth&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;background:#ffdead;&amp;quot; colspan=&amp;quot;8&amp;quot; align=&amp;quot;rigth&amp;quot; width=&amp;quot;500&amp;quot;|MENU&lt;br /&gt;
|-|No||PK, FK || Column Name || Type || Length || description || null || Default Value&lt;br /&gt;
|-&lt;br /&gt;
|1||PK || MENU_ID|| VARCHAR2|| 20||메뉴 아이디 ||NN ||-&lt;br /&gt;
|-&lt;br /&gt;
|2||FK || PARENT_ID   || VARCHAR2|| 20|| 상위 메뉴아이디 || -||-&lt;br /&gt;
|-&lt;br /&gt;
|3||-|| MENU_NAME|| VARCHAR2|| 50||메뉴 이름||- ||-&lt;br /&gt;
|-&lt;br /&gt;
|4||- || MENU_LEVEL|| NUMBER|| -|| 메뉴 레벨 || - ||-&lt;br /&gt;
|-&lt;br /&gt;
|5||- || MENU_ORDER  || NUMBER||-|| 메뉴 순서 ||  -||-&lt;br /&gt;
|-&lt;br /&gt;
|6|| -|| MENU_DESC  || VARCHAR2|| 50|| 메뉴 설명|| - ||-&lt;br /&gt;
|-&lt;br /&gt;
|7||- || PROGRAM_PATH|| VARCHAR2|| 100|| 프로그램 패스(메뉴에 등록할 화면) || -||-&lt;br /&gt;
|-&lt;br /&gt;
|8|| -|| CRT_ID|| VARCHAR2|| 50|| 생성자 아이디 || -||-&lt;br /&gt;
|-&lt;br /&gt;
|9|| -||CRT_DATE|| DATE ||- ||생성 일시 || - ||sysdate  &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=권한 테이블=&lt;br /&gt;
*권한 테이블은 사용자에게 주어질 권한에 대해서 관리하는 테이블로 사용자권한테이블, 메뉴권한테이블에서 권한테이블의 아이디를 참조하여 사용된다.&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;rigth&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;background:#ffdead;&amp;quot; colspan=&amp;quot;8&amp;quot; align=&amp;quot;rigth&amp;quot; width=&amp;quot;500&amp;quot;| ROLE&lt;br /&gt;
|-&lt;br /&gt;
|No||PK, FK || Column Name || Type || Length || description || null || Default Value&lt;br /&gt;
|-&lt;br /&gt;
|1||PK || ROLE_ID|| VARCHAR2|| 20||권한 아이디 ||NN ||-&lt;br /&gt;
|-&lt;br /&gt;
|2|| - || ROLE_NAME   || VARCHAR2|| 30|| 권한 이름 || -||-&lt;br /&gt;
|-&lt;br /&gt;
|3||-|| DESCRIPTION|| VARCHAR2|| 50||설명|| - ||-&lt;br /&gt;
|-&lt;br /&gt;
|4||- || SYS_CODE|| VARCHAR2|| 20|| 시스템 코드 || - ||-&lt;br /&gt;
|-&lt;br /&gt;
|8|| -|| CRT_ID|| VARCHAR2||20|| 생성자 아이디 || -||-&lt;br /&gt;
|-&lt;br /&gt;
|9||- ||CRT_DATE|| DATE ||- ||생성 일시 || - ||sysdate  &lt;br /&gt;
|-&lt;br /&gt;
|10|| -|| UPT_ID|| VARCHAR2|| 200|| 수정자 아이디 ||- ||-&lt;br /&gt;
|-&lt;br /&gt;
|11||- ||UPT_DATE|| DATE ||- ||수정 일시 || - ||sysdate  &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=사용자 테이블=&lt;br /&gt;
*사용자 테이블은 사용자에 대해서 관리하는 테이블로 사용자 권한테이블에서 사용자 아이디를 참조하여 사용된다.&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;rigth&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;background:#ffdead;&amp;quot; colspan=&amp;quot;8&amp;quot; align=&amp;quot;rigth&amp;quot; width=&amp;quot;500&amp;quot;|COM_USR&lt;br /&gt;
|-&lt;br /&gt;
|No||PK, FK || Column Name || Type || Length || description || null || Default Value&lt;br /&gt;
|-&lt;br /&gt;
|1||PK || USR_ID|| VARCHAR2|| 40||사용자 아이디 ||NN ||-&lt;br /&gt;
|-&lt;br /&gt;
|2|| - ||PASSWORD|| VARCHAR2|| 40|| 패스워드 || -||-&lt;br /&gt;
|-&lt;br /&gt;
|3||-|| EMP_ID || VARCHAR2|| 40|| 사번 || - ||-&lt;br /&gt;
|-&lt;br /&gt;
|4||- || USR_NAME || VARCHAR2||40|| 사용자 이름 || - ||-&lt;br /&gt;
|-&lt;br /&gt;
|5|| -||EMAIL  || VARCHAR2||40|| 이메일 || -||-&lt;br /&gt;
|-&lt;br /&gt;
|6||- ||PHONE || VARCHAR2|| 40 ||전화번호 || - ||-&lt;br /&gt;
|-&lt;br /&gt;
|7|| -||CPHONE|| VARCHAR2|| 40|| 휴대폰번호 ||- ||-&lt;br /&gt;
|-&lt;br /&gt;
|8||- ||FAX|| VARCHAR2||40 ||팩스번호 || - ||-&lt;br /&gt;
|-&lt;br /&gt;
|9||- ||USRPOS || VARCHAR2|| 40 ||직급 || - ||-&lt;br /&gt;
|-&lt;br /&gt;
|10|| -||DESCRIPTOIN  || VARCHAR2|| 40|| 설명 ||- ||-&lt;br /&gt;
|-&lt;br /&gt;
|11||- ||COMP_CODE || VARCHAR2||40 ||회사코드 || - ||- &lt;br /&gt;
|-&lt;br /&gt;
|12||- ||CRT_ID || VARCHAR2|| 40 ||생성자 아이디 || - ||- &lt;br /&gt;
|-&lt;br /&gt;
|13||- ||CRT_DATE || DATE || -||생성 일시 || - ||sysdate  &lt;br /&gt;
|-&lt;br /&gt;
|14|| -||UPT_ID  || VARCHAR2|| 40|| 수정자 아이디 ||- ||-&lt;br /&gt;
|-&lt;br /&gt;
|15||- ||UPT_DATE || DATE ||- ||수정 일시 || - ||sysdate  &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=권한 메뉴테이블=&lt;br /&gt;
*권한 메뉴테이블은 권한 ID와 메뉴 ID로 구성된 테이블로  해당 권한을 가진 사람에게만 메뉴가 보여지도록 관리하는 테이블이다. &lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;rigth&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;background:#ffdead;&amp;quot; colspan=&amp;quot;8&amp;quot; align=&amp;quot;rigth&amp;quot; width=&amp;quot;500&amp;quot;| ROLE_MENU&lt;br /&gt;
|-&lt;br /&gt;
|No||PK, FK || Column Name || Type || Length || description || null || Default Value&lt;br /&gt;
|-&lt;br /&gt;
|1||PK || ROLE_ID|| VARCHAR2|| 32||권한 아이디 ||NN ||-&lt;br /&gt;
|-&lt;br /&gt;
|2|| PK || MENU_ID  || VARCHAR2|| 32|| 메뉴 아이디 || NN ||-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=사용자 권한 테이블=&lt;br /&gt;
*사용자 권한 테이블은 사용자 ID와 권한 ID로 구성된 테이블로 사용자에게 권한을 할당하여 해당 권한에 매핑한 메뉴들이 보여지는 것에 대해 관리하는 테이블이다.&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;rigth&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;background:#ffdead;&amp;quot; colspan=&amp;quot;8&amp;quot; align=&amp;quot;rigth&amp;quot; width=&amp;quot;500&amp;quot;| USR_ROLE&lt;br /&gt;
|-&lt;br /&gt;
|No||PK, FK || Column Name || Type || Length || description || null || Default Value&lt;br /&gt;
|-&lt;br /&gt;
|1||PK || USER_ID|| VARCHAR2|| 20||사용자 아이디 ||NN ||-&lt;br /&gt;
|-&lt;br /&gt;
|2|| PK || ROLE_ID  || VARCHAR2||20|| 권한 아이디 || NN ||-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=게시판테이블=&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;rigth&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;background:#ffdead;&amp;quot; colspan=&amp;quot;8&amp;quot; align=&amp;quot;rigth&amp;quot; width=&amp;quot;500&amp;quot;| BBS&lt;br /&gt;
|-&lt;br /&gt;
|No||PK, FK || Column Name || Type || Length || description || null || Default Value&lt;br /&gt;
|-&lt;br /&gt;
|1||PK ||ID||number||-||아이디||NN||-&lt;br /&gt;
|-&lt;br /&gt;
|2||-||SUBJECT ||varchar2||200||글 제목||NN||-&lt;br /&gt;
|-&lt;br /&gt;
|3||-||CONTENT ||text||-||글 내용||NN||-&lt;br /&gt;
|-&lt;br /&gt;
|4||-||REGIST_DATE|| date||-||등록일||NN||-&lt;br /&gt;
|-&lt;br /&gt;
|5||-||HIT ||number||-||조회수||NN||0&lt;br /&gt;
|-&lt;br /&gt;
|6||-||PRODUCT ||varchar2||100||글구분||NN||-&lt;br /&gt;
|-&lt;br /&gt;
|7||-||REPLY_COUNT ||number||-||답변글개수||NN||0&lt;br /&gt;
|-&lt;br /&gt;
|8||-||REGISTER_NAME ||varchar2||100||등록자 이름||-||-&lt;br /&gt;
|-&lt;br /&gt;
|9||-||EMAIL ||varchar2||100||등록자 이메일||-||-&lt;br /&gt;
|-&lt;br /&gt;
|10||-||PASSWORD ||varchar2||10||등록/삭제시 비밀번호||-||-&lt;br /&gt;
|-&lt;br /&gt;
|11||-||PARENT_ID ||number||-||부모글 아이디||-||-&lt;br /&gt;
|-&lt;br /&gt;
|12||-||ANSWER_ORDER ||number||-||답글순서||-||-&lt;br /&gt;
|-&lt;br /&gt;
|13||-||INDENT ||number||-||들여쓰기크기||-||-&lt;br /&gt;
|-&lt;br /&gt;
|14||-||isHTML || char||1||글 내용의 HTML 태그 적용여부||-||-&lt;br /&gt;
|-&lt;br /&gt;
|15||-||PRIORITY ||varchar2||10||글 우선순위||-||-&lt;br /&gt;
|-&lt;br /&gt;
|16||-||REGISTER_ID ||varchar2||10||등록자 ID||-||-&lt;br /&gt;
|-&lt;br /&gt;
|17||-||ATTACHMENT_ID ||varchar2||20||첨부파일 아이디||-||-&lt;br /&gt;
|-&lt;br /&gt;
|18||-||KEYWORD ||varchar2||100||글 키워드||-||-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;rigth&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;background:#ffdead;&amp;quot; colspan=&amp;quot;8&amp;quot; align=&amp;quot;rigth&amp;quot; width=&amp;quot;500&amp;quot;| BBS_COMMENT&lt;br /&gt;
|-&lt;br /&gt;
|No||PK, FK || Column Name || Type || Length || description || null || Default Value&lt;br /&gt;
|-&lt;br /&gt;
|1||PK||ID ||varchar2||20||댓글 아이디||NN||-&lt;br /&gt;
|-&lt;br /&gt;
|2||PK||BBS_ID ||number||-||관련 게시글 아이디||NN||-&lt;br /&gt;
|-&lt;br /&gt;
|3||-||COMMENT ||varchar2||200||댓글||NN||-&lt;br /&gt;
|-&lt;br /&gt;
|4||-||REGIST_DATE|| date||-||등록일||-||-&lt;br /&gt;
|-&lt;br /&gt;
|5||-||REGISTER_NAME ||varchar2||100||등록자 이름||-||-&lt;br /&gt;
|-&lt;br /&gt;
|6||-||REGISTER_ID ||varchar2||10||등록자 ID||-||-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;5&amp;quot; cellspacing=&amp;quot;1&amp;quot; align=&amp;quot;rigth&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;background:#ffdead;&amp;quot; colspan=&amp;quot;8&amp;quot; align=&amp;quot;rigth&amp;quot; width=&amp;quot;500&amp;quot;| BBS_TAG&lt;br /&gt;
|-&lt;br /&gt;
|No||PK, FK || Column Name || Type || Length || description || null || Default Value&lt;br /&gt;
|-&lt;br /&gt;
|1||PK||TAG ||varchar2||20||태그||NN||-&lt;br /&gt;
|-&lt;br /&gt;
|2||PK||BBS_ID ||number||-||관련 게시글 아이디||NN||-&lt;br /&gt;
|-&lt;br /&gt;
|3||-||REGIST_DATE||date||-||등록일자||NN||-&lt;br /&gt;
|}&lt;/div&gt;</description>
			<pubDate>Mon, 08 Sep 2008 09:01:15 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Database_Spec</comments>		</item>
		<item>
			<title>JCFStarterKit Installation</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/JCFStarterKit_Installation</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* JCFStarterKit 활용목적 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물: JCFStarterKit1.0.0로 개인개발환경 설치하기&lt;br /&gt;
*작성자: 서경진&lt;br /&gt;
*최초작성일 : 2008/09/02&lt;br /&gt;
*최종작성일 : 2008/09/05&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
* 이 문서에는 JCFStarterKit1.0.0을 활용하여 개인개발환경을 설치하는 것을 설명할 것이다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=JCFStarterKit 활용목적=&lt;br /&gt;
*JCFStarterKit은 다음과 목적으로 개발되었다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_purpose.JPG|750px|thumb|center|JCFStarterKit1.0.0 활용목적]]&lt;br /&gt;
&lt;br /&gt;
=JCFStarterKit1.0.0 다운받기=&lt;br /&gt;
*[[media:StarterKit.zip|JCFStarterKit1.0.0 다운로드 (zip) : WIN2000/WINXP/Vista]]&lt;br /&gt;
**JCFStarterKit 설치를 위해 C:드라이브에 470MB이상의 공간이 필요하다.&lt;br /&gt;
&lt;br /&gt;
=JCFStarterKit1.0.0 설치하기=&lt;br /&gt;
*위에 StarterKit.zip 파일을 다운로드 받은 후 압축을 풀면 다음과 같이 JCFStarterKit1.0.0.exe와 JCFStarterKit1.0.0.exe.txt 파일을 확인할 수 있다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_icon_exec.jpg|500px|thumb|center|압축을 푼 StarterKit 디렉터리의 JCFStarterKit1.0.0 내용 확인]]&lt;br /&gt;
&lt;br /&gt;
*JCFStarterKit1.0.0.exe 파일을 더블 클릭하여 실행시키면 다음과 같은 설치 마법사가 실행된다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_install_01.jpg|400px|thumb|center|JCFStarterKit 설치]]&lt;br /&gt;
&lt;br /&gt;
*다음 버튼을 클릭한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_install_02.jpg|400px|thumb|center|JCFStarterKit 설치 - 라이센스 (동의)]]&lt;br /&gt;
&lt;br /&gt;
*동의함 버튼을 클릭한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_install_03.jpg|400px|thumb|center|JCFStarterKit 설치 - 라이센스]]&lt;br /&gt;
&lt;br /&gt;
*다음 버튼을 클릭한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_install_04.jpg|400px|thumb|center|JCFStarterKit 설치- 설치 폴더 선택]]&lt;br /&gt;
&lt;br /&gt;
*가능하면 디폴트로 설치한다. (C 드라이브에 470MB 이상의 공간이 필요함)&lt;br /&gt;
*디폴트로 설치하지 않을 경우, 설치 후 이클립스를 실행시키고 설정을 변경해야 한다.&lt;br /&gt;
*설치시작 버튼을 클릭한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_install_05.jpg|400px|thumb|center|JCFStarterKit 설치 진행]]&lt;br /&gt;
&lt;br /&gt;
*설치가 시작된다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_install_07.jpg|400px|thumb|center|JCFStarterKit 설치 진행 중]]&lt;br /&gt;
&lt;br /&gt;
*설치 진행률이 증가되는 것을 확인할 수 있다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_install_end.jpg|400px|thumb|center|JCFStarterKit 설치 완료]]&lt;br /&gt;
&lt;br /&gt;
*설치가 정상적으로 완료되었으면 확인 버튼을 클릭한다.&lt;br /&gt;
*설치가 정상적으로 완료되었는지 확인하기 위해 다음과 같이 JCFStarterKit 설치 폴더를 확인한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_install_directorystructure.jpg|500px|thumb|center|JCFStarterKit 설치 폴더 확인]]&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_startup_menu.jpg|500px|thumb|center|JCFStarterKit 시작 메뉴 확인]]&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_install_programs.jpg|500px|thumb|center|JCFStarterKit 프로그램 메뉴 확인]]&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_uninstall_menu.jpg|500px|thumb|center|제어판의 프로그램 추가/삭제에서 JCFStarterKit1.0.0 설치 확인]]&lt;br /&gt;
&lt;br /&gt;
*설치가 완료되면 다음과 같은 환경변수가 자동으로 설정된다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. JAVA_HOME = C:\j2e\java\jdk1.6.0_06&lt;br /&gt;
2. M2_HOME = C:\j2e\tools\maven\apache-maven-2.0.9&lt;br /&gt;
3. CATALINA_HOME = C:\j2e\was\apache-tomcat-6.0.16&lt;br /&gt;
4. path = %path%;%JAVA_HOME%\bin;%M2_HOME%\bin;%CATALINA_HOME%\bin&lt;br /&gt;
5. classpath = .;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*다음과 같이 시스템 등록정보&amp;gt;고급&amp;gt;환경변수에서 위의 설정값들이 정상적으로 설정된 것을 확인할 수 있다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_install_java_home.jpg|280px|JAVA_HOME 환경변수 설정]]&lt;br /&gt;
[[그림:JCFStarterKit_install_m2_home.jpg|280px|M2_HOME 환경변수 설정]]&lt;br /&gt;
[[그림:JCFStarterKit_install_catalina_home.jpg|280px|CATALINA_HOME 환경변수 설정]]&lt;br /&gt;
[[그림:JCFStarterKit_install_path.jpg|280px|path 환경변수 설정]]&lt;br /&gt;
&lt;br /&gt;
=eclipse 구동하기=&lt;br /&gt;
*설치된 JCFStarterKit에 포함된 eclipse IDE를 구동하기 위해 두 가지 선행작업이 필요하다.&lt;br /&gt;
**eclipse 실행 단축 아이콘에 JVM 메모리 관련 인수가 설정된 단축 아이콘 복사하기&lt;br /&gt;
**eclipse WTP에서 미리 설치된 Tomcat6.0 서버를 제거하고 다시 설치하기&lt;br /&gt;
&lt;br /&gt;
==단축 아이콘 복사하기==&lt;br /&gt;
*바탕화면에 복사된 eclipse 바로가기로 eclipse를 구동시키기 위해서 설치 폴더 ide\eclipse에 있는 eclipse 바로가기를 바탕화면과 시작메뉴/프로그램에 다음과 같이 단축 아이콘을 복사(덮어쓰기)한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_copy_eclipse_shortcut.jpg|500px|thumb|center|바탕화면/프로그램 메뉴에 JCFStarterKit 단축 아이콘 복사하기]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_copy_wallpaper_eclipseshortcut.jpg|500px|thumb|center|바탕화면 JCFStarterKit 단축 아이콘 확인]]&lt;br /&gt;
&lt;br /&gt;
*이클립스 실행 시 발생할 수 있는 메모리 문제를 예방하기 위해서 다음과 같이 설정된 단축 아이콘을 사용한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_eclipse_shortcut_properties.jpg|300px|thumb|center|바탕화면 JCFStarterKit 단축 아이콘 복사완료 확인]]&lt;br /&gt;
&lt;br /&gt;
==eclipse 실행하기==&lt;br /&gt;
*바탕화면에 있는 eclipse 바로가기를 실행시키면 다음과 같이 workspace를 설정하는 화면이 출력된다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_workspace_launcher.jpg|400px|thumb|center|workspace 선택화면]]&lt;br /&gt;
&lt;br /&gt;
*workspace를 선택하고 OK를 클릭하면 다음과 같이 eclipse가 실행된다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_eclipse_tomcat_exec.jpg|500px|thumb|center|eclipse 실행화면]]&lt;br /&gt;
&lt;br /&gt;
==WTP 환경 수정하기==&lt;br /&gt;
&lt;br /&gt;
=JCFStarterKit1.0.0 제거하기 (Uninstallation)=&lt;br /&gt;
*설치된 JCFStarterKit1.0.0을 제거하기 방법은 두 가지가 있다.&lt;br /&gt;
**시작 프로그램에 있는 Uninstall JCFStarterKit1.0.0을 실행하는 방법&lt;br /&gt;
**프로그램 추가/삭제에 있는 JCFStarterKit1.0.0을 선택하여 삭제하는 방법&lt;br /&gt;
*위의 두 가지 중 하나를 선택하여 실행하면 다음과 같은 창이 출력된다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_uninstall_popup.jpg|250px|thumb|center|Uninstall 실행 시 최초 팝업 화면]]&lt;br /&gt;
&lt;br /&gt;
*예 버튼을 클릭하면 제거가 진행되는 것을 확인할 수 있다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_uninstall_01.jpg|400px|thumb|center|JCFStarterKit 제거 진행 화면]]&lt;br /&gt;
&lt;br /&gt;
*제거 진행 시 workspace나 다른 폴더에 사용자가 추가적한 파일에 대한 삭제는 진행과정 중 팝업창을 통해 삭제 여부를 결정하게 된다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_uninstall_02.jpg|400px|thumb|center|JCFStarterKit 제거 완료]]&lt;br /&gt;
&lt;br /&gt;
*제거가 완료되면 확인 버튼을 클릭한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_uninstall_complete.jpg|500px|thumb|center|JCFStarterKit 제거 확인]]&lt;br /&gt;
&lt;br /&gt;
*정상적으로 제거가 완료되었는지 확인하기 위해 바탕화면의 단축 아이콘이 삭제되었는지 다음과 같이 확인할 수 있다.&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFStarterKit_uninstall_wallpaper.jpg|500px|thumb|center|바탕화면에 JCFStarterKit 단축 아이콘 제거 확인]]&lt;/div&gt;</description>
			<pubDate>Tue, 02 Sep 2008 00:55:37 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:JCFStarterKit_Installation</comments>		</item>
		<item>
			<title>CommonModule</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/CommonModule</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF3.0 공통모듈 upgrade 버전 가이드 &lt;br /&gt;
*작성자:김민아&lt;br /&gt;
*작성일 : 2008/09/01&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
*환경 정보&lt;br /&gt;
**WAS : Tomcat 6.0&lt;br /&gt;
**jdk :jdk 1.6.0_06&lt;br /&gt;
**DB : oracle10g&lt;br /&gt;
*[[source download|소스 다운받기]]&lt;br /&gt;
*[[CommonModule install|개인 컴퓨터에 설치하기]]&lt;br /&gt;
*ERD 보기&lt;br /&gt;
[[그림:commModule.jpg|center|850px|thumb|JCF3.0 공통모듈 upgrade 버전  erd]]&lt;br /&gt;
*[[Database Spec|테이블 명세서]]&lt;br /&gt;
*[[CommonModule user guide|공통모듈 사용가이드]]&lt;br /&gt;
**[[MenuGuide|메뉴관리]]&lt;br /&gt;
**[[roleGuide|권한관리]]&lt;br /&gt;
**[[UsrGuide|사용자관리]]&lt;br /&gt;
**[[CodeUserGuide|코드관리]]&lt;br /&gt;
**[[BoardUserGuide|게시판]]&lt;/div&gt;</description>
			<pubDate>Mon, 01 Sep 2008 00:35:59 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:CommonModule</comments>		</item>
		<item>
			<title>JCF Quick Education</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/JCF_Quick_Education</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물 : JCF 비정기교육 자료&lt;br /&gt;
* 최초작성일 : 2008/08/14&lt;br /&gt;
* 최종작성일 : 2008/08/18&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{경고|이 곳은 JCF 비정기교육에 대한 강의자료가 있는 방입니다. }}&lt;br /&gt;
&lt;br /&gt;
=준비사항=&lt;br /&gt;
*[[JCFStarterKit_Installation|JCFStarterKit 기반의 개인 개발환경 설치하기]]&lt;br /&gt;
*[[media:jcf_basicSample_cr(2).zip|샘플소스 다운 받기]]&lt;br /&gt;
*[[media:mysql.zip|mysql 다운받기]]&lt;br /&gt;
*JCF 공통모듈 설치&lt;br /&gt;
&lt;br /&gt;
=1일차=&lt;br /&gt;
*JCF 공통모듈 기반의 아키텍처 이해&lt;br /&gt;
*[[media:JCF.pdf|JCF 소개 (pdf자료)]]&lt;br /&gt;
*[[media:JCFOverviewAndArchitecture.pdf|JCF 아키텍처 (pdf자료)]]&lt;br /&gt;
*Quick Start로 예제 돌려보기&lt;br /&gt;
**Struts2 + Spring + IBatis&lt;br /&gt;
*JCF 공통모듈 이해하기&lt;br /&gt;
**Quick Start와 JCF 공통모듈 차이점 이해하기&lt;br /&gt;
*JCF 아키텍처 이해하기&lt;br /&gt;
**[[media:FW_STRUTS2.pdf|Struts2 (pdf자료)]]&lt;br /&gt;
**[[media:FW_SPRING2.pdf|Spring2.5 (pdf자료)]]&lt;br /&gt;
***Spring IoC&lt;br /&gt;
***Spring AOP&lt;br /&gt;
**[[media:FW_IBATIS2.pdf|iBatis2.3 (pdf자료)]]&lt;br /&gt;
***iBatis Cache 적용하기&lt;br /&gt;
***iBatis Dynamic Query 사용하기&lt;br /&gt;
*[[media:TransactionAndCache.pdf|트랜잭션처리 (pdf자료)]]&lt;br /&gt;
&lt;br /&gt;
=2일차=&lt;br /&gt;
*[[media:BasicDevelopment.pdf|기본 모듈 개발하기 (pdf자료)]]&lt;br /&gt;
*WTP Dynamic Web Project 기반의 Sample 웹 어플리케이션 구현하기&lt;br /&gt;
*[[media:Logging.pdf|log4j를 이용한 로깅처리하기 (pdf자료)]]&lt;br /&gt;
&lt;br /&gt;
=Appendix=&lt;br /&gt;
*[[media:CodeDev.pdf|코드처리하기 (pdf자료)]]&lt;br /&gt;
*[[media:Search_Paging_Sorting.pdf|검색, 페이징, 정렬 처리하기 (pdf자료)]]&lt;br /&gt;
*[[media:Security.pdf|보안처리하기 (pdf자료)]]&lt;br /&gt;
*[[media:MasterAndDetail.pdf|Master/Detail 처리하기 (pdf자료)]]&lt;br /&gt;
*[[media:TagLibrary.pdf|Tag Library 활용하기 (pdf자료)]]&lt;br /&gt;
*[[media:Debugging.pdf|Debugging하기 (pdf자료)]]&lt;br /&gt;
*[[media:Testing.pdf|Testing (pdf자료)]]&lt;br /&gt;
*[[media:ANT.pdf|Ant 활용하기 (pdf자료)]]&lt;/div&gt;</description>
			<pubDate>Sun, 17 Aug 2008 03:35:02 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:JCF_Quick_Education</comments>		</item>
		<item>
			<title>SetMessage</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/SetMessage</link>
			<description>&lt;p&gt;바꾼내용 간추리기: New page: &amp;lt;code lang='javascript'&amp;gt; function setMessage(errMsg, showType) { 	//alert(&amp;quot;showType&amp;quot;+showType+&amp;quot;errMsg&amp;quot;+errMsg); 	//alert(showType); 	//alert(errMsg); 	if ( showType == &amp;quot;ALERT&amp;quot;) { 		alert(e...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;code lang='javascript'&amp;gt;&lt;br /&gt;
function setMessage(errMsg, showType)&lt;br /&gt;
{&lt;br /&gt;
	//alert(&amp;quot;showType&amp;quot;+showType+&amp;quot;errMsg&amp;quot;+errMsg);&lt;br /&gt;
	//alert(showType);&lt;br /&gt;
	//alert(errMsg);&lt;br /&gt;
	if ( showType == &amp;quot;ALERT&amp;quot;) {&lt;br /&gt;
		alert(errMsg);&lt;br /&gt;
	} else if ( showType == &amp;quot;STARUS&amp;quot; ) {		&lt;br /&gt;
		div_msg.stMsg.text = errMsg; &lt;br /&gt;
	} else if ( showType == &amp;quot;CONFIRM&amp;quot; ) {&lt;br /&gt;
		retVal = confirm(errMsg);&lt;br /&gt;
		return retVal; &lt;br /&gt;
	} else {&lt;br /&gt;
		stMsg.Value = errMsg;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</description>
			<pubDate>Wed, 13 Aug 2008 01:34:34 GMT</pubDate>			<dc:creator>Itanywhere</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:SetMessage</comments>		</item>
		<item>
			<title>Aop:pointcut의 정규표현식</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Aop:pointcut%EC%9D%98_%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==&amp;lt;aop:config&amp;gt;==&lt;br /&gt;
*트랜젝션을 처리할 대상을 넣음&lt;br /&gt;
{{정보|참조:&lt;br /&gt;
*[[%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98#.EC.8A.A4.ED.94.84.EB.A7.81.EC.97.90.EC.84.9C_.ED.8A.B8.EB.9E.9C.EC.9E.AD.EC.85.98_.EC.84.A0.EC.96.B8.ED.95.98.EA.B8.B0|스프링에서 트랜잭션 선언하기]]&lt;br /&gt;
}}&lt;br /&gt;
==공통모듈에서의 정규표현식==&lt;br /&gt;
*applicationContext-aop.xml&lt;br /&gt;
&amp;lt;code lang='xml'&amp;gt;&lt;br /&gt;
	&amp;lt;aop:config&amp;gt;&lt;br /&gt;
	   &amp;lt;aop:pointcut id=&amp;quot;serviceOperation&amp;quot; expression=&amp;quot;execution(* *..*Service.*(..))&amp;quot;/&amp;gt;&lt;br /&gt;
	   &amp;lt;aop:advisor advice-ref=&amp;quot;txAdvice&amp;quot; pointcut-ref=&amp;quot;serviceOperation&amp;quot;/&amp;gt;	&lt;br /&gt;
	&amp;lt;/aop:config&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*설명&lt;br /&gt;
**&amp;lt;nowiki&amp;gt;*_&amp;lt;/nowiki&amp;gt;:모든 형태의 가시성(public,proteced..)을 가지는 메소드&lt;br /&gt;
**&amp;lt;nowiki&amp;gt;*..&amp;lt;/nowiki&amp;gt;:모든 패키지명&lt;br /&gt;
**&amp;lt;nowiki&amp;gt;*Service&amp;lt;/nowiki&amp;gt;:클래스명이 Service로 끝나는 클래스&lt;br /&gt;
**&amp;lt;nowiki&amp;gt;.*(..))&amp;lt;/nowiki&amp;gt;:모든 형태의 파라미터를 가지는 모든 메소드&lt;br /&gt;
{{주의사항|&lt;br /&gt;
'''&amp;lt;nowiki&amp;gt;* *..*Service.*(..))&amp;lt;/nowiki&amp;gt;''': 모든형태의 가시성을 가지는 모든 패키지명에서 클래스명이 Service로 끝나는 클래스의 모든 형태의 파라미터&lt;br /&gt;
}}&lt;/div&gt;</description>
			<pubDate>Tue, 12 Aug 2008 09:24:36 GMT</pubDate>			<dc:creator>Itanywhere</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Aop:pointcut%EC%9D%98_%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D</comments>		</item>
		<item>
			<title>X-Internet 로그인</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/X-Internet_%EB%A1%9C%EA%B7%B8%EC%9D%B8</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 마이플렛폼 로그인 화면 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==개요==&lt;br /&gt;
*현재 common module은 표준웹에서 로그인 하여 x-internet 전용창을 call하는 흐름&lt;br /&gt;
*장단점&lt;br /&gt;
**마이플렛폼 개발툴에서 Launch project로 실행해 볼 수 없음&lt;br /&gt;
**어플리케이션 test 시 마이플렛폼 개발툴에서 개발한후 다시 web 브라우져를 통해 로그인해야하는 번거로움이 있음&lt;br /&gt;
**표준웹에서 가졌던 JSESSIONID와 마이플렛폼 전용브라우져의 JSESSIONID가 다르므로 login이후 JSESSIONID을 client 레지스트리에 넣어주고 마이플렛폼 브라우져에서 JSESSIONID를 빼는 작업을 해야함. &lt;br /&gt;
**마이플렛폼 로그인을 할 경우는 autocookie를 통해 서버단 jsessionid를 가져오므로 setReg,getReg할 필요 없음. 단지 JSESSIONID란 이름으로 share변수를 선언하기만 하면 됨&lt;br /&gt;
[[그림:weblogin.png|900px|center|thumb|표준웹로그인 기반 흐름]]&lt;br /&gt;
[[그림:milogin.png|900px|center|thumb|마이플렛폼 로그인 기반 흐름]]&lt;br /&gt;
==마이플렛폼 개발툴에서 (PID) 로그인 하기==&lt;br /&gt;
===마이플렛폼 용 startxml 추가 생성하여 pid에 프로젝트 등록===&lt;br /&gt;
*dev_common_ci_main.xml 생성&lt;br /&gt;
**initurl=&amp;quot;CommonGroup::login.xml&amp;quot; 로 교체&lt;br /&gt;
**OnBeforeExit=&amp;quot;Common_Exit&amp;quot;를 삭제&lt;br /&gt;
*pid에 project manager에 dev_common_ci_main.xml로 등록&lt;br /&gt;
===마이플렛폼 로그인 화면===&lt;br /&gt;
{{경고|&lt;br /&gt;
*마이플렛폼의 option에서 autocokiee를 true로 하면(기본값 true) 자동으로 서버단의 쿠키값을 마이플렛폼의 global 변수로 가져옴&lt;br /&gt;
*share 변수로 JSESSIONID를 선언할 경우 자동으로 서버단의 sessionID가 JSESSIONID변수로 들어감&lt;br /&gt;
}}&lt;br /&gt;
*auth/authResult.action 호출시 j_username과 j_password 를 파라미터로 가지고 감&lt;br /&gt;
&amp;lt;code lang='javascript'&amp;gt;&lt;br /&gt;
function btnLogin_OnClick(obj)&lt;br /&gt;
{&lt;br /&gt;
	var queryString = &amp;quot;&amp;quot;;&lt;br /&gt;
	queryString += &amp;quot;?j_username=&amp;quot; + edUserName.Text;&lt;br /&gt;
	queryString += &amp;quot;&amp;amp;j_password=&amp;quot; + edPassword.Text;&lt;br /&gt;
	GV_IS_DEV = true;&lt;br /&gt;
		&lt;br /&gt;
			transaction(&lt;br /&gt;
			&amp;quot;Login&amp;quot;, //strServiceID&lt;br /&gt;
			&amp;quot;Common::login/loginResult.action&amp;quot; + queryString,  //strUrl&lt;br /&gt;
			&amp;quot;&amp;quot;, //arrParmeter&lt;br /&gt;
			&amp;quot;&amp;quot;,&lt;br /&gt;
			 &amp;quot;&amp;quot;,// returnDataSet ID&lt;br /&gt;
			&amp;quot;fn_LoginCallBack&amp;quot;);  // fnCallback			&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function fn_LoginCallBack() &lt;br /&gt;
{&lt;br /&gt;
                //마이플렛폼으로 로그인할 경우 jsessionID를 레지스트리에 넣어줄 필요가 없음&lt;br /&gt;
		//alert(JSESSIONID);                 &lt;br /&gt;
		//setReg(&amp;quot;GlobalVal&amp;quot;,JSESSIONID);&lt;br /&gt;
		go(&amp;quot;CommonGroup::MainFrame.xml&amp;quot;); &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===loginAction===&lt;br /&gt;
&amp;lt;code lang='java'&amp;gt;&lt;br /&gt;
function btnLogin_OnClick(obj)&lt;br /&gt;
	public void authResult() { &lt;br /&gt;
		&lt;br /&gt;
		SecurityContext securityContext = SecurityContextHolder.getContext();&lt;br /&gt;
		AuthenticationProcessingFilter authenticationProcessingFilter = (AuthenticationProcessingFilter)SpringContextHolder.getBean(&amp;quot;authenticationProcessingFilter&amp;quot;);&lt;br /&gt;
		Authentication authentication = authenticationProcessingFilter.attemptAuthentication(getRequest());&lt;br /&gt;
		if (authentication.isAuthenticated()){&lt;br /&gt;
			securityContext.setAuthentication(authentication);&lt;br /&gt;
			System.out.println(getRequest().getSession().getId());&lt;br /&gt;
     		        //마이플렛폼에 autocookie값이 true일 경우에는 자동으로 마이플렛폼이 서버단 cookie값을 가져오기 때문에 Outchanel로 jsessionID를 넣어줄 필요가 없음&lt;br /&gt;
                       //OutChannel.setVariable(&amp;quot;JSESSIONID&amp;quot;, getRequest().getSession().getId());&lt;br /&gt;
		       //OutChannel.send();&lt;br /&gt;
		}else{&lt;br /&gt;
			OutChannel.error(&amp;quot;-2000&amp;quot;, &amp;quot;login fail&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</description>
			<pubDate>Tue, 12 Aug 2008 06:59:35 GMT</pubDate>			<dc:creator>Itanywhere</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:X-Internet_%EB%A1%9C%EA%B7%B8%EC%9D%B8</comments>		</item>
		<item>
			<title>TimeOut Message</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/TimeOut_Message</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* srv_fn_AsyncCall */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==sessiontimeout 설정==&lt;br /&gt;
===was에서 설정===&lt;br /&gt;
**tomcat의 경우 conf 폴더 밑에 web.xml에서 설정함 (기본값 30분)&lt;br /&gt;
&amp;lt;code lang='xml'&amp;gt;&lt;br /&gt;
 &amp;lt;session-config&amp;gt;&lt;br /&gt;
        &amp;lt;session-timeout&amp;gt;30&amp;lt;/session-timeout&amp;gt;&lt;br /&gt;
    &amp;lt;/session-config&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===application내에서 설정===&lt;br /&gt;
*web/web-inf/web.xml에서 설정(was설정보다 우선함)&lt;br /&gt;
&amp;lt;code lang='xml'&amp;gt;&lt;br /&gt;
 &amp;lt;session-config&amp;gt;&lt;br /&gt;
        &amp;lt;session-timeout&amp;gt;30&amp;lt;/session-timeout&amp;gt;&lt;br /&gt;
    &amp;lt;/session-config&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===마이플렛폼에서 설정===&lt;br /&gt;
*pid 상에서 설정가능함.&lt;br /&gt;
*서버에 한번 요청을 한후 response가 오는 시간을 설정&lt;br /&gt;
&lt;br /&gt;
==spring security에서 세션timeout exception 잡아내기==&lt;br /&gt;
*exceptionTranslationFilter에서 authenticationEntryPoint property를 수정, 세션종료후 서버단 호출시 exception잡아서 loginFormUrl을 호출 &lt;br /&gt;
*loginFormUrl은 /commonJSP/loginError.jsp이며 jsp에서 에러코드를 던짐&lt;br /&gt;
*applicationContext-security.xml 수정&lt;br /&gt;
&lt;br /&gt;
*filterInvocationInterceptor bean을 아래와 같이 수정하여 모든 action에 대해 spring security가 권한을 intercept 할수있도록 함&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang='xml'&amp;gt;&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;filterInvocationInterceptor&amp;quot;&lt;br /&gt;
			class=&amp;quot;org.acegisecurity.intercept.web.FilterSecurityInterceptor&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;property name=&amp;quot;authenticationManager&amp;quot; ref=&amp;quot;authenticationManager&amp;quot; /&amp;gt;&lt;br /&gt;
		  	&amp;lt;property name=&amp;quot;accessDecisionManager&amp;quot; ref=&amp;quot;accessDecisionManager&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		  	&amp;lt;!--with db//filterInvocationDefinitionSource --&amp;gt;&lt;br /&gt;
		  	  &amp;lt;!-- &lt;br /&gt;
			&amp;lt;property name=&amp;quot;objectDefinitionSource&amp;quot;&amp;gt;&amp;lt;ref bean=&amp;quot;filterInvocationDefinitionSource&amp;quot;/&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
			 --&amp;gt;&lt;br /&gt;
			&amp;lt;property name=&amp;quot;objectDefinitionSource&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;value&amp;gt;&lt;br /&gt;
					CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON&lt;br /&gt;
					PATTERN_TYPE_APACHE_ANT&lt;br /&gt;
				    /login.jsp*=ROLE_ANONYMOUS&lt;br /&gt;
				    /j_acegi_logout*=ROLE_ANONYMOUS&lt;br /&gt;
				    /login/*.action*=ROLE_ANONYMOUS&lt;br /&gt;
					&amp;lt;!-- test하는 모든 권한을 넣어주세요&lt;br /&gt;
						ex)/**/*.action=ROLE_COMMON_ADMIN,ROLE_CIMS_ADMIN,ROLE_ACC_ADMIN&lt;br /&gt;
					--&amp;gt;&lt;br /&gt;
				    /**/*.action=ROLE_COMMON_ADMIN				  		    &lt;br /&gt;
				&amp;lt;/value&amp;gt;			 &lt;br /&gt;
			&amp;lt;/property&amp;gt;&lt;br /&gt;
&lt;br /&gt;
		&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*filterInvocationInterceptor bean에서 url 패턴별로 권한을 검사한 후 권한이 없는 요청이 왔을때 exceptionTranslationFilter에서 처리&lt;br /&gt;
&amp;lt;code lang='xml' em='5,6'&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;exceptionTranslationFilter&amp;quot;&lt;br /&gt;
		class=&amp;quot;org.acegisecurity.ui.ExceptionTranslationFilter&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!--부여받은 롤이 없어서 롤이 anonymous일때--&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;authenticationEntryPoint&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;bean class=&amp;quot;org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint&amp;quot;&amp;gt;		&lt;br /&gt;
			   &amp;lt;property name=&amp;quot;loginFormUrl&amp;quot; value=&amp;quot;/commonJSP/loginError.jsp&amp;quot;  /&amp;gt;&lt;br /&gt;
		           &amp;lt;property name=&amp;quot;serverSideRedirect&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/bean&amp;gt;&lt;br /&gt;
		&amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;!-- 권한이 anonymous가 아니지만 허락된 권한이 아닐떄--&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;accessDeniedHandler&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;bean&lt;br /&gt;
				class=&amp;quot;org.acegisecurity.ui.AccessDeniedHandlerImpl&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;property name=&amp;quot;errorPage&amp;quot; value=&amp;quot;/commonJSP/loginError.jsp&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;/bean&amp;gt;&lt;br /&gt;
		&amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==loginFormUrl에서 세션timeout 에러코드와 에러메세지 던지기==&lt;br /&gt;
*loginError.jsp&lt;br /&gt;
&amp;lt;code lang='jsp' em='6,7'&amp;gt;&lt;br /&gt;
&amp;lt;%@page import=&amp;quot;jcf.web.ux.miplatform.MiResponse&amp;quot;%&amp;gt;&lt;br /&gt;
&amp;lt;%@page contentType=&amp;quot;text/html; charset=EUC-KR&amp;quot; %&amp;gt;&lt;br /&gt;
&amp;lt;% 	&lt;br /&gt;
		System.out.println(&amp;quot;세션만료&amp;quot;);&lt;br /&gt;
		&lt;br /&gt;
		MiResponse res = new MiResponse(response);&lt;br /&gt;
		res.error(&amp;quot;-10000&amp;quot;, &amp;quot;세션이 만료되었습니다.&amp;quot;);	&lt;br /&gt;
%&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==마이플렛폼에서 서버단 메세지 받기==&lt;br /&gt;
===Transaction 사용하여 서버에 호출하는 경우===&lt;br /&gt;
*마이플렛폼 화면에서 서버호출 (예)용어사전 조회버튼 누를시&lt;br /&gt;
&amp;lt;code lang='javascript' em='3'&amp;gt;&lt;br /&gt;
function menuFind()&lt;br /&gt;
{&lt;br /&gt;
	Transaction( &lt;br /&gt;
	&amp;quot;FIND&amp;quot;, &lt;br /&gt;
	&amp;quot;Common::term/findTerms.action&amp;quot;, &lt;br /&gt;
	&amp;quot;&amp;quot;, &lt;br /&gt;
	&amp;quot;ds_term=ds_term&amp;quot;, &lt;br /&gt;
	 &amp;quot;&amp;quot;, &lt;br /&gt;
	&amp;quot;trancallback&amp;quot;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*마이플렛폼 화면에서 서버호출 후 callback에서 에러처리&lt;br /&gt;
**에러코드를 잡에서 setMessage를 호출하고 에러코드가 양수일 경우 status bar에 메세지를 뿌려주는 postxxx()를 호출&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang='javascript' em='6,7,10,16,17,20'&amp;gt;&lt;br /&gt;
function trancallback(trid, ErrorCode, ErrorMsg )&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
 if( trid == &amp;quot;save&amp;quot; )&lt;br /&gt;
	{&lt;br /&gt;
		if( ErrorCode &amp;lt; 0 ) {&lt;br /&gt;
		setMessage(ErrorMsg, &amp;quot;ALERT&amp;quot;);&lt;br /&gt;
		break;&lt;br /&gt;
		}&lt;br /&gt;
		postSave();&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	&lt;br /&gt;
if( trid == &amp;quot;FIND&amp;quot; )	&lt;br /&gt;
	{&lt;br /&gt;
		if( ErrorCode &amp;lt; 0 ){		&lt;br /&gt;
			setMessage(ErrorMsg, &amp;quot;ALERT&amp;quot;);&lt;br /&gt;
			break;&lt;br /&gt;
			}&lt;br /&gt;
		postFind();	&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{팁|&lt;br /&gt;
*setMessage() 란?&lt;br /&gt;
**JCF_JS::jcf_message.js 사용&lt;br /&gt;
**setMessage(errorMeg, type);&lt;br /&gt;
**type종류(&amp;quot;ALERT&amp;quot;,&amp;quot;STARUS&amp;quot;,&amp;quot;CONFIRM&amp;quot;) &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===srv_fn_AsyncCall사용하여 서버에 호출하는 경우===&lt;br /&gt;
====srv_fn_AsyncCall====&lt;br /&gt;
{{정보|&lt;br /&gt;
*srv_fn_AsyncCall()&lt;br /&gt;
**위치 : JCF_JS::lib_service.js&lt;br /&gt;
**역할: 비동기식 서버호출 , Progress UI(loading.xml) 보여줌, 서버 호출 후 errorcode 및 errorMsg 받아서 setMassage 해줌)&lt;br /&gt;
**특징: 단위화면에서 callback function으로 에러메세지처리 구현 하지 않아도 됨.&lt;br /&gt;
}}&lt;br /&gt;
&amp;lt;code lang='javascript' em='56,57,58,59,60'&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/******************************************************************&lt;br /&gt;
 * 입력: svcid		: svcid&lt;br /&gt;
         svcName	: Transaction코드&lt;br /&gt;
         InData		: Input Dataset List&lt;br /&gt;
         OutData	: Output Dataset List&lt;br /&gt;
         arg		: 처리하고자할 argument&lt;br /&gt;
         Result		: 서비스후에 처리할 Function&lt;br /&gt;
 * return    	    : 처리 결과 Dataset&lt;br /&gt;
 * ex : srv_fn_AsyncCall(&amp;quot;select&amp;quot;,&amp;quot;KCAE01_MVCColsSelect.jsp&amp;quot;,&amp;quot;&amp;quot;,args_out,args_mvs,&amp;quot;fnCallBack&amp;quot;);&lt;br /&gt;
******************************************************************/&lt;br /&gt;
function srv_fn_AsyncCall(svcid,svcName,InData,OutData,arg,Result,Progress)&lt;br /&gt;
{&lt;br /&gt;
	SetWaitCursor(true);&lt;br /&gt;
	SetCapture();&lt;br /&gt;
	global.MainFrame.enable = false;&lt;br /&gt;
	//alert(Progress);&lt;br /&gt;
	if(Progress == true) {		&lt;br /&gt;
		objProgress = object(&amp;quot;DivProgress&amp;quot;);&lt;br /&gt;
		if(!isValidObject(objProgress)) {&lt;br /&gt;
			objProgress = Create(&amp;quot;Div&amp;quot;,&amp;quot;DivProgress&amp;quot;,'Url=&amp;quot;CommonGroup::Loading.xml&amp;quot; width=&amp;quot;0&amp;quot; height=&amp;quot;0&amp;quot; Visible=false');&lt;br /&gt;
		}&lt;br /&gt;
		objProgress.Width = nProgWidth;&lt;br /&gt;
		objProgress.Height = nProgHeight;&lt;br /&gt;
		objProgress.Left = srv_fn_GetProgLeft();&lt;br /&gt;
		objProgress.Top = srv_fn_GetProgTop();&lt;br /&gt;
		objProgress.Visible = true;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	scmv_userFunc = Result;&lt;br /&gt;
	Transaction(svcid,svcName,InData,OutData,arg,&amp;quot;srv_fn_Result&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function srv_fn_GetProgLeft()&lt;br /&gt;
{&lt;br /&gt;
	return (this.Width / 2) - (nProgWidth / 2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function srv_fn_GetProgTop()&lt;br /&gt;
{&lt;br /&gt;
	return (this.Height / 2) - (nProgHeight / 2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/******************************************************************&lt;br /&gt;
 * Async Transaction 결과&lt;br /&gt;
 *****************************************************************/&lt;br /&gt;
function srv_fn_Result(TrID,strErrCode,strErrorMsg)&lt;br /&gt;
{&lt;br /&gt;
	if(objProgress.Visible == true) objProgress.Visible = false;&lt;br /&gt;
	global.MainFrame.enable = true;&lt;br /&gt;
	ReleaseCapture();&lt;br /&gt;
	SetWaitCursor(false);&lt;br /&gt;
	// session time out (재로그인)&lt;br /&gt;
	if(toNumber(strErrCode) == -10000)&lt;br /&gt;
	{&lt;br /&gt;
		if(JSESSIONID != &amp;quot;timeout&amp;quot;) {&lt;br /&gt;
			JSESSIONID = &amp;quot;timeout&amp;quot;;	&lt;br /&gt;
			alert(strErrorMsg);&lt;br /&gt;
		}&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	// no authority - 권한 없음(로그아웃)&lt;br /&gt;
	if(toNumber(strErrCode) == -20000)&lt;br /&gt;
	{&lt;br /&gt;
		// 권한 없음 처리 로직을 넣으세요...&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	// Exception 처리&lt;br /&gt;
	if(toNumber(strErrCode) == -70000)&lt;br /&gt;
	{&lt;br /&gt;
		// Exception 처리 로직을 넣으세요...&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	if(toNumber(strErrCode) &amp;lt; 0 &amp;amp;&amp;amp; toNumber(strErrCode) &amp;gt; -1000000000)&lt;br /&gt;
	{&lt;br /&gt;
		//alert(strErrCode);&lt;br /&gt;
		alert(strErrorMsg);   	}&lt;br /&gt;
	if(length(scmv_userFunc) == 0) return;&lt;br /&gt;
	var ExprCall = scmv_userFunc + '(TrID, strErrCode, strErrorMsg)';&lt;br /&gt;
	eval(ExprCall);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*srv_fn_AsyncCall 사용하여 마이플렛폼 화면에서 서버호출 (예)용어사전 조회버튼 누를시&lt;br /&gt;
&amp;lt;code lang='javascript' em='3'&amp;gt;&lt;br /&gt;
function menuFind()&lt;br /&gt;
{&lt;br /&gt;
	srv_fn_AsyncCall( &lt;br /&gt;
	&amp;quot;FIND&amp;quot;, &lt;br /&gt;
	&amp;quot;Common::term/findTerms.action&amp;quot;, &lt;br /&gt;
	&amp;quot;&amp;quot;, &lt;br /&gt;
	&amp;quot;ds_term=ds_term&amp;quot;, &lt;br /&gt;
	 &amp;quot;&amp;quot;, &lt;br /&gt;
	&amp;quot;trancallback&amp;quot;,&lt;br /&gt;
	true);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</description>
			<pubDate>Tue, 12 Aug 2008 06:28:41 GMT</pubDate>			<dc:creator>Itanywhere</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:TimeOut_Message</comments>		</item>
		<item>
			<title>WebServices CXF</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/WebServices_CXF</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* CXF Archetype 만들기 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물: CXF Architype 만들기&lt;br /&gt;
*작성자: 서경진&lt;br /&gt;
*최초작성일 : 2008/08/11&lt;br /&gt;
*최종작성일 : 2008/08/14&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
* 이 문서는 웹서비스 엔진 중에 하나인 CXF에 대하여 설명한 것이다.&lt;br /&gt;
}}&lt;br /&gt;
{{경고|&lt;br /&gt;
*이 문서는 현재 작성중에 있습니다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=CXF Archetype 만들기=&lt;br /&gt;
&lt;br /&gt;
[[그림:CXF_Maven_Archetype_DirectoryStrutcture.JPG|400px|thumb|center|CXF 웹서비스 Archetype 디렉터리 구조]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. archetype plugin을 위한 새 프로젝트와 pom.xml 생성하기&lt;br /&gt;
2. archetype descriptor 생성하기&lt;br /&gt;
3. prototype 파일과 prototype pom.xml 생성하기&lt;br /&gt;
4. archetype 설치하고 실행하기&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==archetype plugin을 위한 새 프로젝트와 pom.xml 생성하기==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==archetype descriptor 생성하기==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==prototype 파일과 prototype pom.xml 생성하기==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==archetype 설치하고 실행하기==&lt;br /&gt;
&lt;br /&gt;
=CXF Quick Start로 웹서비스 개발하기=&lt;/div&gt;</description>
			<pubDate>Mon, 11 Aug 2008 05:24:11 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:WebServices_CXF</comments>		</item>
		<item>
			<title>Spring Quartz Batch</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_Quartz_Batch</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* SpringFramework + Quartz + SpringBatch 예제 다운로드 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물: SpringFramework + Quartz + SpringBatch 사용하기 (예제)&lt;br /&gt;
*작성자: 나윤주&lt;br /&gt;
*최초작성일 : 2008/08/08&lt;br /&gt;
*최종작성일 : 2008/08/11&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
* 이 문서는 Web Service 환경에서 SpringFramework와 Quartz 스케줄러를 사용해 SpringBatch를 실행시키는 방법을 설명한다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==환경준비==&lt;br /&gt;
*이 예제는 Web Service 환경에서 Spring Batch를 사용하는 것을 목적으로 하며, 이클립스 기반에서 작성되었다.&lt;br /&gt;
*주요 기술 구성은 SpringFramework와 Quartz, SpringBatch이다.&lt;br /&gt;
*환경설정&lt;br /&gt;
**이클립스를 통해 Dynamic Web Project를 생성한다.&lt;br /&gt;
**주요 라이브러리는 spring.jar, quartz.jar, spring-batch-core.jar, spring-batch-infrastructure.jar, jta.jar, commons-collections.jar, commons-io.jar, commons-logging.jar, commons-pool.jar, hsqldb.jar 등이 있다. 이 라이브러리들은 아래 예제 코드에 포함되어 있다. (/spring-quartz-batch/web/WEB-INF/lib/)&lt;br /&gt;
&lt;br /&gt;
==SpringFramework에서 Quartz 사용하기==&lt;br /&gt;
*Quartz는 Java application과 통합되어 job을 스케줄링하고 관리할 수 있는 Job Scheduling System 이다.&lt;br /&gt;
*SpringFramwork에서는 Quartz와 연계하여 스케줄링 할 수 있는 API를 제공한다.&lt;br /&gt;
*SpringFramwork에서 Quartz를 사용하기 위해 스케줄링 할 Job과 스케줄러의 설정이 필요하다.&lt;br /&gt;
===Job Class===&lt;br /&gt;
*수행될 Job은 간단하게 Java Class로 작성된다.&lt;br /&gt;
*spring.jar에 포함된 org.springframework.scheduling.quartz.QuartzJobBean Class를 상속하며 executeInternal() 메소드를 구현해야 한다.&lt;br /&gt;
*executeInternal() 메소드에서 수행될 Job의 내용을 작성한다.&lt;br /&gt;
*간단한 Log를 찍는 job class는 다음과 같이 구현할 수 있다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* HelloJob.java */&lt;br /&gt;
package quartz.example;&lt;br /&gt;
&lt;br /&gt;
import java.util.Date;&lt;br /&gt;
&lt;br /&gt;
import org.apache.commons.logging.Log;&lt;br /&gt;
import org.apache.commons.logging.LogFactory;&lt;br /&gt;
import org.quartz.JobExecutionContext;&lt;br /&gt;
import org.springframework.scheduling.quartz.QuartzJobBean;&lt;br /&gt;
&lt;br /&gt;
public class HelloJob extends QuartzJobBean {&lt;br /&gt;
&lt;br /&gt;
    private static Log _log = LogFactory.getLog(HelloJob.class);&lt;br /&gt;
    &lt;br /&gt;
    public HelloJob() {&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    protected void executeInternal(JobExecutionContext context) {&lt;br /&gt;
    	_log.info(&amp;quot;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; Hello World! - &amp;quot; + new Date() + &amp;quot; &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Job/Scheduler Configuration===&lt;br /&gt;
*Job과 scheduler의 설정은 xml 파일에서 이루어진다.&lt;br /&gt;
*xml 설정 파일은 web.xml에서 contextConfigLocation 설정에 포함시켜 웹 서비스가 시작됨과 동시에 스케줄된 Job이 작동하도록 한다.&lt;br /&gt;
*Job을 실행시키는 스케줄을 담고 있는 Trigger로는 SimpleTriggerBean과 CronTriggerBean이 있다.&lt;br /&gt;
**SimpleTrigger는 한번 발생하는 Job이나 일정한 주기를 가지고 반복되는 Job 등에 적용할 수 있다.&lt;br /&gt;
**CronTrigger는 Calendar 기반 즉, 년/월/일/시/분/초/요일 등을 기준으로 실행되어야 하는 Job 등에 적용할 수 있다.&lt;br /&gt;
*TriggerBean을 통해 작성된 스케줄은 SchedulerFactoryBean에 등록함으로써 작동된다. &lt;br /&gt;
*아래 코드에서는 simpleTrigger를 사용하여 서비스가 시작되고 10초 후 부터 50초 간격으로 Job을 실행시키도록 스케줄하였다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;beans ...(xmlns 설정)&amp;gt;&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;helloJob&amp;quot; class=&amp;quot;org.springframework.scheduling.quartz.JobDetailBean&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;jobClass&amp;quot; value=&amp;quot;quartz.example.HelloJob&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;simpleTrigger&amp;quot; class=&amp;quot;org.springframework.scheduling.quartz.SimpleTriggerBean&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;jobDetail&amp;quot; ref=&amp;quot;helloJob&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;startDelay&amp;quot; value=&amp;quot;10000&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;repeatInterval&amp;quot; value=&amp;quot;50000&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;bean class=&amp;quot;org.springframework.scheduling.quartz.SchedulerFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;triggers&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;list&amp;gt;&lt;br /&gt;
				&amp;lt;ref bean=&amp;quot;simpleTrigger&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/list&amp;gt;&lt;br /&gt;
		&amp;lt;/property&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SpringFramework + Quartz + SpringBatch 사용하기==&lt;br /&gt;
{{틀:주의사항|&lt;br /&gt;
*Spring Batch는 경우에 따라 다양한 설정이 가능하고, 필요할 수 있으므로 반드시 레퍼런스를 참고하여 사용하도록 한다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
*위에서 설명한 SpringFramework + Quartz의 Quartz Job에서 Spring Batch Job을 수행한다.&lt;br /&gt;
*즉, SpringFramework를 사용하는 웹 서비스에서 Quartz를 통해 스케줄링을 하고, Spring Batch Job을 수행하게 된다.&lt;br /&gt;
*Spring Batch Job을 수행하기 위해 Spring Batch의 JobLauncher, JobRepository 등의 설정과 Job에 대한 정의가 필요하다.&lt;br /&gt;
===Job과 연관된 components 설정===&lt;br /&gt;
*JobRepository와 JobLauncher는 Job의 실행을 위한 기본적으로 지정해주어야 하는 설정이다.&lt;br /&gt;
**JobRepository는 Job을 관리하는 Repository로 데이터베이스 및 데이터소스 설정을 한다.&lt;br /&gt;
**JobLauncher는 Job과 실행 Parameter를 전달하여 Job의 실행을 도와주는 역할을 한다.&lt;br /&gt;
*SimpleJob과 TaskletStep 등은 미리 정의해 놓고 간단한 Job을 정의할 때 상속받아 사용할 수 있도록 한다.&lt;br /&gt;
&amp;lt;code lang='xml'&amp;gt;&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;jobRepository&amp;quot; class=&amp;quot;org.springframework.batch.core.repository.support.JobRepositoryFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;databaseType&amp;quot; value=&amp;quot;hsql&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;dataSource&amp;quot; ref=&amp;quot;dataSource&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;jobLauncher&amp;quot; class=&amp;quot;org.springframework.batch.core.launch.support.SimpleJobLauncher&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;jobRepository&amp;quot; ref=&amp;quot;jobRepository&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;simpleJob&amp;quot; class=&amp;quot;org.springframework.batch.core.job.SimpleJob&amp;quot; abstract=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;jobRepository&amp;quot; ref=&amp;quot;jobRepository&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;taskletStep&amp;quot; class=&amp;quot;org.springframework.batch.core.step.tasklet.TaskletStep&amp;quot; abstract=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;jobRepository&amp;quot; ref=&amp;quot;jobRepository&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===Job의 정의===&lt;br /&gt;
*Job은 xml 파일로 정의되며, Job 내부의 Step이 Java Class로 구현된다.&lt;br /&gt;
*위에서 정의한 SimpleJob을 상속받아 개별 Job에 대한 속성을 지정해 줄 수 있다.&lt;br /&gt;
*여기서는 myHelloJob을 정의하고 내부 Step으로 메시지를 전달하는 Class를 구현하였다.&lt;br /&gt;
&amp;lt;code lang='xml'&amp;gt;&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;myHelloJob&amp;quot; parent=&amp;quot;simpleJob&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;name&amp;quot; value=&amp;quot;myHelloJob&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;steps&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;list&amp;gt;&lt;br /&gt;
				&amp;lt;bean id=&amp;quot;firstHello&amp;quot; parent=&amp;quot;taskletStep&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;property name=&amp;quot;tasklet&amp;quot;&amp;gt;&lt;br /&gt;
						&amp;lt;bean class=&amp;quot;quartz.example.MyHello&amp;quot;&amp;gt;&lt;br /&gt;
							&amp;lt;property name=&amp;quot;message&amp;quot; value=&amp;quot;Hi~&amp;quot; /&amp;gt;&lt;br /&gt;
						&amp;lt;/bean&amp;gt;&lt;br /&gt;
					&amp;lt;/property&amp;gt;&lt;br /&gt;
				&amp;lt;/bean&amp;gt;&lt;br /&gt;
				&amp;lt;bean id=&amp;quot;secondHello&amp;quot; parent=&amp;quot;taskletStep&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;property name=&amp;quot;tasklet&amp;quot;&amp;gt;&lt;br /&gt;
						&amp;lt;bean class=&amp;quot;quartz.example.MyHello&amp;quot;&amp;gt;&lt;br /&gt;
							&amp;lt;property name=&amp;quot;message&amp;quot; value=&amp;quot;Oh~ Hi~&amp;quot; /&amp;gt;&lt;br /&gt;
						&amp;lt;/bean&amp;gt;&lt;br /&gt;
					&amp;lt;/property&amp;gt;&lt;br /&gt;
				&amp;lt;/bean&amp;gt;&lt;br /&gt;
			&amp;lt;/list&amp;gt;&lt;br /&gt;
		&amp;lt;/property&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*정의한 Job을 Quartz Job에 연결하기 위해, Quartz Job의 정의 및 구현도 변경되어야 한다.&lt;br /&gt;
*구현한 Quartz Job Class에 SpringBatch의 Job과 JobLauncher 변수를 등록하고 정의에도 추가해 준다.&lt;br /&gt;
&amp;lt;code lang='xml'&amp;gt;&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;helloJob&amp;quot; class=&amp;quot;org.springframework.scheduling.quartz.JobDetailBean&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;jobClass&amp;quot; value=&amp;quot;quartz.example.HelloJob&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;jobDataAsMap&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;map&amp;gt;&lt;br /&gt;
				&amp;lt;entry key=&amp;quot;launcher&amp;quot; value-ref=&amp;quot;jobLauncher&amp;quot;/&amp;gt;&lt;br /&gt;
				&amp;lt;entry key=&amp;quot;job&amp;quot; value-ref=&amp;quot;myHelloJob&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;/map&amp;gt;&lt;br /&gt;
		&amp;lt;/property&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*SpringBatch Job은 JobLauncher의 run() API를 통해 실행 시킬 수 있다.&lt;br /&gt;
*Job의 내용이 같을 경우 한번 실행된 Job이므로 이미 완료되었다는 예외가 발생하므로, JobParameter를 다르게 줌으로써 계속적으로 실행 할 수 있도록 한다.&lt;br /&gt;
**이 예제에서는 JobParameter로 Date를 전달하였다.&lt;br /&gt;
&amp;lt;code lang='java'&amp;gt;&lt;br /&gt;
/* HelloJob.java */&lt;br /&gt;
/* .. 중간생략 .. */&lt;br /&gt;
public class HelloJob extends QuartzJobBean {  &lt;br /&gt;
	private JobLauncher launcher;&lt;br /&gt;
	private Job job;&lt;br /&gt;
    &lt;br /&gt;
	/* .. 중간생략 .. */&lt;br /&gt;
    &lt;br /&gt;
	protected void executeInternal(JobExecutionContext context) {&lt;br /&gt;
    		_log.info(&amp;quot;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; &amp;quot; +  &amp;quot; Hello World! - &amp;quot; + new Date() + &amp;quot; &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;quot;);&lt;br /&gt;
    	&lt;br /&gt;
    		JobParametersBuilder jobParameterBulider = new JobParametersBuilder();&lt;br /&gt;
    		jobParameterBulider.addDate(&amp;quot;date&amp;quot;, new Date());&lt;br /&gt;
    	&lt;br /&gt;
    		try {&lt;br /&gt;
			JobExecution jobExecution = launcher.run(job, jobParameterBulider.toJobParameters());		&lt;br /&gt;
		} catch (JobExecutionAlreadyRunningException e) {&lt;br /&gt;
			/* .. 중간생략 .. */&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==SpringFramework + Quartz + SpringBatch 예제 다운로드==&lt;br /&gt;
*[[media:spring-quartz-batch.zip|SpringFramework + Quartz + SpringBatch 예제 다운로드]]&lt;br /&gt;
*데이터베이스는 hsqldb를 사용하였다.&lt;br /&gt;
**이 예제에서는 데이터베이스를 사용하지 않으나, 데이터베이스를 사용하는 batch job을 개발할 경우 데이터베이스 설정을 참조할 수 있다.&lt;br /&gt;
{{정보|&lt;br /&gt;
*예제 실행을 위해서는 JDK, 이클립스, 톰캣 등의 개발환경이 필요하다. ([[개인 개발환경]] 참고) &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
*(보충)아래 예제는 Web Service Application인 블로그와 Spring Batch를 적용한 예제이다.&lt;br /&gt;
**Spring MVC 파일 업로드로 저장된 파일을 BLOB 타입으로 변환해서 데이터베이스에 업데이트하는 부분을 배치처리하였다.&lt;br /&gt;
**Spring MVC + SpringFramework + iBatis + HSQL + Quartz + SpringBatch의 조합.&lt;br /&gt;
**[[media:blog-batch.zip|블로그 + Spring Batch 예제 다운로드]]&lt;br /&gt;
&lt;br /&gt;
==참고자료==&lt;br /&gt;
*[http://static.springframework.org/spring-batch/ Spring Batch Web Site]&lt;br /&gt;
*[http://static.springframework.org/spring-batch/spring-batch-docs/reference/html/index.html Spring Batch Reference]&lt;br /&gt;
*[http://chanwook.tistory.com/671 Spring Batch 튜토리얼]&lt;br /&gt;
*[http://www.opensymphony.com/quartz/ Quartz Web Site]&lt;br /&gt;
*[http://static.springframework.org/spring/docs/2.5.x/reference/scheduling.html SpringFramework Refernece(Using the OpenSymphony Quartz Scheduler)]&lt;/div&gt;</description>
			<pubDate>Fri, 08 Aug 2008 08:03:40 GMT</pubDate>			<dc:creator>Stardust</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Spring_Quartz_Batch</comments>		</item>
		<item>
			<title>Spring Batch Environment Setting</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_Batch_Environment_Setting</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 주요 TestCase 이해하기 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물: Spring Batch Environment Setting&lt;br /&gt;
*작성자: 서경진&lt;br /&gt;
*최초작성일 : 2008/07/24&lt;br /&gt;
*최종작성일 : 2008/07/30&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
* 이 문서에는 Spring Batch 코어와 샘플 프로젝트를 설치하고 구동하는 것을 설명할 것이다.&lt;br /&gt;
}}&lt;br /&gt;
{{경고|&lt;br /&gt;
*이 문서는 현재 작성중에 있습니다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=프로젝트 다운받기=&lt;br /&gt;
*Spring Batch에 대한 이해를 높이기 위해서 Spring Batch에서 제공하는 소스와 샘플을 설치하여 테스트하는 것이 필요하다.&lt;br /&gt;
*우선 프로젝트를 구성하기 위해 Spring Batch SVN 사이트(http://springframework.svn.sourceforge.net/svnroot/springframework/spring-batch) 에서 소스를 다운로드 받는다.&lt;br /&gt;
*Eclipse에서 다음과 같이 Repository를 설정한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringBatch_SubversionSite.JPG|400px|thumb|center|Spring Batch SVN Site]]&lt;br /&gt;
&lt;br /&gt;
*해당 URL을 통해 접근하면 다음과 같은 디렉토리 구조를 가지는 것을 확인할 수 있다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringBatch_DirectoryStructure.JPG|400px|thumb|center|Spring Batch 디렉토리 구조]]&lt;br /&gt;
&lt;br /&gt;
*SVN 디렉토리 구조에서 trunk에서 오른쪽 버튼을 클릭하여 소스를 checkout 한다.&lt;br /&gt;
*Spring Batch와 관련된 모든 소스들이 Checkout 되고 로컬 프로젝트 디렉토리 구조는 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringBatch_LocalDirectoryStructure.JPG|700px|thumb|center|로컬 프로젝트 디렉토리 구조]]&lt;br /&gt;
&lt;br /&gt;
=Eclipse 프로젝트로 Import하기=&lt;br /&gt;
*Package Explorer View에서 오른쪽 마우스를 클릭하고 출력된 메뉴에서 Import를 선택한다.&lt;br /&gt;
*Import창에 다음과 같이 설정하고 spring-batch-core 프로젝트를 생성한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringBatch_Core_ImportProject.JPG|525px]]&lt;br /&gt;
[[그림:SpringBatch_Core_ImportProject_selectDir.JPG|525px]]&lt;br /&gt;
&lt;br /&gt;
*마지막 그림에서 finish를 클릭하면 eclipse의 explorer view에 다음과 같이 spring-batch-core 프로젝트가 등록된 것을 확인할 수 있다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringBatch_Core_EclipseProject.JPG|772px|thumb|center|eclipse 프로젝트 등록]]&lt;br /&gt;
&lt;br /&gt;
*spring-batch에 있는 서브 디렉터리인 spring-batch-infrastructure, spring-batch-integration, spring-batch-samples도 위와 같은 방법으로 eclipse 프로젝트로 등록한다.&lt;br /&gt;
*다음은 spring-batch의 서브 프로젝트를 eclipse 프로젝트로 등록한 화면이다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringBatch_Core_All_EclipseProject.JPG|933px|thumb|center|spring-batch 서브 프로젝트를 eclipse 프로젝트로 등록]]&lt;br /&gt;
&lt;br /&gt;
=Maven 명령으로 실행하기=&lt;br /&gt;
*현재 eclipse에 등록된 spring-batch 프로젝트는 POM (Project Object Model) 기반의 Maven 프로젝트이다.&lt;br /&gt;
*Maven 기반의 프로젝트를 구동시키기 위해 Maven과 M2 Plugin을 설치하는 것이 필요하다.&lt;br /&gt;
&lt;br /&gt;
==Maven과 M2 Plugin 설치하기==&lt;br /&gt;
*아래의 JCF tutorials의 개인 개발환경에서 지시하는 내용에 따라 개발환경을 구성한다.&lt;br /&gt;
&lt;br /&gt;
{{정보|&lt;br /&gt;
*JCF 개인 개발환경 구성: [http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%EA%B5%90%EC%9C%A1%EC%9A%A9_%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD_%28%EA%B0%9C%EC%9D%B8%29 이동]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==로컬 라이브러리 저장소로 install하기==&lt;br /&gt;
*개인 개발환경이 구성되면 Maven과 M2 Plugin의 사용이 가능하다.&lt;br /&gt;
*spring-batch-infrastructure로부터 spring-batch-samples까지 M2 eclipse를 활용하여 다음과 같이 install한다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. install의 순서&lt;br /&gt;
1) spring-batch-infrastructure&lt;br /&gt;
2) spring-batch-core (spring-batch-infrastructure에 대한 dependency 존재)&lt;br /&gt;
3) spring-batch-samples&lt;br /&gt;
4) spring-integration-batch (Optional)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===spring-batch-infrastructure===&lt;br /&gt;
*다음과 같이 Maven install 명령을 실행하여 spring-batch-core가 install 될 수 있는 환경을 구축한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringBatch_Infrastructure_Maven_Install.JPG|600px|thumb|center|spring-batch-infrastructure 프로젝트의 Run as 메뉴에서 Maven install 실행하기]]&lt;br /&gt;
&lt;br /&gt;
*Maven install 명령을 실행하면 다음과 같이 시작하며 task-segment: [install]은 다음과 같은 순서로 task를 처리한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. resources:resources&lt;br /&gt;
2. compiler:compile&lt;br /&gt;
3. resources:testResources&lt;br /&gt;
4. compiler:testCompile&lt;br /&gt;
5. surefire:test&lt;br /&gt;
6. jar:jar&lt;br /&gt;
7. source:jar&lt;br /&gt;
8. bundle:manifest&lt;br /&gt;
9. install:install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Maven install이 시작되었을 때의 콘솔화면이다.&lt;br /&gt;
[[그림:SpringBatch_Infrastructure_Maven_Install_Start.JPG|700px|thumb|center|install 시작]]&lt;br /&gt;
*Maven install이 종료되었을 때의 콘솔화면이다.&lt;br /&gt;
[[그림:SpringBatch_Infrastructure_Maven_Install_End.JPG|800px|thumb|center|install 종료]]&lt;br /&gt;
&lt;br /&gt;
===spring-batch-core===&lt;br /&gt;
*spring-batch-core는 다음과 같이 spring-batch-infrastructure에 대한 dependency가 존재한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;dependency&amp;gt;&lt;br /&gt;
	&amp;lt;groupId&amp;gt;org.springframework.batch&amp;lt;/groupId&amp;gt;&lt;br /&gt;
	&amp;lt;artifactId&amp;gt;spring-batch-infrastructure&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
	&amp;lt;version&amp;gt;${project.version}&amp;lt;/version&amp;gt;&lt;br /&gt;
&amp;lt;/dependency&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringBatch_Core_Maven_Install.JPG|600px|thumb|center|spring-batch-core 프로젝트의 Run as 메뉴에서 Maven install 실행하기]]&lt;br /&gt;
&lt;br /&gt;
*Maven install을 클릭하면 콘솔 View에 다음과 같이 install task의 시작을 알린다.&lt;br /&gt;
*Maven install 명령을 실행하면 다음과 같이 시작하며 task-segment: [install]은 다음과 같은 순서로 task를 처리한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. antrun:run&lt;br /&gt;
2. resources:resources&lt;br /&gt;
3. compiler:compile&lt;br /&gt;
4. resources:testResources&lt;br /&gt;
5. compiler:testCompile&lt;br /&gt;
6. surefire:test&lt;br /&gt;
7. jar:jar&lt;br /&gt;
8. statemgmt:start-fork&lt;br /&gt;
9. antrun:run&lt;br /&gt;
10. statemgmt:end-fork&lt;br /&gt;
11. source:jar&lt;br /&gt;
12. statemgmt:clear-fork-context&lt;br /&gt;
13. bundle:manifest&lt;br /&gt;
14. install:install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Maven install이 시작되었을 때의 콘솔화면이다.&lt;br /&gt;
[[그림:SpringBatch_Core_Maven_Install_Start.JPG|700px|thumb|center|install 시작]]&lt;br /&gt;
*Maven install이 종료되었을 때의 콘솔화면이다.&lt;br /&gt;
[[그림:SpringBatch_Core_Maven_Install_End.JPG|900px|thumb|center|install 종료]]&lt;br /&gt;
&lt;br /&gt;
===spring-batch-samples===&lt;br /&gt;
*samples는 spring-batch-infrastructure와 spring-batch-core에 대한 dependency를 가지고 있다.&lt;br /&gt;
*따라서 spring-batch-infrastructure와 spring-batch-core에 대한 install이 선행된 후에 samples에 대한 install이 가능하다.&lt;br /&gt;
*다음은 spring-batch-samples 프로젝트에 있는 pom.xml 파일의 dependency의 일부분이다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;dependency&amp;gt;&lt;br /&gt;
	&amp;lt;groupId&amp;gt;org.springframework.batch&amp;lt;/groupId&amp;gt;&lt;br /&gt;
	&amp;lt;artifactId&amp;gt;spring-batch-core&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
	&amp;lt;version&amp;gt;${project.version}&amp;lt;/version&amp;gt;&lt;br /&gt;
&amp;lt;/dependency&amp;gt;&lt;br /&gt;
&amp;lt;dependency&amp;gt;&lt;br /&gt;
	&amp;lt;groupId&amp;gt;org.springframework.batch&amp;lt;/groupId&amp;gt;&lt;br /&gt;
	&amp;lt;artifactId&amp;gt;spring-batch-infrastructure&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
	&amp;lt;version&amp;gt;${project.version}&amp;lt;/version&amp;gt;&lt;br /&gt;
&amp;lt;/dependency&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*spring-batch-samples 프로젝트도 다른 프로젝트와 마찬가지로 Maven install을 실행한다.&lt;br /&gt;
*Maven install이 실행하면 task-segment: [install]은 다음과 같은 순서로 task를 처리한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. antrun:run&lt;br /&gt;
2. resources:resources&lt;br /&gt;
3. compiler:compile&lt;br /&gt;
4. resources:testResources&lt;br /&gt;
5. compiler:testCompile&lt;br /&gt;
6. surefire:test&lt;br /&gt;
7. jar:jar&lt;br /&gt;
8. statemgmt:start-fork&lt;br /&gt;
9. antrun:run&lt;br /&gt;
10. statemgmt:end-fork&lt;br /&gt;
11. source:jar&lt;br /&gt;
12. statemgmt:clear-fork-context&lt;br /&gt;
13. install:install&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Maven install이 시작되었을 때의 콘솔화면이다.&lt;br /&gt;
[[그림:SpringBatch_Samples_Maven_Install_Start.JPG|700px|thumb|center|install 시작]]&lt;br /&gt;
*Maven install이 종료되었을 때의 콘솔화면이다.&lt;br /&gt;
[[그림:SpringBatch_Samples_Maven_Install_End.JPG|700px|thumb|center|install 종료]]&lt;br /&gt;
&lt;br /&gt;
==test 실행하기==&lt;br /&gt;
*Maven install 이후에 Maven에 대하여 다음과 같이 선택적인 실행이 가능하다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. Maven build&lt;br /&gt;
2. Maven build...&lt;br /&gt;
3. Maven clean&lt;br /&gt;
4. Maven generate-sources&lt;br /&gt;
5. Maven install&lt;br /&gt;
6. Maven test&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*따라서 test만 실행하기 위해서는 Maven test를 실행하여 콘솔을 통해 실행과정을 모니터링할 수 있다.&lt;br /&gt;
*각 TestCase를 별도로 실행하는 것도 가능하다.&lt;br /&gt;
&lt;br /&gt;
=주요 TestCase 이해하기=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==별도로 spring-batch TestCase 실행시키기==&lt;/div&gt;</description>
			<pubDate>Thu, 24 Jul 2008 09:41:45 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Spring_Batch_Environment_Setting</comments>		</item>
		<item>
			<title>Spring Batch Use Cases</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_Batch_Use_Cases</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물: Spring Batch Use Cases 이해하기&lt;br /&gt;
*작성자: 서경진&lt;br /&gt;
*최초작성일 : 2008/07/24&lt;br /&gt;
*최종작성일 : 2008/08/01&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
* 이 문서에는 Spring Batch Use Cases에 대하여 설명한 것이다.&lt;br /&gt;
}}&lt;br /&gt;
{{경고|&lt;br /&gt;
*이 문서는 현재 작성중에 있습니다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Spring Batch Use Cases 분석=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UserCase No.1: Simple Batch Repeat==&lt;br /&gt;
*목적&lt;br /&gt;
**데이터 item이나 메시지를 처리하는 것과 같은 단순 작업(operation)을 모든 배치 범위내에서 트랜잭션을 보장하면서 정해진 횟수만큼 반복한다.&lt;br /&gt;
**트랜잭션 자원은 성능적인 잇점을 유도하기 위해서 모든 작업간에 공유된다.&lt;br /&gt;
&lt;br /&gt;
*범위&lt;br /&gt;
&lt;br /&gt;
==UserCase No.2: Automatic Retry After Failure==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UserCase No.3: Commit Batch Process Periodically==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UserCase No.4: Asynchronous Chunk Processing==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UserCase No.5: Copy File to File in a Batch==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UserCase No.6: Massively Parallel Batch Processing==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UserCase No.7: Manual Restart After Failure==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UserCase No.8: Sequential Processing of Dependent Steps==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UserCase No.9: Partial Processing==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UserCase No.10: Whole-Batch Transaction==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UserCase No.11: Scheduled Processing==&lt;/div&gt;</description>
			<pubDate>Thu, 24 Jul 2008 09:30:31 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Spring_Batch_Use_Cases</comments>		</item>
		<item>
			<title>Ext-js grid combol</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Ext-js_grid_combol</link>
			<description>&lt;p&gt;바꾼내용 간추리기: New page: ==Grid에서 콤보처리== 그리드에서 일반적인 텍스트 입력이 아닌 콤보처리시 선택후 화면 display value가 보여지지 않고 코드값이 보여지므로 이...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Grid에서 콤보처리==&lt;br /&gt;
그리드에서 일반적인 텍스트 입력이 아닌 콤보처리시 선택후 화면 display value가 보여지지 않고 코드값이 보여지므로&lt;br /&gt;
이에 대한 처리법을 다루도록 한다.&lt;br /&gt;
&lt;br /&gt;
*이 콤보처리에서의 문제점&lt;br /&gt;
**현재는 콤보값 렌더링 부분이 IE에서만 동작하고 있으므로 주의하도록 한다.&lt;br /&gt;
&lt;br /&gt;
==콤보 선언==&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
var statusCombo = new Ext.form.ComboBox({&lt;br /&gt;
			    store: cbStore,&lt;br /&gt;
			    valueField: 'abbr',&lt;br /&gt;
			    displayField:'state',&lt;br /&gt;
			    typeAhead: true,&lt;br /&gt;
			    editable: true,&lt;br /&gt;
			    mode: 'local',&lt;br /&gt;
			    triggerAction: 'all',&lt;br /&gt;
			    lazyRender:true,&lt;br /&gt;
               		    listClass: 'x-combo-list-small',&lt;br /&gt;
			    emptyText:'Select a state...',&lt;br /&gt;
			    selectOnFocus:true&lt;br /&gt;
 }); &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==그리드에 콤보 넣기==&lt;br /&gt;
이 콤보컨트롤을 그리드에 추가해야 하므로,&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
ColumnModel 선언시 넣도록 한다.&lt;br /&gt;
var cm = new Ext.grid.ColumnModel([&lt;br /&gt;
    	checkColumn,&lt;br /&gt;
    	{&lt;br /&gt;
          header: &amp;quot;요청/장애#&amp;quot;,  // 헤더 타이틀&lt;br /&gt;
           dataIndex: 'id',   // 매핑되는 컬럼명&lt;br /&gt;
           align: 'center'&lt;br /&gt;
        },{&lt;br /&gt;
           header: &amp;quot;제목&amp;quot;,&lt;br /&gt;
           dataIndex: 'title',&lt;br /&gt;
           align: 'left'&lt;br /&gt;
        },{&lt;br /&gt;
           id:'state',&lt;br /&gt;
           header: &amp;quot;상태&amp;quot;,&lt;br /&gt;
           dataIndex: 'status',&lt;br /&gt;
           align: 'center',&lt;br /&gt;
           '''editor: statusCombo,'''           &lt;br /&gt;
           renderer:Ext.jcf.Combo(statusCombo)            &lt;br /&gt;
        },&lt;br /&gt;
...&lt;br /&gt;
       ]);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
여기에 renderer를 추가시키면 된다. &lt;br /&gt;
renderer는 '''Ext.jcf.Combo'''를 사용하고 이에 대한 param 값은 콤보컨트롤 명을 넣도록 한다.&lt;/div&gt;</description>
			<pubDate>Thu, 24 Jul 2008 08:35:12 GMT</pubDate>			<dc:creator>Mariaro</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Ext-js_grid_combol</comments>		</item>
		<item>
			<title>Ext-js paging</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Ext-js_paging</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Paging 처리==&lt;br /&gt;
Ext.jcf.Grid 를 이용하여 페이징된 그리드를 처리한다.&lt;br /&gt;
*생성할 파일&lt;br /&gt;
**comCiMng.jsp : 전체화면을 구성하는 jsp&lt;br /&gt;
**comCiMng.js : 그리드와 store 핸들링을 처리하는 js 파일&lt;br /&gt;
*그 외 사용할 공통 스크립트 파일&lt;br /&gt;
**/js/ext/adapter/ext/ext-base.js&lt;br /&gt;
**/js/ext/ext-all.js&lt;br /&gt;
**/js/Ext.jcf.Common.js&lt;br /&gt;
**/js/Ext.jcf.Form.js&lt;br /&gt;
**/js/Ext.jcf.FormType.js&lt;br /&gt;
**/js/Ext.jcf.Grid.js&lt;br /&gt;
**/js/common_grid.js&lt;br /&gt;
[[그림:edit_grid_ext.jpg]]&lt;br /&gt;
==js 파일 등록==&lt;br /&gt;
먼저 JSP 파일에 필요한 js 파일을 사용할수 있도록 추가한다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;../../js/ext/adapter/ext/ext-base.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;../../js/ext/ext-all.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;../../js/gmdat-common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;../../js/Ext.jcf.Common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;../../js/Ext.jcf.Form.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;../../js/Ext.jcf.FormType.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;../../js/Ext.jcf.Grid.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;../../js/common_grid.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==검색필드 만들기 : 입력값 정의==&lt;br /&gt;
위 그림처럼 검색하기 위한 검색 항목이 있는데, 다음과 같이 지정한다.&lt;br /&gt;
===JSP===&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- 검색 영역 --&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;s_table_header_1&amp;quot; border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;0&amp;quot;&lt;br /&gt;
	bordercolordark=&amp;quot;white&amp;quot; bordercolorlight=&amp;quot;#C0C0C0&amp;quot; width=&amp;quot;100%&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;CI분류명&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td colspan=3&amp;gt;&amp;lt;input id=&amp;quot;shCiClassName&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;td&amp;gt;분류레벨&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;shCiClassLevel&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;td&amp;gt;소속사&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;shCompCode&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;대분류&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;shCiClassLev1&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;중분류&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;shCiClassLev2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;소분류&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;shCiClassLev3&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;세분류&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;shCiClassLev4&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===js===&lt;br /&gt;
Ext.form.Combo의 생성은 기존의 문서를 참조하도록 한다.&lt;br /&gt;
일반 텍스트 필드의 경우 다음과 같이 정의한다.&lt;br /&gt;
getTextField 함수는 앞서 호출한 Ext.jcf.Form에 정의되어 있으므로 따로 함수선언을 하지 않아도 된다.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
//1 . 입력 값 정의&lt;br /&gt;
    fmCiClassName = getTextField('shCiClassName', 120, 20);&lt;br /&gt;
    fmCiClassLevel = getTextField('shCiClassLevel', 120, 20);&lt;br /&gt;
    fmCompCode = getTextField('shCompCode', 120, 20);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
다음 page 호출시 application/json 형태가 아닌 일반 HttpRequest 형태로 넘어가므로,&lt;br /&gt;
이 값들을 저장하고 있다가 넘겨줄 수 있도록 아래의 처리를 추가한다.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
//2. 다음 paging 처리시 넘겨줘야 할 param 값을 Ext.jcf.HiddenForm에 담는다.&lt;br /&gt;
    fmSrchForm = new Ext.jcf.HiddenForm('/dsom/comCiMng/allComCiMngs.action', [fmCiClassName,fmCiClassLevel,fmCompCode,ciClassLevel1,ciClassLevel2,ciClassLevel3,ciClassLevel4])&lt;br /&gt;
    setFormPanelElements(false,fmSrchForm);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ext.jcf.HiddenForm은 이후 호출할때의 주소와 넘겨줄 값들에 대해 정의한 것이며,&lt;br /&gt;
이것을 FormPanel로 등록하도록 한다.&lt;br /&gt;
&lt;br /&gt;
==Column 정보 생성==&lt;br /&gt;
화면의 그리드상에 보여줄 컬럼에 대한 정의를 한다.&lt;br /&gt;
Ext.jcf.ColumnConfig를 이용하여 정의하며, &lt;br /&gt;
add(&amp;quot;헤더명&amp;quot;,&amp;quot;실제 보여줄 attribute값&amp;quot;,사이즈,정렬)이 기본이다.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
var config = new Ext.jcf.ColumnConfig();&lt;br /&gt;
    config.add(&amp;quot;분류ID&amp;quot;,'ciClassId', 25,'center');&lt;br /&gt;
    config.add(&amp;quot;분류명&amp;quot;,'ciClassName',250, 'left', null, null, new Ext.form.TextField({allowBlank: false,maxLength:153}));&lt;br /&gt;
    config.add(&amp;quot;분류레벨&amp;quot;, 'ciClassLevel', 25,'center');&lt;br /&gt;
    config.add(&amp;quot;상위분류&amp;quot;, 'upperCiClassId',25,'center');&lt;br /&gt;
    config.add(&amp;quot;사용여부&amp;quot;, 'activeFlag', 15,'center');&lt;br /&gt;
    config.add(&amp;quot;고객사&amp;quot;,'compCode', 90,'center');&lt;br /&gt;
    config.add(&amp;quot;비고&amp;quot;,  'ciClassDesc', 150,'center');&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
분류명과 같이 에디팅이 필요한 항목일 경우 에디터(Ext.form.TextField)를 추가한다.&lt;br /&gt;
config.add(&amp;quot;분류명&amp;quot;,'ciClassName',250, 'left', null, null, '''new Ext.form.TextField({allowBlank: false,maxLength:153})''');&lt;br /&gt;
&lt;br /&gt;
==Grid 선언==&lt;br /&gt;
Ext.jcf.Grid를 선언하는데, 이때 페이징일 경우 type을 paging으로 선언한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
grid = new Ext.jcf.Grid({&lt;br /&gt;
	'''type: 'paging'''', //'basic',  'detail'&lt;br /&gt;
    	single: true,&lt;br /&gt;
    	width: 'auto',&lt;br /&gt;
    	height: 180,&lt;br /&gt;
    	clicksToEdit:1,&lt;br /&gt;
    	paging: {&lt;br /&gt;
    		'''store: ciStore''',&lt;br /&gt;
    		display: 'text',&lt;br /&gt;
    		value: 'value',&lt;br /&gt;
    		xtype: 'bbar'&lt;br /&gt;
    	},&lt;br /&gt;
    	panel: {&lt;br /&gt;
    		title: '',&lt;br /&gt;
    		render: 'ciMngList',&lt;br /&gt;
    		width: 'auto',&lt;br /&gt;
    		height: 260,&lt;br /&gt;
    		resize: true&lt;br /&gt;
    	},&lt;br /&gt;
    	listeners: {//그리드 관련 이벤트 정보&lt;br /&gt;
    		beforeedit : function(e) {&lt;br /&gt;
			var action = e.record.get(ACTION_FIELD);	&lt;br /&gt;
			if(action == DELETE_RECORD)	return false;&lt;br /&gt;
		},&lt;br /&gt;
		validateedit : function (e){&lt;br /&gt;
			if (e.field == 'ciClassName'){						&lt;br /&gt;
				var val = e.value.toUpperCase();						&lt;br /&gt;
			}	&lt;br /&gt;
		},&lt;br /&gt;
		afteredit : function(e) {		&lt;br /&gt;
			editRecord(e.record);&lt;br /&gt;
			e.record.set(e.field, e.value.toUpperCase());&lt;br /&gt;
		},&lt;br /&gt;
    		rowclick: function(grid, index) {&lt;br /&gt;
			var record = grid.getStore().getAt(index);&lt;br /&gt;
	    		selectedRecord = record;&lt;br /&gt;
    		}&lt;br /&gt;
    	},&lt;br /&gt;
    	columns: config.getConfig()&lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==레코드 정의==&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
//3-3. CI분류 Records 정의&lt;br /&gt;
var CiClass = Ext.data.Record.create([&lt;br /&gt;
		{name: 'flag', 		type: 'string'},&lt;br /&gt;
           	{name: 'ciClassId',     type: 'string'},&lt;br /&gt;
          	{name: 'ciClassName',   type: 'string'},&lt;br /&gt;
		{name: 'ciClassLevel',  type: 'string'},           	&lt;br /&gt;
           	{name: 'upperCiClassId',type: 'string'},&lt;br /&gt;
           	{name: 'compCode',      type: 'string'},&lt;br /&gt;
           	{name: 'activeFlag',    type: 'string'},&lt;br /&gt;
           	{name: 'ciClassDesc',   type: 'string'}           	           	           	&lt;br /&gt;
    ]);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Store 정보 생성==&lt;br /&gt;
JsonStore를 생성하여 앞서 정의한 record를 field를 지정하고,&lt;br /&gt;
listener에 loadStoreBaseParams를 추가하면서 처음 선언한 HiddenForm을 담도록 한다.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
//3-4. Paging 데이터 바인딩을 위한 Store 정의&lt;br /&gt;
 ciStore = new Ext.data.JsonStore({&lt;br /&gt;
            url: '/dsom/comCiMng/allComCiMngsForPaging.action',&lt;br /&gt;
            root:'allCiClass.list',&lt;br /&gt;
	    totalProperty: 'allCiClass.totalSize',&lt;br /&gt;
	    id: 'ciClassId',&lt;br /&gt;
	    forceFit :true,&lt;br /&gt;
            fields:CiClass,&lt;br /&gt;
            listeners:{&lt;br /&gt;
        	beforeload:function(store){&lt;br /&gt;
        	loadStoreBaseParams(store,fmSrchForm);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Grid 생성==&lt;br /&gt;
grid를 생성하면서 jsonStore를 담는다.&lt;br /&gt;
&amp;lt;code&amp;gt;    &lt;br /&gt;
// 4. Grid 생성&lt;br /&gt;
 grid.create(ciStore);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</description>
			<pubDate>Wed, 23 Jul 2008 08:15:43 GMT</pubDate>			<dc:creator>Mariaro</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Ext-js_paging</comments>		</item>
		<item>
			<title>Jquery calendar</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Jquery_calendar</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 결과 화면 보기 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==개요==&lt;br /&gt;
웹 화면에서 날짜 선택시 많이 사용되는 달력 컴포넌트의 사용법이다.&lt;br /&gt;
*달력 컴포넌트는 아래 조건을 만족하도록 한다.&lt;br /&gt;
**기존 달력 컴포넌트의 경우 ComboBox와 중복될 경우 Combo 아래에 달력이 생성되어 문제가 되었으므로 이를 보완할 수 있도록 한다. &lt;br /&gt;
**가급적 웹표준을 준수하고 자바스크립트의 코딩이 간결해 지도록 한다.&lt;br /&gt;
**다른 컴포넌트나 폼요소와의 종속성을 배제한다.&lt;br /&gt;
&lt;br /&gt;
==jQuery의 Datepicker==&lt;br /&gt;
===입력할 항목 확인===&lt;br /&gt;
현재 예는 게시기간을 입력하는 부분에서 시작일과 종료일 텍스트 입력항목에 달력을 추가하고자 한다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;F2F2F2&amp;quot;&amp;gt;게시기간&lt;br /&gt;
&amp;lt;td bgcolor=&amp;quot;#FCFCFC&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;s:textfield id=&amp;quot;strFromDate&amp;quot; name=&amp;quot;notice.strFromDate&amp;quot; theme=&amp;quot;simple&amp;quot; size=&amp;quot;10&amp;quot; readonly=&amp;quot;true&amp;quot;/&amp;gt; ~&lt;br /&gt;
	&amp;lt;s:textfield id=&amp;quot;strToDate&amp;quot; name=&amp;quot;notice.strToDate&amp;quot; theme=&amp;quot;simple&amp;quot; size=&amp;quot;10&amp;quot; readonly=&amp;quot;true&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===StyleSheet와 Js 파일 추가하기===&lt;br /&gt;
JQuery의 달력은 몇 가지 종류가 있지만, 그간 프로젝트에서 가장 선호하는 형태이자 (상단에 년월이 표시되는) 달력의 모양도 CSS를 통해 수정이 용이하므로&lt;br /&gt;
다음을 사용하도록 한다.&lt;br /&gt;
우선 달력을 추가하기 위해 화면에 다음을 추가한다.&lt;br /&gt;
* StyleSheet&lt;br /&gt;
** flora.datepicker.css&lt;br /&gt;
** datePicker.css&lt;br /&gt;
* JavaScript&lt;br /&gt;
** datepicker.js&lt;br /&gt;
** ui.datepicker.js&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;css/flora.datepicker.css&amp;quot; &lt;br /&gt;
     type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot; title=&amp;quot;Flora (Default)&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;css/datePicker.css&amp;quot; type=&amp;quot;text/css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;js/jquery/datepicker.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;js/jquery/ui.datepicker.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===입력항목에 달력추가 스크립트 작성하기===&lt;br /&gt;
문서의 ready 부분에 다음을 추가한다.&lt;br /&gt;
이 때, # 부분에 들어가는 값은 입력 텍스트 필드의 id 명을 의미한다.&lt;br /&gt;
지금 시작일(id:strFromDate)과 종료일(id:strToDate) 두 필드에 넣고자 하므로,&lt;br /&gt;
다음과 같이 작성한다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;&lt;br /&gt;
	  $(document).ready(function(){&lt;br /&gt;
	   $('#strFromDate').datepicker();&lt;br /&gt;
	   $('#strToDate').datepicker();&lt;br /&gt;
	  });&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==결과 화면 보기==&lt;br /&gt;
다음과 같이 텍스트 필드를 클릭시 달력이 화면에 뿌려지는지 확인한다.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[그림:jquery_cal.jpg]]&lt;/div&gt;</description>
			<pubDate>Tue, 22 Jul 2008 06:54:10 GMT</pubDate>			<dc:creator>Mariaro</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Jquery_calendar</comments>		</item>
		<item>
			<title>WebStandard extJS</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/WebStandard_extJS</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 준비사항 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
* 산출물 : 일반웹 grid에서 extJS 느낌내기&lt;br /&gt;
* 작성자 : 김민아&lt;br /&gt;
* 최초작성일 : 2008/07/16&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|이곳은 일반 jsp table을 extJS 그리드로 바꾸는 예제에 대해 다룬다.}}&lt;br /&gt;
=샘플화면보기=&lt;br /&gt;
[http://extjs.com/deploy/dev/examples/grid/from-markup.html 보러가기]&lt;br /&gt;
=준비사항=&lt;br /&gt;
*ext-base.js&lt;br /&gt;
*ext-all.js&lt;br /&gt;
*ext-all.css&lt;br /&gt;
&lt;br /&gt;
=jsp 파일보기 =&lt;br /&gt;
*밑의 예제에서와 같이 ext-base.js, ext-all.js, ext-all.css를 import 시킨다.(이파일은 extJs사이트에서 다운받도록 한다.)&lt;br /&gt;
*밑에서 설명할 comUsr.js파일도 import시킨다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;jsp&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;%@ page contentType=&amp;quot;text/html; charset=UTF-8&amp;quot;%&amp;gt;&lt;br /&gt;
&amp;lt;%@ taglib prefix=&amp;quot;s&amp;quot; uri=&amp;quot;/struts-tags&amp;quot;%&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;meta http-equiv=&amp;quot;Content-Type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!--extJs 스크립트  --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&lt;br /&gt;
	src=&amp;quot;/../js/ext/adapter/ext/ext-base.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/../js/ext/ext-all.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;!--extJs  css   --&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot;&lt;br /&gt;
	href=&amp;quot;/../js/ext/resources/css/ext-all.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;!--comUsr.js--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/../jcf/biz/comUsr.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;&amp;lt;s:text name=&amp;quot;사용자 관리&amp;quot; /&amp;gt;&amp;lt;/h1&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;!-- form 정의  --&amp;gt;&lt;br /&gt;
&amp;lt;s:form name='userList' action=&amp;quot;delComUsrList.action&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;!-- 그리드 시작 --&amp;gt;&lt;br /&gt;
	&amp;lt;table cellspacing=&amp;quot;0&amp;quot; width=&amp;quot;550&amp;quot; id='usrGrid'&amp;gt;&lt;br /&gt;
		&amp;lt;thead&amp;gt;&lt;br /&gt;
			&amp;lt;tr&amp;gt;&lt;br /&gt;
				&amp;lt;th align=&amp;quot;center&amp;quot;&amp;gt;사번&amp;lt;/th&amp;gt;&lt;br /&gt;
				&amp;lt;th align=&amp;quot;center&amp;quot;&amp;gt;성명&amp;lt;/th&amp;gt;&lt;br /&gt;
				&amp;lt;th align=&amp;quot;center&amp;quot;&amp;gt;소속사&amp;lt;/th&amp;gt;&lt;br /&gt;
				&amp;lt;th align=&amp;quot;center&amp;quot;&amp;gt;부서&amp;lt;/th&amp;gt;&lt;br /&gt;
			&amp;lt;/tr&amp;gt;&lt;br /&gt;
		&amp;lt;/thead&amp;gt;&lt;br /&gt;
		&amp;lt;tbody&amp;gt;&lt;br /&gt;
			&amp;lt;s:iterator value=&amp;quot;userList&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;tr&amp;gt;&lt;br /&gt;
					&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;s:property value=&amp;quot;empId&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
					&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;s:property value=&amp;quot;userName&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
					&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;s:property value=&amp;quot;compCode&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
					&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;s:property value=&amp;quot;deptId&amp;quot; /&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
				&amp;lt;/tr&amp;gt;&lt;br /&gt;
			&amp;lt;/s:iterator&amp;gt;&lt;br /&gt;
		&amp;lt;/tbody&amp;gt;&lt;br /&gt;
	&amp;lt;/table&amp;gt;&lt;br /&gt;
	&amp;lt;!-- 그리드 끝--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/s:form&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=js파일 보기(comUsr.js)=&lt;br /&gt;
*밑의의 소스를 그대로 복사에서 사용하되  &amp;quot;usrGrid&amp;quot;는 jsp파일의 table으로 id이므로 이부분만 바꾸어준다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Ext JS Library 2.0.2&lt;br /&gt;
 * Copyright(c) 2006-2008, Ext JS, LLC.&lt;br /&gt;
 * licensing@extjs.com&lt;br /&gt;
 * &lt;br /&gt;
 * http://extjs.com/license&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
Ext.onReady(function() {&lt;br /&gt;
	   Ext.QuickTips.init();&lt;br /&gt;
	 gridBind();&lt;br /&gt;
&lt;br /&gt;
	 &lt;br /&gt;
  function gridBind(){&lt;br /&gt;
  	// create the grid&lt;br /&gt;
&lt;br /&gt;
    var grid = new Ext.grid.TableGrid(&amp;quot;usrGrid&amp;quot;, {&lt;br /&gt;
      stripeRows: true // stripe alternate rows&lt;br /&gt;
    });&lt;br /&gt;
    grid.render();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @class Ext.grid.TableGrid&lt;br /&gt;
 * @extends Ext.grid.Grid&lt;br /&gt;
 * A Grid which creates itself from an existing HTML table element.&lt;br /&gt;
 * @constructor&lt;br /&gt;
 * @param {String/HTMLElement/Ext.Element} table The table element from which this grid will be created - &lt;br /&gt;
 * The table MUST have some type of size defined for the grid to fill. The container will be &lt;br /&gt;
 * automatically set to position relative if it isn't already.&lt;br /&gt;
 * @param {Object} config A config object that sets properties on this grid and has two additional (optional)&lt;br /&gt;
 * properties: fields and columns which allow for customizing data fields and columns for this grid.&lt;br /&gt;
 * @history&lt;br /&gt;
 * 2007-03-01 Original version by Nige &amp;quot;Animal&amp;quot; White&lt;br /&gt;
 * 2007-03-10 jvs Slightly refactored to reuse existing classes&lt;br /&gt;
 */&lt;br /&gt;
Ext.grid.TableGrid = function(table, config) {&lt;br /&gt;
  config = config || {};&lt;br /&gt;
  Ext.apply(this, config);&lt;br /&gt;
  var cf = config.fields || [], ch = config.columns || [];&lt;br /&gt;
  table = Ext.get(table);&lt;br /&gt;
&lt;br /&gt;
  var ct = table.insertSibling();&lt;br /&gt;
&lt;br /&gt;
  var fields = [], cols = [];&lt;br /&gt;
  var headers = table.query(&amp;quot;thead th&amp;quot;);&lt;br /&gt;
  for (var i = 0, h; h = headers[i]; i++) {&lt;br /&gt;
    var text = h.innerHTML;&lt;br /&gt;
    var name = 'tcol-'+i;&lt;br /&gt;
&lt;br /&gt;
    fields.push(Ext.applyIf(cf[i] || {}, {&lt;br /&gt;
      name: name,&lt;br /&gt;
      mapping: 'td:nth('+(i+1)+')/@innerHTML'&lt;br /&gt;
    }));&lt;br /&gt;
&lt;br /&gt;
    cols.push(Ext.applyIf(ch[i] || {}, {&lt;br /&gt;
      'header': text,&lt;br /&gt;
      'dataIndex': name,&lt;br /&gt;
      'width': h.offsetWidth,&lt;br /&gt;
      'tooltip': h.title,&lt;br /&gt;
      'sortable': true&lt;br /&gt;
    }));&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  var ds  = new Ext.data.Store({&lt;br /&gt;
    reader: new Ext.data.XmlReader({&lt;br /&gt;
      record:'tbody tr'&lt;br /&gt;
    }, fields)&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  ds.loadData(table.dom);&lt;br /&gt;
&lt;br /&gt;
  var cm = new Ext.grid.ColumnModel(cols);&lt;br /&gt;
&lt;br /&gt;
  if (config.width || config.height) {&lt;br /&gt;
    ct.setSize(config.width || 'auto', config.height || 'auto');&lt;br /&gt;
  } else {&lt;br /&gt;
    ct.setWidth(table.getWidth());&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  if (config.remove !== false) {&lt;br /&gt;
    table.remove();&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  Ext.applyIf(this, {&lt;br /&gt;
    'ds': ds,&lt;br /&gt;
    'cm': cm,&lt;br /&gt;
    'sm': new Ext.grid.RowSelectionModel(),&lt;br /&gt;
    autoHeight: true,&lt;br /&gt;
    autoWidth: false&lt;br /&gt;
  });&lt;br /&gt;
  Ext.grid.TableGrid.superclass.constructor.call(this, ct, {});&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
Ext.extend(Ext.grid.TableGrid, Ext.grid.GridPanel);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=주의사항=&lt;br /&gt;
*경로설정주의&lt;br /&gt;
**js파일과 css파일의 경로가 정확해야한다.(FireFox의 FireBug로 보았을 때 위에서 설명한 js파일과 css파일이 잘 import되어있어야 한다.)&lt;br /&gt;
*별도의 CSS 생략&lt;br /&gt;
**위에서 import한 CSS외에는 임으로 CSS를 적용하지 않도록 한다.(그리드에 css중복 적용됨)&lt;br /&gt;
*jsp파일의 제일 상단 주의&lt;br /&gt;
**jsp파일의 제일 상단이 밑에와 같이 시작되어야한다.그렇지 않으면 grid가 깨진다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &amp;quot;-//W3C//DTD HTML 4.01//EN&amp;quot; &amp;quot;http://www.w3.org/TR/html4/strict.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;%@ page contentType=&amp;quot;text/html; charset=UTF-8&amp;quot;%&amp;gt;&lt;br /&gt;
&amp;lt;%@ taglib prefix=&amp;quot;s&amp;quot; uri=&amp;quot;/struts-tags&amp;quot;%&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</description>
			<pubDate>Wed, 16 Jul 2008 02:07:39 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:WebStandard_extJS</comments>		</item>
		<item>
			<title>Grid에서 checkbox선택하기</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Grid%EC%97%90%EC%84%9C_checkbox%EC%84%A0%ED%83%9D%ED%95%98%EA%B8%B0</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*표준웹을 사용할 경우 삭제는  Grid에서 check박스를 클릭하여 삭제하도록 한다.&lt;br /&gt;
=그리드에서 checkbox 구현하기=&lt;br /&gt;
*jsp파일 &lt;br /&gt;
&amp;lt;code lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;%@ page contentType=&amp;quot;text/html; charset=UTF-8&amp;quot;%&amp;gt;&lt;br /&gt;
&amp;lt;%@ taglib prefix=&amp;quot;s&amp;quot; uri=&amp;quot;/struts-tags&amp;quot;%&amp;gt;&lt;br /&gt;
&amp;lt;%@taglib uri=&amp;quot;/WEB-INF/tld/app.tld&amp;quot; prefix=&amp;quot;app&amp;quot;%&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;!-- 저정 버튼 클릭 시 이벤트  --&amp;gt;&lt;br /&gt;
&amp;lt;SCRIPT language='javascript' type='text/javascript'&amp;gt;&lt;br /&gt;
   var userId=document.getElementsByName('userId');&lt;br /&gt;
	function submit()&lt;br /&gt;
	{  &lt;br /&gt;
  	 document.the-table.submit();&lt;br /&gt;
     }&lt;br /&gt;
	&amp;lt;/SCRIPT&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;!-- form 정의  --&amp;gt;&lt;br /&gt;
&amp;lt;s:form  name='userList' action=&amp;quot;delComUsrList.action&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- 그리드 시작 --&amp;gt;&lt;br /&gt;
&amp;lt;table  cellspacing=&amp;quot;0&amp;quot; id=&amp;quot;the-table&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;thead&amp;gt;&lt;br /&gt;
		&amp;lt;tr&amp;gt;&lt;br /&gt;
			&amp;lt;th&amp;gt;삭제  //checkbox head&amp;lt;/th&amp;gt;&lt;br /&gt;
			&amp;lt;th align=&amp;quot;center&amp;quot;&amp;gt;ID&amp;lt;/th&amp;gt;&lt;br /&gt;
		&amp;lt;/tr&amp;gt;&lt;br /&gt;
	&amp;lt;/thead&amp;gt;&lt;br /&gt;
	&amp;lt;tbody&amp;gt;&lt;br /&gt;
		&amp;lt;s:iterator value=&amp;quot;userList&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;tr&amp;gt;&lt;br /&gt;
			    &amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
//input type을 checkbox로 지정하고 name은 userId value는 userId로 지정하여 Action에서 userId라는 리스트로 value값을 받을 수 있게함&lt;br /&gt;
&lt;br /&gt;
                              	&amp;lt;input type=&amp;quot;checkbox&amp;quot;	name=&amp;quot;userId&amp;quot; value='&amp;lt;s:property id=&amp;quot;userId&amp;quot; value=&amp;quot;userId&amp;quot; /&amp;gt;'&amp;gt;&lt;br /&gt;
				&amp;lt;/td&amp;gt;&lt;br /&gt;
				&amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;s:property value=&amp;quot;empId&amp;quot; /&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
				&amp;lt;/td&amp;gt;&lt;br /&gt;
			&amp;lt;/tr&amp;gt;&lt;br /&gt;
		&amp;lt;/s:iterator&amp;gt;&lt;br /&gt;
	&amp;lt;/tbody&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;!-- 그리드 끝--&amp;gt;&lt;br /&gt;
&amp;lt;/s:form&amp;gt;&lt;br /&gt;
&amp;lt;!-- form 끝--&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
=Action에서delete함수 구현하기=&lt;br /&gt;
*Action의 delete함수&lt;br /&gt;
**여기서 userId는 jsp의 checkbox에서 name으로 지정한 값이다. &lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
private String[] userId;&lt;br /&gt;
	public String delComUsrList() {&lt;br /&gt;
	  userService.delUsrList(userId);	&lt;br /&gt;
		return SUCCESS;&lt;br /&gt;
&lt;br /&gt;
	public String[] getUserId() {&lt;br /&gt;
		return userId;&lt;br /&gt;
	}&lt;br /&gt;
	public void setUserId(String[] userId) {&lt;br /&gt;
		this.userId = userId;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</description>
			<pubDate>Tue, 08 Jul 2008 05:42:16 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Grid%EC%97%90%EC%84%9C_checkbox%EC%84%A0%ED%83%9D%ED%95%98%EA%B8%B0</comments>		</item>
		<item>
			<title>Ext-js common script</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Ext-js_common_script</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 공통스크립트 리스트 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=공통스크립트 리스트=&lt;br /&gt;
[[그림:commonscript.jpg|800px|center]]&lt;br /&gt;
&lt;br /&gt;
=사용방법=&lt;br /&gt;
*toUpperCase – 영문글자열을 대문자로 변환&lt;br /&gt;
예)&lt;br /&gt;
&amp;lt;code lang=&amp;quot;jsp&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;td class=&amp;quot;Mbox_bg&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;m_oper&amp;quot; size=&amp;quot;15&amp;quot; maxlength=&amp;quot;10&amp;quot; class=&amp;quot;Mbox_C&amp;quot; onBlur=&amp;quot;toUpperCase(id)&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*참조) gmdat_common.js 의 toUpperCase  &lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
 * 받은 영문글자열을 대문자로 바꾸기&lt;br /&gt;
 */&lt;br /&gt;
function toUpperCase(Uid) {&lt;br /&gt;
	var Uname = document.getElementById(Uid).value;&lt;br /&gt;
	if (Uname == &amp;quot;&amp;quot; || Uname == 0)&lt;br /&gt;
	{&lt;br /&gt;
		return;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
	{	&lt;br /&gt;
		Uname = Uname.toUpperCase();&lt;br /&gt;
					document.getElementById(Uid).value = Uname;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/code&amp;gt;&lt;br /&gt;
*showCalendar – 달력 생성&lt;br /&gt;
밑의 예제는 gageMast[1].jsp 파일의 일부이다. onClick  이벤트를 showCalendar 로 지정하여 달력팝업창을 나타낸다.. 여기서 'm_regiDate'는  달력팝업창에서 선택할 날짜를 입력할 input의 id이고, 'cal3'은 달력팝업창을 띄울 div의 id이다. &lt;br /&gt;
&amp;lt;code lang=&amp;quot;jsp&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;td class=&amp;quot;Mnn_label&amp;quot; nowrap width='10%'&amp;gt;등록일자&amp;lt;/td&amp;gt;&lt;br /&gt;
       &amp;lt;td class=&amp;quot;Mbox_bg&amp;quot;&amp;gt;&lt;br /&gt;
       	&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;m_regiDate&amp;quot; size=&amp;quot;15&amp;quot; maxlength=&amp;quot;8&amp;quot; class=&amp;quot;Mbox_D&amp;quot;&lt;br /&gt;
 isDate=&amp;quot;Y&amp;quot; readonly&amp;gt;&lt;br /&gt;
       	&amp;lt;input type=&amp;quot;button&amp;quot; class=&amp;quot;submit1&amp;quot; value=&amp;quot;달력&amp;quot;&lt;br /&gt;
 onClick=&amp;quot;showCalendar('m_regiDate', 'cal3');&amp;quot;/&amp;gt;&lt;br /&gt;
       	&amp;lt;div id=&amp;quot;cal3&amp;quot; style=&amp;quot;position:absolute; left:224; top:360; z-index:1&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
       &amp;lt;/td&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*참조) gmdat_common.js 의 showCalendar &lt;br /&gt;
&amp;lt;code lang=&amp;quot;js&amp;quot;&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * calendar 생성&lt;br /&gt;
 */&lt;br /&gt;
function showCalendar(domId, posiId) {&lt;br /&gt;
	var cal = new Ext.DatePicker({&lt;br /&gt;
		dayNames : ['일','월','화','수','목','금','토'],     // 요일의 이름을 넣어줍니다. &lt;br /&gt;
	   	monthNames : ['1월','2월','3월','4월','5월','6월','7월','8월','9월','10월','11월','12월'],     // 월 이름 이구여&lt;br /&gt;
	   	format : &amp;quot;Y년 m월 d일&amp;quot;,             // 기본 데이타 형식입니다.&lt;br /&gt;
	   	disabledDays : null,&lt;br /&gt;
	   	disabledDaysText : &amp;quot;사용불가&amp;quot;,&lt;br /&gt;
	   	disabledDates : null,&lt;br /&gt;
	   	disabledDatesText : &amp;quot;사용불가&amp;quot;,&lt;br /&gt;
	   	minValue : null,&lt;br /&gt;
	   	maxValue : null,&lt;br /&gt;
	   	minText : &amp;quot;필드 안의 날짜는 반드시 {0}의 이후이어야 한다. &amp;quot;,&lt;br /&gt;
	   	maxText : &amp;quot;필드 안의 날짜는 반드시 {0}의 이전이어야 한다. &amp;quot;,&lt;br /&gt;
	   	invalidText : &amp;quot;{0} 은 유효한 날짜가 아닙니다. - 반드시 {1}과 같은 형식이어야 합니다.&amp;quot;,&lt;br /&gt;
	   	nextText : &amp;quot;다음 달(Ctrl+Right)&amp;quot;,&lt;br /&gt;
	   	prevText : &amp;quot;이전 달(Ctrl+Left)&amp;quot;,&lt;br /&gt;
	   	todayText : &amp;quot;오늘은 {0}&amp;quot;     // 처음 생성하면 하단에 Today라고 버튼이 있는데 그 버튼의 메세지를 바꿔줍니다. 이미지에서는 이미 바뀐 상태입니다. &lt;br /&gt;
	});&lt;br /&gt;
	cal.setValue(new Date());   // 오늘 날짜로 달력을 셋팅합니다.&lt;br /&gt;
	cal.render(posiId);&lt;br /&gt;
	cal.on('select', function(cal, date) {&lt;br /&gt;
		Ext.get(domId).dom.value = formatDate(date);&lt;br /&gt;
		cal.destroy();&lt;br /&gt;
	});&lt;br /&gt;
} ‘&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*numberOnly   - 숫자만  입력 가능하도록 설졍&lt;br /&gt;
밑의 예제는 gageMast[1].jsp 파일의 일부이다. onkeypress 이벤트를 numberOnly 로 지정하여 오직 숫자만 입력할 수 있도록 설정한다.&lt;br /&gt;
&amp;lt;code lang='jsp'&amp;gt;&lt;br /&gt;
&amp;lt;td class=&amp;quot;Mbox_bg&amp;quot;&amp;gt;&lt;br /&gt;
       &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;m_acquCost&amp;quot; size=&amp;quot;15&amp;quot; maxlength=&amp;quot;50&amp;quot; class=&amp;quot;Mbox_F&amp;quot; isAmt=&amp;quot;Y&amp;quot; onBlur=&amp;quot;setCurrency(id)&amp;quot; onkeypress=&amp;quot;numberOnly()&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*참조) gmdat_common.js 의 numberOnly &lt;br /&gt;
&amp;lt;code lang='js'&amp;gt;&lt;br /&gt;
function numberOnly() {&lt;br /&gt;
	var input_key = event.keyCode;&lt;br /&gt;
	if (!(isNumber( input_key )))&lt;br /&gt;
	{	&lt;br /&gt;
		event.keyCode = '0';&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</description>
			<pubDate>Tue, 08 Jul 2008 04:42:18 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Ext-js_common_script</comments>		</item>
		<item>
			<title>Ext-js code</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Ext-js_code</link>
			<description>&lt;p&gt;바꾼내용 간추리기: New page: =javascrpt파일= ==findCode함수==  *화면이 로딩될 때 코드값을 가져오는 메소드(findCode)를 onReady메소드 안에 넣는다.   *findCode 메소드에서는 Ext.Ajax.r...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=javascrpt파일=&lt;br /&gt;
==findCode함수== &lt;br /&gt;
*화면이 로딩될 때 코드값을 가져오는 메소드(findCode)를 onReady메소드 안에 넣는다.  &lt;br /&gt;
*findCode 메소드에서는 Ext.Ajax.request라는 메소드 사용하여 서버에request를 보낼 url 을 지정한다. 서버로부터 값을 제대로 받아왔는지 확인하기 위해 success 와 failure을 지정해주고 success  function 안에는 try /catch 문을 선언한다.  &lt;br /&gt;
*alert(r.responseText)을 통해 받아온 JSON 데이터값을 alert창으로 확인한다.&lt;br /&gt;
*cbStore3.loadData 로  cbStore3라는  JsonStore 에  받아온 데이터 중 해당되는 데이터를  담는다.  &lt;br /&gt;
&amp;lt;code lang=&amp;quot;javescript&amp;quot;&amp;gt;&lt;br /&gt;
Ext.onReady(function(){&lt;br /&gt;
     findCode();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;javescript&amp;quot;&amp;gt;&lt;br /&gt;
function findCode(){&lt;br /&gt;
params = &amp;quot;{&amp;quot;  + &amp;quot;}&amp;quot;&lt;br /&gt;
           	&lt;br /&gt;
		Ext.Ajax.request({&lt;br /&gt;
		    url: '/mdms/deptInfo/findCodes.action',&lt;br /&gt;
		   jsonData: params,&lt;br /&gt;
		    headers: {&lt;br /&gt;
            	'Content-Type': 'application/json'&lt;br /&gt;
        	},		               &lt;br /&gt;
		    success: function( r, o ) {&lt;br /&gt;
		    	alert(r.responseText);	    	&lt;br /&gt;
		    	try {&lt;br /&gt;
		    		cbStore3.loadData(Ext.decode(r.responseText));&lt;br /&gt;
		    	&lt;br /&gt;
		    	} catch(e) {&lt;br /&gt;
		    	}&lt;br /&gt;
	    	},&lt;br /&gt;
			failure: function( r, o ) {&lt;br /&gt;
			alert(&amp;quot;ERR&amp;quot;+r.responseText);&lt;br /&gt;
			}&lt;br /&gt;
		})&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
==JsonStore==&lt;br /&gt;
*cbStore3는 findCode에서 받아온 데이터를  저장하기  위한   JsonStore 이다. New Ext.data.JsonStore 로 cbStore3 라는 JsonStore 를 생성한다. root에는 action의 return  값을  fields에는 List로 받은  return  값의 각Object들을 넣는다. '&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;javescript&amp;quot;&amp;gt;&lt;br /&gt;
    //#########################################################################&lt;br /&gt;
	/* &lt;br /&gt;
	 * JsonStore 생성&lt;br /&gt;
	 */&lt;br /&gt;
// ###########################################################################&lt;br /&gt;
	var cbStore3 = new Ext.data.JsonStore({&lt;br /&gt;
		root:'inspTrgtList',&lt;br /&gt;
	    fields: [ 'id', 'name', 'parentId']&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
7.3.3. ComboBox&lt;br /&gt;
*new Ext.form.ComboBox 로  combo3라는 ComboBox를 생성한다&lt;br /&gt;
*밑의 예제에 있는  property들 중에  빨간글씨로 지정되어 있는 것들은  모든 ComboBox마다  해당되는 데이터를 바인딩하고,  그 외의 것들은 밑에 예제와 동일하게 지정한다. &lt;br /&gt;
&amp;lt;code lang=&amp;quot;javescript&amp;quot;&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
	 * 콤보박스 생성&lt;br /&gt;
	 */&lt;br /&gt;
var combo3 = new Ext.form.ComboBox({&lt;br /&gt;
	    store: cbStore3,&lt;br /&gt;
	     displayField:'name',&lt;br /&gt;
	     valueField: 'id',&lt;br /&gt;
	    typeAhead: true,&lt;br /&gt;
	    mode: 'local',&lt;br /&gt;
	    triggerAction: 'all',&lt;br /&gt;
	    emptyText:'Select a state...',&lt;br /&gt;
	    selectOnFocus:true,&lt;br /&gt;
	    editable: true,&lt;br /&gt;
	    applyTo: 'm_inspTrgtCode'&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*Preperty 설명)&lt;br /&gt;
**	Store:  바인딩할  store 지정,&lt;br /&gt;
**	displayField : 화면에 보여지는 text 값&lt;br /&gt;
**	valueField:  실제  저장되는  value 값&lt;br /&gt;
**	Mode: local  data를 로당할지  server에서  data를 가져와  로딩할지 여부 (local은 local  data를 로드한다는 뜻이고 remote는  server로부터 data를 로드한다는 뜻이다)&lt;br /&gt;
**	triggerAction:   이미 선택된 값 외의  코드값도 선택할 수 있게할지  여부( triggerAction을 all이라고 지정하지 않는다면  이미  값이 있거나,  한번 선택된 코드값은 수정할 수 없음)&lt;br /&gt;
**	emptyText :  combox에 값이 바인딩이 되지 않았을 때 기본으로 보여지는 텍스트&lt;br /&gt;
**	selectOnFocus: combox를 클릭했을 때, combox에 바인딩된  데이터를 Focus 할지 여부이다. (True로 설정해놓았으면, combox를 클릭했을 때, combox에 바인딩된  데이터가  파란네모박스  안에  흰글씨로 Focus 됨)&lt;br /&gt;
**	Editable: combox 수정여부(ombox에서 선택하기 않고  직접입력이 가능하도록 설정하고 싶다면 true로 지정)&lt;br /&gt;
**	applyTo:  실제 바인딩 할 jsp파일의 id&lt;/div&gt;</description>
			<pubDate>Tue, 08 Jul 2008 04:34:24 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Ext-js_code</comments>		</item>
		<item>
			<title>JCF WebStandard</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/JCF_WebStandard</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{정보|JCF에서는 그리드 상에서 editing이 필요한 경우에서만 ext-js를 사용하도록 권장한다.}}&lt;br /&gt;
*Ext JS를 이용한 개발&lt;br /&gt;
**[[Ext-JS CRUD|Ext JS 그리드에서 CRUD만들기]]&lt;br /&gt;
**[[ext-js paging|Ext JS 그리드에서 페이징처리하기]]&lt;br /&gt;
**[[exj-js multi grid|연관된 2개의 Ext JS 그리드 처리하기]] &lt;br /&gt;
**[[ext-js code|Ext JS에서 코드처리하기]]&lt;br /&gt;
**[[ext-js linked combo| Ext JS Linked Combo Box 처리]]&lt;br /&gt;
**[[ext-js grid combol | Ext JS 그리드에서 Combo box 사용 시, Display 값 표시하기]]&lt;br /&gt;
**[[ext-js common script|Ext JS 공통스크립트 사용하기]]&lt;br /&gt;
*웹표준 기술을 이용한 개발&lt;br /&gt;
**[[webStandard_extJS|일반 그리드에서 ext-js느낌내기]]&lt;br /&gt;
**[[EDU USER DEV|CRUD만들기]]&lt;br /&gt;
**[[grid에서 checkbox선택하기]]&lt;br /&gt;
**[[Paging|페이징처리하기]]&lt;br /&gt;
**[[사용자주소 코드처리|코드처리하기]]&lt;br /&gt;
**[[jquery calendar|JQuery를 이용한 달력 만들기]]&lt;br /&gt;
*기타 자료들&lt;br /&gt;
**[[Naming Convention|네이밍 표준 규칙]]&lt;br /&gt;
**[[JCF3 id|채번관리하기(id생성)]]&lt;br /&gt;
**[http://trirand.com/jqgrid/jqgrid.html# jqGrid]&lt;br /&gt;
**[http://www.webplicity.net/flexigrid/# Flexigrid for jQuery]&lt;br /&gt;
**[http://ajaxian.com/archives/extending-firebug-tutorials# Extending Firebug Tutorials]&lt;/div&gt;</description>
			<pubDate>Tue, 08 Jul 2008 02:53:44 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:JCF_WebStandard</comments>		</item>
		<item>
			<title>JcfRoadMap ReferenceArchitecture</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/JcfRoadMap_ReferenceArchitecture</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물: JCF 로드맵과 발전방향&lt;br /&gt;
*작성자: 서경진&lt;br /&gt;
*최초작성일 : 2008/07/07&lt;br /&gt;
*최종작성일 : 2008/07/07&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
* 이 문서에는 JCF의 Reference Architecture를 기반으로 진행될 로드맵과 발전방향에 대하여 설명할 것이다.&lt;br /&gt;
}}&lt;br /&gt;
{{경고|&lt;br /&gt;
*이 문서는 현재 작성중에 있습니다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=JCF Reference Architecture=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFReferenceArchitecture.JPG|910px|thumb|center|JCF Reference Architecture]]&lt;br /&gt;
&lt;br /&gt;
=JCF RoadMap=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[그림:JCFRoadMap.JPG|900px|thumb|center|JCF RoadMap]]&lt;br /&gt;
&lt;br /&gt;
=JCF 발전방향=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==다중 채널 및 UI 통합(MCI: Multi-Channel Interface)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==개발환경 고도화(CI &amp;amp; Agile)==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===개인개발환경===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===개발협업환경===&lt;br /&gt;
&lt;br /&gt;
*개발 포탈&lt;br /&gt;
&lt;br /&gt;
===CI환경===&lt;br /&gt;
&lt;br /&gt;
*자동화&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==공통모듈 고도화==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==SOA &amp;amp; Integration==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===웹서비스 (Web Services)===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ESB (Enterprise Service Bus)===&lt;br /&gt;
&lt;br /&gt;
==JCF 아키텍처 간소화==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Metadata 통합관리==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Runtime Patterns 정의==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==TDDx2 (Test Driven Development &amp;amp; Task Driven Development)==&lt;/div&gt;</description>
			<pubDate>Mon, 07 Jul 2008 07:33:17 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:JcfRoadMap_ReferenceArchitecture</comments>		</item>
		<item>
			<title>Spring MVC ControllerWorkFlow</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_MVC_ControllerWorkFlow</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물: Spring MVC Architecturing&lt;br /&gt;
*작성자: 서경진&lt;br /&gt;
*최초작성일 : 2008/07/07&lt;br /&gt;
*최종작성일 : 2008/07/09&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
* 이 문서에는 Spring MVC에서 Request를 처리하는 WorkFlow에서 아키텍처를 결정하기 위한 구성요소들에 대하여 설명한 것이다.&lt;br /&gt;
}}&lt;br /&gt;
{{경고|&lt;br /&gt;
*이 문서는 현재 작성중에 있습니다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=Spring MVC 처리과정=&lt;br /&gt;
Spring MVC는 클라이언트의 요청을 처리하기 위해 다양한 클래스를 기반으로, 다음과 같은 처리과정을 통해 View를 제공하게 된다.&lt;br /&gt;
*일반적으로 모델 2 개발 방식의 최초 진입지점인 컨트롤러를 담당하는 대상이 서블릿인 것처럼, Spring MVC 또한 클라이언트의 요청이 처음으로 진입되는 지점으로 서블릿인 DispatcherServlet을 정의하였다(①). DispatcherServlet은 Spring MVC에서 가장 핵심적인 기능을 구현하고 있는 클래스로서 클라인언트로부터 발생한 하나의 요청을 처리하기 위하여 필요한 클래스들의 중계를 담당하는 역할을 한다.&lt;br /&gt;
*클라이언트로부터 요청이 들어오면 DispatcherServlet은 빈 설정파일에 정의되어 있는 HandlerMapping을 이용하여 요청 URL에 해당하는 Controller 객체를 얻게 된다(②). 빈 설정파일에 정의되어 있는 Controller는 일반적으로 요청 URL을 기반으로 정의되어 있다. 따라서 HandlerMapping은 요청 URL에 Mapping되어 있는 Controller를 DispatcherServlet에 반환하게 된다.&lt;br /&gt;
*DispatcherServlet은 HandlerMapping으로부터 Controller를 얻게되면 요청에 대한 모든 작업을 Controller에게 위임하게 된다(③).&lt;br /&gt;
*Controller는 Spring MVC를 구현하기 위하여 개발자들이 직접 구현을 담당하게 되는 부분으로 클라이언트로부터 전달된 인자에 대한 유효성 검증작업, 비즈니스 계층과의 통신, 비즈니스 계층에서 발생한 에러에 대한 처리, 작업 완료후 이동하게 될 뷰화면등에 대한 모든 처리를 담당하게 된다.&lt;br /&gt;
*Controller는 비즈니스 계층과의 통신을 완료한 다음 비즈니스 계층에서 전달된 모델 데이터와 클라이언트에게 보여줄 뷰 화면에 대한 정보를 ModelAndView 클래스에 담아서 DispatcherServlet에 반환하게 된다(④).&lt;br /&gt;
*DispatcherServlet으로 전달된 ModelAndView 클래스의 View정보는 View 객체(View Object) 또는 논리적인 View 이름(String)을 가지게 된다. ModelAndView 클래스에 저장되어 있는 View정보가 View 객체를 통하여 Controller에서 반환되었다면 DispatcherServlet은 View 객체를 이용하여 클라이언트에 화면을 출력하게 된다(⑥).&lt;br /&gt;
*그러나 ModelAndView에 저장되어 있는 View 정보가 논리적인 View 이름일 경우에는 빈 설정파일에 정의되어 있는 ViewResolver 클래스를 이용하여 클라이언트에게 출력할 View 객체를 얻게 된다(⑤).&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringMVC_RequestHandlingFlow.JPG|700px|thumb|center|Spring MVC Request 처리과정 및 대상 클래스 생명주기(원본:자바지기)]]&lt;br /&gt;
&lt;br /&gt;
위에서 처럼 하나의 요청을 처리하기 위하여 관여하고 있는 클래스가 상당히 많다는 것을 알 수 있다. 그러나 요청을 처리하기 위하여 모든 클래스를 개발자들이 직접 구현할 필요는 없다. 하나의 요청이 추가될 때마다 개발자들이 구현할 필요가 있는 클래스는 Controller 클래스 하나뿐이다. 나머지 클래스는 Spring MVC에서 제공하는 클래스를 이용하여 구현하는 것이 가능하다. 물론 모델 데이터를 출력할 뷰 화면(JSP 또는 Velocity등) 또한 개발자들이 직접 구현해야 한다. 위에서 살펴보았던 대로 Spring MVC가 하나의 요청을 처리하기 위하여 실행되는 단계를 보면 그리 복잡하지 않은 것처럼 생각될 수 있다. 그러나 실질적인 Spring MVC의 복잡도는 유연성을 제공하기 위하여 지원되는 무수히 많은 옵션들 때문이다. Spring MVC는 웹 애플리케이션의 유연성을 지원한다는 명목하에 다양한 종류의 HandlerMapping, Controller, ViewResolver, View 클래스들을 지원하고 있다.&lt;br /&gt;
&lt;br /&gt;
다시 한번 간단히 정리하면 다음과 같다.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. Resource에 대한 클라이언트의 Request&lt;br /&gt;
2. Spring Front Controller가 Request를 가로체서 적당한 Handler Mappings을 찿는다&lt;br /&gt;
3. Handler Adapters와 함께 디스패처 서블릿은 Controller에 Request를 디스패치한다.&lt;br /&gt;
4. Controller는 클라이언트 Request를 처리하고 FrontController에게 ModelAndView의 폼안에 Model과 View를 리턴한다.&lt;br /&gt;
5. Front Controller는 View Resolver 객체에게 문의하여 실제 View를 찿는다.&lt;br /&gt;
6. 클라이언트에게 선택된 뷰를 출력한다&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==HandlerMapping을 이용하여 URL과 Controller 연결하기==&lt;br /&gt;
HandlerMapping은 클라이언트가 요청한 URL과 Controller를 매핑하는 역할을 수행한다. 그 동작과정은 클라이언트 Request에 대하여 Dispatcher가 Requet와 Handling 객체맵에서 적당한 Handler Mapping을 찾는다. HanlerMapping은 클라이언트 URL이 Handler에게 매핑되는 방법을 제공한다. Spring MVC는 같은 기능을 지원하기 위하여 여러가지 옵션을 제공하고 있는데, Controller와 URL의 매핑하는 HandlerMapping 또한 여러 가지 방법을 제공하고 있다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringMVC_HandlerMapping.JPG|700px|thumb|center|HandlerMapping Interface의 계층구조]]&lt;br /&gt;
&lt;br /&gt;
위의 그림은 Spring MVC가 제공하는 HandlerMapping의 다양한 방법을 구현한 클래스의 계층구조를 나타내고 있다. 실제적으로 HandlerMapping을 위해 Spring에서 제공하는 구현체는 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
*BeanNameUrlHandlerMapping&lt;br /&gt;
*SimpleUrlHandlerMapping&lt;br /&gt;
*CommonsPathMapHandlerMapping&lt;br /&gt;
*ControllerBeanNameHandlerMapping&lt;br /&gt;
*ControllerClassNameHandlerMapping&lt;br /&gt;
*DefaultAnnotationHandlerMapping&lt;br /&gt;
&lt;br /&gt;
===BeanNameUrlHandlerMapping===&lt;br /&gt;
*BeanNameUrlHandlerMapping은 빈 이름과 URL을 Mapping한다.&lt;br /&gt;
*BeanNameUrlHandlerMapping을 이용하여 Mapping하는 방법은 Struts 프레임워크에서 사용하는 방법과 유사하므로 Struts 프레임워크를 사용하여 개발한 경험이 있다면 익숙하게 대응할 수 있다.&lt;br /&gt;
*Struts와 다른 점이라면 Spring MVC의 BeanNameUrlHandlerMapping은 매핑을 위한 경로정보로 ANT 빌드툴에서 경로정보를 표현하는 스타일을 사용할 수 있다.&lt;br /&gt;
**예를 들어 ANT 빌드툴에서 별표(*), 물음표(?)와 같은 기호들을 사용할 수 있듯이 BeanNameUrlHandlerMapping에서도 사용이 가능하다.&lt;br /&gt;
**&amp;lt;bean name=&amp;quot;/*/.html&amp;quot; class=&amp;quot;com.daewoobrenic.jcf.web.springmvc.BaseUrlFilenameViewController&amp;quot;/&amp;gt;&lt;br /&gt;
*빈 설정파일에 HandlerMapping이 설정되어 있지 않을 경우 Spring MVC는 BeanNameUrlHandlerMapping을 디폴트 HandlerMapping으로 설정한다.&lt;br /&gt;
&lt;br /&gt;
===SimpleUrlHandlerMapping===&lt;br /&gt;
*SimpleUrlHandlerMapping은 매핑에 대한 정보를 각각의 Controller에서 설정하는 것이 아니라 하나의 저장소에서 관리한다.&lt;br /&gt;
*Controller를 개발하는 개발자들은 빈을 정의하기만 하고 이 Controller가 어떻게 매핑되어서 사용되는지에 대해서는 몰라도 된다.&lt;br /&gt;
*SimpleUrlHandlerMapping은 서블릿명-servlet.xml 파일에 다음과 같이 정의한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!--SimpleUrlHandlerMapping을 사용할 경우 방법 #1과 방법 #2가 있다.--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;!--SimpleUrlHandlerMapping 방법 #1--&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;urlMapping&amp;quot; class=&amp;quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;mappings&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;props&amp;gt;&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;**/*.html&amp;quot;&amp;gt;staticViewController&amp;lt;/prop&amp;gt;&lt;br /&gt;
            ......&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/user/listUser.do&amp;quot;&amp;gt;userController&amp;lt;/prop&amp;gt;&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/user/viewUser.do&amp;quot;&amp;gt;userController&amp;lt;/prop&amp;gt;&lt;br /&gt;
            ......&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/board/board.do&amp;quot;&amp;gt;boardController&amp;lt;/prop&amp;gt;&lt;br /&gt;
        &amp;lt;/props&amp;gt;&lt;br /&gt;
    &amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--SimpleUrlHandlerMapping 방법 #2--&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;urlMapping&amp;quot; class=&amp;quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;mappings&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;bean class=&amp;quot;org.springframework.beans.factory.config.PropertiesFactoryBean&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;property name=&amp;quot;location&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;value&amp;gt;/WEB-INF/UrlMapping.properties&amp;lt;/value&amp;gt;&lt;br /&gt;
            &amp;lt;/property&amp;gt;&lt;br /&gt;
        &amp;lt;/bean&amp;gt;&lt;br /&gt;
    &amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*SimpleUrlHandlerMapping 방법 #2를 적용한 경우에는 UrlMapping의 프로퍼티를 설정하는 것이 필요하다.&lt;br /&gt;
*위의 xml에서 정의한 UrlMapping.properties에 다음과 같은 mapping 정보를 기술하면 된다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
**/*.html=staticViewController&lt;br /&gt;
&lt;br /&gt;
## user module mapping&lt;br /&gt;
/user/listUser.do=userController&lt;br /&gt;
/user/viewUser.do=userController&lt;br /&gt;
&lt;br /&gt;
## board module mapping&lt;br /&gt;
/board/board.do=boardController&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*SimpleUrlHandlerMapping의 장점&lt;br /&gt;
**어플리케이션의 규모가 클 경우 매핑 정보를 수정할 필요가 있을 때 BeanNameUrlHandlerMapping보다 더 효율적으로 관리하는 것이 가능하다.&lt;br /&gt;
**개발자와 통합관리자가 분리된 경우 개발자는 매핑에 대한 문제에 신경쓰지 않고 Controller 클래스만 개발하면 된다.&lt;br /&gt;
**관리하는 입장에서 SimpleUrlHandlerMapping을 사용하면 mapping 정보를 통합하여 관리할 수 있다.&lt;br /&gt;
&lt;br /&gt;
*SimpleUrlHandlerMapping의 단점&lt;br /&gt;
**Controller빈을 정의하고 매핑을 별도로 설정하는 불편함이 있다.&lt;br /&gt;
**개발자와 통합관리자가 동일한 경우 개발자는 SimpleUrlHandlerMapping을 사용하는 매핑 방법이 불편할 수도 있다.&lt;br /&gt;
&lt;br /&gt;
BeanNameUrlHandlerMapping과 SimpleUrlHandlerMapping에 대한 사용방법은 현재 진행하고 있는 프로젝트가 어느 부분에 중점을 두고 있느냐에 따라 결정하면 된다.&lt;br /&gt;
&lt;br /&gt;
===CommonsPathMapHandlerMapping===&lt;br /&gt;
*드믈게 사용되는 핸들러 매핑이다.&lt;br /&gt;
*컨트롤러의 소스파일에서 직접 URL 매핑을 지정하는 방법이다.&lt;br /&gt;
*다음과 같은 방법으로 설정하면 HandlerMapping을 제공할 수 있다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
*@@ org.springframework.web.servlet.handler.commonsattributes.&lt;br /&gt;
*PathMap(&amp;quot;/listUser.jsp&amp;quot;)&lt;br /&gt;
*/&lt;br /&gt;
public class UserController{&lt;br /&gt;
......&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
*@@ org.springframework.web.servlet.handler.commonsattributes.&lt;br /&gt;
*PathMap(&amp;quot;/listCode.jsp&amp;quot;)&lt;br /&gt;
*/&lt;br /&gt;
public class CodeController{&lt;br /&gt;
......&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*클래스에서 CommonsAttribute 설정을 활성화하기 위해서 설정파일(서블릿명-servlet.xml)에 다음과 같은 설정이 필요하다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;beans&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
    &amp;lt;bean id=&amp;quot;metaHandlerMapping&amp;quot; class=&amp;quot;org.springframework.web.servlet.handler.metadata.CommonsPathMapHandlerMapping&amp;quot;/&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ControllerBeanNameHandlerMapping===&lt;br /&gt;
*BeanNameUrlHandlerMapping와 유사하게 URL과 빈이름을 매핑한다.&lt;br /&gt;
*차이점이 있다면 아래의 소스에서 확인할 수 있듯이 beanName을 기반으로 URL을 구성하는 방식이 다르다는 것이다.&lt;br /&gt;
*ControllerBeanNameHandlerMapping는 buildUrlsForHandler 메소드에서 Handler를 위한 mapping을 제공한다.&lt;br /&gt;
*generatePathMapping 메소드에서는 beanName과 선택적으로 지정된 urlPrefix와 urlSuffix를 조합하여 PathMap을 생성한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ControllerBeanNameHandlerMapping extends AbstractControllerUrlHandlerMapping {&lt;br /&gt;
	private String urlPrefix = &amp;quot;&amp;quot;;&lt;br /&gt;
	private String urlSuffix = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        ......&lt;br /&gt;
&lt;br /&gt;
        protected String[] buildUrlsForHandler(String beanName, Class beanClass) {&lt;br /&gt;
		List urls = new ArrayList();&lt;br /&gt;
		urls.add(generatePathMapping(beanName));&lt;br /&gt;
		String[] aliases = getApplicationContext().getAliases(beanName);&lt;br /&gt;
		for (int i = 0; i &amp;lt; aliases.length; i++) {&lt;br /&gt;
			urls.add(generatePathMapping(aliases[i]));&lt;br /&gt;
		}&lt;br /&gt;
		return StringUtils.toStringArray(urls);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
        /**&lt;br /&gt;
        * Prepends a '/' if required and appends the URL suffix to the name.&lt;br /&gt;
        */&lt;br /&gt;
        protected String generatePathMapping(String beanName) {&lt;br /&gt;
	        String name = (beanName.startsWith(&amp;quot;/&amp;quot;) ? beanName : &amp;quot;/&amp;quot; + beanName);&lt;br /&gt;
	        StringBuffer path = new StringBuffer();&lt;br /&gt;
	        if (!name.startsWith(this.urlPrefix)) {&lt;br /&gt;
		        path.append(this.urlPrefix);&lt;br /&gt;
	        }&lt;br /&gt;
	        path.append(name);&lt;br /&gt;
	        if (!name.endsWith(this.urlSuffix)) {&lt;br /&gt;
		        path.append(this.urlSuffix);&lt;br /&gt;
	        }&lt;br /&gt;
	        return path.toString();&lt;br /&gt;
        }&lt;br /&gt;
        ......&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class BeanNameUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Checks name and aliases of the given bean for URLs, starting with &amp;quot;/&amp;quot;.&lt;br /&gt;
	 */&lt;br /&gt;
	protected String[] determineUrlsForHandler(String beanName) {&lt;br /&gt;
		List urls = new ArrayList();&lt;br /&gt;
		if (beanName.startsWith(&amp;quot;/&amp;quot;)) {&lt;br /&gt;
			urls.add(beanName);&lt;br /&gt;
		}&lt;br /&gt;
		String[] aliases = getApplicationContext().getAliases(beanName);&lt;br /&gt;
		for (int i = 0; i &amp;lt; aliases.length; i++) {&lt;br /&gt;
			if (aliases[i].startsWith(&amp;quot;/&amp;quot;)) {&lt;br /&gt;
				urls.add(aliases[i]);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		return StringUtils.toStringArray(urls);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ControllerClassNameHandlerMapping===&lt;br /&gt;
*ControllerClassNameHandlerMapping도 마찬가지로 URL을 구성하는 방법이 다르다.&lt;br /&gt;
*pathMapping을 구성하는데 해당 클래스의 패키지명(packageName)에서 '.'을 '/'로 변경하여 기본 path를 구성한다.&lt;br /&gt;
*다음에 CONTROLLER_SUFFIX가 클래스 이름에 있는 경우 CONTROLLER_SUFFIX를 제거한 이름만 소문자로 구성하여 기본 path에 붙여 pathMapping을 구성한다.&lt;br /&gt;
*만약 MultiActionController인 경우에는 pathMapping과 그 하위에 있는 모든 요청을 처리하게 된다.&lt;br /&gt;
*MultiActionController가 아닌 경우에는 pathMapping에 정의된 모든 Controller 클래스로 요청을 매핑하게 된다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ControllerClassNameHandlerMapping extends AbstractControllerUrlHandlerMapping {&lt;br /&gt;
	/**&lt;br /&gt;
	 * Common suffix at the end of controller implementation classes.&lt;br /&gt;
	 * Removed when generating the URL path.&lt;br /&gt;
	 */&lt;br /&gt;
	private static final String CONTROLLER_SUFFIX = &amp;quot;Controller&amp;quot;;&lt;br /&gt;
	private boolean caseSensitive = false;&lt;br /&gt;
	private String pathPrefix;&lt;br /&gt;
	private String basePackage;&lt;br /&gt;
&lt;br /&gt;
        ......&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Generate the actual URL paths for the given controller class.&lt;br /&gt;
	 * &amp;lt;p&amp;gt;Subclasses may choose to customize the paths that are generated&lt;br /&gt;
	 * by overriding this method.&lt;br /&gt;
	 * @param beanClass the controller bean class to generate a mapping for&lt;br /&gt;
	 * @return the URL path mappings for the given controller&lt;br /&gt;
	 */&lt;br /&gt;
	protected String[] generatePathMappings(Class beanClass) {&lt;br /&gt;
		StringBuffer pathMapping = buildPathPrefix(beanClass);&lt;br /&gt;
		String className = ClassUtils.getShortName(beanClass);&lt;br /&gt;
		String path = (className.endsWith(CONTROLLER_SUFFIX) ?&lt;br /&gt;
				className.substring(0, className.indexOf(CONTROLLER_SUFFIX)) : className);&lt;br /&gt;
		if (path.length() &amp;gt; 0) {&lt;br /&gt;
			if (this.caseSensitive) {&lt;br /&gt;
				pathMapping.append(path.substring(0, 1).toLowerCase()).append(path.substring(1));&lt;br /&gt;
			}&lt;br /&gt;
			else {&lt;br /&gt;
				pathMapping.append(path.toLowerCase());&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		if (isMultiActionControllerType(beanClass)) {&lt;br /&gt;
			return new String[] {pathMapping.toString(), pathMapping.toString() + &amp;quot;/*&amp;quot;};&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			return new String[] {pathMapping.toString() + &amp;quot;*&amp;quot;};&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Build a path prefix for the given controller bean class.&lt;br /&gt;
	 * @param beanClass the controller bean class to generate a mapping for&lt;br /&gt;
	 * @return the path prefix, potentially including subpackage names as path elements&lt;br /&gt;
	 */&lt;br /&gt;
	private StringBuffer buildPathPrefix(Class beanClass) {&lt;br /&gt;
		StringBuffer pathMapping = new StringBuffer();&lt;br /&gt;
		if (this.pathPrefix != null) {&lt;br /&gt;
			pathMapping.append(this.pathPrefix);&lt;br /&gt;
			pathMapping.append(&amp;quot;/&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			pathMapping.append(&amp;quot;/&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		if (this.basePackage != null) {&lt;br /&gt;
			String packageName = ClassUtils.getPackageName(beanClass);&lt;br /&gt;
			if (packageName.startsWith(this.basePackage)) {&lt;br /&gt;
				String subPackage = packageName.substring(this.basePackage.length()).replace('.', '/');&lt;br /&gt;
				pathMapping.append(this.caseSensitive ? subPackage : subPackage.toLowerCase());&lt;br /&gt;
				pathMapping.append(&amp;quot;/&amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		return pathMapping;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===DefaultAnnotationHandlerMapping===&lt;br /&gt;
*Spring MVC에서 지원하는 Annotation인 @RequestMapping에 설정된 URL로 요청이 발행하면 @RequestMapping이 설정된 해당 클래스의 매소드로 매핑된다.&lt;br /&gt;
*아래의 예제에서 설정된 내용은 %WebContextRoot%/deptInfo/findDeptSpecs.action (servlet-mapping pattern을 .action으로 정의함)이 클라이언트에서 요청되었을 때 findDeptSpecs 메소드에서 해당 요청을 처리하게 된다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
@Controller&lt;br /&gt;
public class DeptController extends BaseController {&lt;br /&gt;
	protected static Log log = LogFactory.getLog(DeptController.class);&lt;br /&gt;
&lt;br /&gt;
	@Autowired&lt;br /&gt;
	private DeptInfoService deptInfoService;		//Autowired Component Service&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param searchMap&lt;br /&gt;
	 * @return&lt;br /&gt;
	 */&lt;br /&gt;
	@RequestMapping(&amp;quot;/deptInfo/findDeptSpecs&amp;quot;)&lt;br /&gt;
	public ModelAndView findDeptSpecs(@ModelAttribute(&amp;quot;searchMap&amp;quot;) HashMap searchMap) {&lt;br /&gt;
		return new ModelAndView(&amp;quot;jsonView&amp;quot;, &amp;quot;deptSpecs&amp;quot;, deptInfoService.viewDeptSpecs(super.searchMap));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * @param searchList&lt;br /&gt;
	 * @return&lt;br /&gt;
	 */&lt;br /&gt;
	@RequestMapping(&amp;quot;/deptInfo/saveDeptSpecs&amp;quot;)&lt;br /&gt;
	public ModelAndView saveDeptSpecs(@ModelAttribute(&amp;quot;searchList&amp;quot;) List searchList) {&lt;br /&gt;
		deptInfoService.saveDeptSpec(super.searchList);&lt;br /&gt;
		return new ModelAndView(&amp;quot;jsonView&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==하나의 이상의 HandlerMapping을 사용하기==&lt;br /&gt;
*Spring MVC 기반의 웹 어플리케이션을 개발하다보면, HandlerMapping을 BeanNameUrlHandlerMapping와 SimpleUrlHandlerMapping 모두 사용해야하는 경우가 발생할 수 있다.&lt;br /&gt;
*Spring MVC는 HandlerMapping과 같이 같은 기능을 구현하기 위한 다양한 옵션을 제공하는 기능들이 많다. 그런데 이 같은 옵션들을 하나의 ApplicationContext내에서 같이 사용하고자 할 경우 각 옵션에 우선 순위를 결정하는 것이 가능하다.&lt;br /&gt;
*Spring 프레임워크는 org.springframework.core.Ordered 인터페이스를 구현함으로서 이 같은 기능이 가능하도록 지원하고 있다.&lt;br /&gt;
*BeanNameUrlHandlerMapping와 SimpleUrlHandlerMapping을 같이 사용하도록 빈 설정파일을 변경하면 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;bean class=&amp;quot;org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;order&amp;quot;&amp;gt;&amp;lt;value&amp;gt;1&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;    &amp;lt;!-- Order를 1로 지정함 --&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;bean class=&amp;quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;order&amp;quot;&amp;gt;&amp;lt;value&amp;gt;2&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;    &amp;lt;!-- Order를 2로 지정함 --&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;mappings&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;props&amp;gt;&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/board/board.do&amp;quot;&amp;gt;boardController&amp;lt;/prop&amp;gt;&lt;br /&gt;
        &amp;lt;/props&amp;gt;&lt;br /&gt;
    &amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*하나의 빈 설정파일에서 BeanNameUrlHandlerMapping와 SimpleUrlHandlerMapping을 모두 사용하고 있는 것을 확인할 수 있다.&lt;br /&gt;
*실무 프로젝트를 진행할 때 위에서 처럼 두가지의 HandlerMapping을 사용하는 경우는 많지 않을 것이다.&lt;br /&gt;
*대부분의 프로젝트들이 프로젝트 초반에 어느 HandlerMapping을 사용할지 결정한 다음 프로젝트를 진행할 것이다.&lt;br /&gt;
&lt;br /&gt;
==HandlerAdapter 이해하기==&lt;br /&gt;
*Spring MVC에서 DispatcherServlet이 적당한 HandlerMapping을 찾아 Request를 처리하는 방법은 상당히 동적이다.&lt;br /&gt;
*이와 같은 동적인 행위가 HandlerAdapter의 폼 내에서 이루어 진다.&lt;br /&gt;
*다음 그림은 HandlerAdapter 인터페이스의 구현한 클래스를 나타낸다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringMVC_HandlerAdapter.JPG|700px|thumb|center|HandlerAdapter 인터페이스의 계층구조]]&lt;br /&gt;
&lt;br /&gt;
*처음 언급한 Request 처리방법에서 DispatcherServlet은 적당한 Handler Mapping을 선택하고, Request를 설정파일의 컨트롤러에게 넘긴다.&lt;br /&gt;
*이것은 기본적인 경우로 org.springframework.web.servlet.SimpleControllerHandlerAdapter로 정의된 Default HandlerAdapter에서 처리한다.&lt;br /&gt;
*다음은 Spring MVC의 Default HandlerAdapter인 SimpleControllerHandlerAdapter의 소스코드이다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class SimpleControllerHandlerAdapter implements HandlerAdapter {&lt;br /&gt;
&lt;br /&gt;
	public boolean supports(Object handler) {&lt;br /&gt;
		return (handler instanceof Controller);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)&lt;br /&gt;
			throws Exception {&lt;br /&gt;
&lt;br /&gt;
		return ((Controller) handler).handleRequest(request, response);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public long getLastModified(HttpServletRequest request, Object handler) {&lt;br /&gt;
		if (handler instanceof LastModified) {&lt;br /&gt;
			return ((LastModified) handler).getLastModified(request);&lt;br /&gt;
		}&lt;br /&gt;
		return -1L;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*다른 핸들러 어뎁터 타입으로 Throwaway Controler HandlerAdapter, 그리고 SimpleServletController handlerAdapter가 있다.&lt;br /&gt;
*ThrowawayControllerHandlerAdapter는 DispatcherServlet으로부터 ThrowawayController에게 Request를 전달한다.&lt;br /&gt;
*SimpleServletHandlerAdapter는 Request를 DispatherServlet으로부터 Servlet.service() 메쏘드에 의해 만들어지는 Servlet에게 전달한다.&lt;br /&gt;
*설정파일에 다음과 같이 용도에 따라 설정할 수 있다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;bean id=&amp;quot;throwawayHandler&amp;quot; class = &amp;quot;org.springframework.web.servlet.mvc.throwaway.ThrowawayControllerHandlerAdapter&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--또는--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bean id=&amp;quot;throwawayHandler&amp;quot; class=&amp;quot;org.springframework.web.servlet.mvc.throwaway.SimpleServletHandlerAdapter&amp;quot;/&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==HandlerInterceptor 이해하기==&lt;br /&gt;
*Spring MVC는 서블릿 2.3부터 지원하고 있는 ServletFilter와 같은 기능을 지원하기 위하여 HandlerInterceptor를 지원한다.&lt;br /&gt;
*HandlerInterceptor는 Controller가 실행되기 전, 후에 공통적으로 추가해야하는 작업이 있다면 유용하게 사용할 수 있다.&lt;br /&gt;
*서블릿 2.3을 지원하지 않는 환경하에서 ServletFilter와 같은 효과를 필요로할 경우 유용하게 사용할 수 있다.&lt;br /&gt;
*HandlerInterceptor의 내부는 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package org.springframework.web.servlet;&lt;br /&gt;
&lt;br /&gt;
import javax.servlet.http.HttpServletRequest;&lt;br /&gt;
import javax.servlet.http.HttpServletResponse;&lt;br /&gt;
&lt;br /&gt;
public interface HandlerInterceptor {&lt;br /&gt;
&lt;br /&gt;
	boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)&lt;br /&gt;
	    throws Exception;&lt;br /&gt;
&lt;br /&gt;
	void postHandle(&lt;br /&gt;
			HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)&lt;br /&gt;
			throws Exception;&lt;br /&gt;
&lt;br /&gt;
	void afterCompletion(&lt;br /&gt;
			HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)&lt;br /&gt;
			throws Exception;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Controller 실행 전에 수행될 동작은 preHandle에 정의하고, 실행 후에 수행될 동작은 postHandle에 정의한다.&lt;br /&gt;
&lt;br /&gt;
===HandlerInterceptorAdapter 클래스로 HandlerIntercetor 구현하기===&lt;br /&gt;
*HandlerInterceptorAdapter 클래스는 HandlerIntercetor을 구현하고 있는 클래스로 Adaptor 패턴이 적용된 클래스이다.&lt;br /&gt;
*HandlerIntercetor의 모든 메소드를 구현할 필요가 없는 경우에는 HandlerInterceptorAdapter 클래스를 이용하면 쉽게 구현하는 것이 가능하다.&lt;br /&gt;
*다음 예제는 HandlerIntercetor을 추가하여 Controller가 실행되기 전후에 Logging 메세지를 출력하도록 구현한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
package com.daewoobrenic.jcf.web;&lt;br /&gt;
&lt;br /&gt;
import javax.servlet.http.HttpServletRequest;&lt;br /&gt;
import javax.servlet.http.HttpServletResponse;&lt;br /&gt;
&lt;br /&gt;
import org.apache.commons.logging.Log;&lt;br /&gt;
import org.apache.commons.logging.LogFactory;&lt;br /&gt;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;&lt;br /&gt;
&lt;br /&gt;
public class LoggingHandlerInterceptor extends HandlerInterceptorAdapter {&lt;br /&gt;
    protected final Log logger = LogFactory.getLog(getClass());&lt;br /&gt;
&lt;br /&gt;
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {&lt;br /&gt;
        if( logger.isDebugEnabled() ) {&lt;br /&gt;
            logger.debug(&amp;quot;afterCompletion method called&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object obj) throws Exception {&lt;br /&gt;
        if( logger.isDebugEnabled() ) {&lt;br /&gt;
            logger.debug(&amp;quot;preHandle method called&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return super.preHandle(req, res, obj);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*앞의 예제와 같이 HandlerIntercetor를 구현한 다음 빈 설정파일에 다음과 같이 정의하면 모든 Controller가 실행되기 전후에 공통적으로 필요한 작업을 수행한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;urlMapping&amp;quot; class=&amp;quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;interceptors&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;list&amp;gt;&lt;br /&gt;
            &amp;lt;ref bean=&amp;quot;loggingInterceptor&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;/list&amp;gt;&lt;br /&gt;
    &amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;mappings&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;props&amp;gt;&lt;br /&gt;
            &amp;lt;!-- static view mapping --&amp;gt;&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;**/*.html&amp;quot;&amp;gt;staticViewController&amp;lt;/prop&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/index.do&amp;quot;&amp;gt;indexController&amp;lt;/prop&amp;gt;&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/menu.do&amp;quot;&amp;gt;leftMenuController&amp;lt;/prop&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/changelocale.do&amp;quot;&amp;gt;sessionLocaleController&amp;lt;/prop&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/user/login.do&amp;quot;&amp;gt;loginFormController&amp;lt;/prop&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!-- user module mapping --&amp;gt;&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/user/listUser.do&amp;quot;&amp;gt;userController&amp;lt;/prop&amp;gt;&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/user/viewUser.do&amp;quot;&amp;gt;userController&amp;lt;/prop&amp;gt;&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/user/editUser.do&amp;quot;&amp;gt;userFormController&amp;lt;/prop&amp;gt;&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!-- board module mapping --&amp;gt;&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/board/board.do&amp;quot;&amp;gt;boardController&amp;lt;/prop&amp;gt;&lt;br /&gt;
            &amp;lt;prop key=&amp;quot;/board/editBoard.do&amp;quot;&amp;gt;boardFormController&amp;lt;/prop&amp;gt;&lt;br /&gt;
        &amp;lt;/props&amp;gt;&lt;br /&gt;
    &amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bean id=&amp;quot;loggingInterceptor&amp;quot; class=&amp;quot;com.daewoobrenic.jcf.web.LoggingHandlerInterceptor&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==다양한 형태의 Controller 구성하기==&lt;br /&gt;
*Spring MVC는 용도에 따라 다양한 형태의 Controller를  제공한다.&lt;br /&gt;
*전형적인 Controller 유형으로 ViewContoller, CommandController(FormContoller), MulitActionController, ParameterizableViewController, ServletForwardingController, ServletWrappingController를 제공한다.&lt;br /&gt;
*다음은 Controller Interface가 제공하는 다양한 Abstract 클래스와 Implementation 클래스의 계측구조이다.&lt;br /&gt;
&lt;br /&gt;
[[그림:AbstractController.JPG|800px|thumb|center|Controller Interface의 계층구조]]&lt;br /&gt;
&lt;br /&gt;
===AbstractController===&lt;br /&gt;
*Custom Controller 컴포넌트를 만들려고 할 경우, Controller 인터페이스를 구현하지 말고 AbstractController를 상속한다.&lt;br /&gt;
*기본적으로 GET과 Post를 지원한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class JcfSimpleController extends AbstractController{&lt;br /&gt;
&lt;br /&gt;
    public void handleRequestInternal(HttpServletRequest request, &lt;br /&gt;
	HttpServletResponse response){&lt;br /&gt;
&lt;br /&gt;
        return new ModelAndView(&amp;quot;jcfView&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*DispatcherServlet은 Request와 Response를 파라미터로 하여 handleRequest()를 호출한다&lt;br /&gt;
*Implementation 클래스는 ModelAndView 객체를 리턴한다.&lt;br /&gt;
*Logical View Name과 실제 Physical Location 뷰 리소스 사이의 매핑을 제공하는 일을 하는 ViewResolver라는 컴포넌트가 있다.&lt;br /&gt;
*예제에서 DispatcherServlet이 JcfSimpleController 객체를 invoke할 경우, View의 형태에 따라 JstlView인 경우는 jcfView.jsp로, JsonView인 경우는 jcfView.js를 통해 jcfView.jsp로 클라이언트에 출력될 것이다.&lt;br /&gt;
&lt;br /&gt;
===AbstractCommandController===&lt;br /&gt;
*CommandController는 비즈니스 로직이 사용자에 의해 제공되는 값(모델)에 의해 종속될 때 적용하는 것이 적절하다.&lt;br /&gt;
*Spring MVC에서는 데이터 바인딩 기능뿐만 아니라 유효성 체크기능까지 입력폼으로 모든 기능을 지원하기 위하여 AbstractCommandController 클래스를 지원한다.&lt;br /&gt;
*AbstractCommandController를 기반으로 구현된 Controller는 데이터 바인딩 뿐만 아니라 유효성 체크까지 지원한다.&lt;br /&gt;
*데이터 바인딩 및 데이터에 대한 유효성 체크 기능을 지원하고 있지만 이 Controller를 이용할 경우 입력 화면이 추가될 때마다 Controller가 하나씩 추가되어야 하며, 빈 설정 정보 또한 수정해 주어야 한다는 단점이 있다.&lt;br /&gt;
*다음의 예제에서 사용자 이름의 존재유무에 따라 success.jsp와 failure.jsp가 출력된다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class JcfSimpleController extends AbstractCommandController{&lt;br /&gt;
&lt;br /&gt;
    public JcfSimpleController(){&lt;br /&gt;
        setCommandClass(UserInfo.class);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void handle(HttpServletRequest request, HttpServletResponse response,&lt;br /&gt;
	Object command){&lt;br /&gt;
&lt;br /&gt;
        UserInfo userInfo = (UserInfo)command;&lt;br /&gt;
        if ( exists(userInfo.getUserName){&lt;br /&gt;
            return new ModelAndView(&amp;quot;success&amp;quot;);&lt;br /&gt;
        }else{&lt;br /&gt;
            return new ModelAndView(&amp;quot;failure&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private boolean exits(String username){&lt;br /&gt;
        // Some logic here.&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*클라이언트 파라미터는 UserInfo라는 클래스로 캡슐화되어 있고 username 필드는 UserInfo의 username 속성에 매핑된다.&lt;br /&gt;
*JcfSimpleController의 생성자에서 지정한 CommandClass인 UserInfo는 다음과 같다.&lt;br /&gt;
*CommandClass는 생성자에서 지정할 수 있고 서블릿명-servlet.xml 설정파일에서 Controller의 property로 설정할 수 있다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class UserInfo{&lt;br /&gt;
&lt;br /&gt;
    private String username;&lt;br /&gt;
    // Getters and Setters here.&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===UrlFilenameViewController===&lt;br /&gt;
*웹 애플리케이션을 개발하다보면 샘플 애플리케이션의 메인 페이지처럼 정적인 페이지에 접근해야 되는 경우가 종종 발생한다.&lt;br /&gt;
*웹 애플리케이션의 모든 URL에 대하여 공통적인 작업을 처리할 필요가 있을 경우에는 정적인 페이지 또한 DispatcherServlet을 통하여 접근한다.*&lt;br /&gt;
*정적인 페이지의 경우 비즈니스 계층과 통신하는 부분도 없을 뿐 아니라 단지 HTML이나 JSP화면을 출력하는 역할만을 담당하고 있다.&lt;br /&gt;
*Spring MVC의 특성상 정적인 페이지에 접근하기 위하여 매번 새로운 Controller를 추가하는 것은 불필요한 작업이 아닐 수 없다.&lt;br /&gt;
*이 같은 단점을 보완하기 위하여 Spring MVC는 UrlFilenameViewController를 지원한다.&lt;br /&gt;
*UrlFilenameViewController의 단점은 모든 URL을 다음과 같이 처리한다는 것이다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
http://localhost:8080/jcf/index.html =&amp;gt; /jcf/index.jsp&lt;br /&gt;
http://localhost:8080/jcf/user/index.html =&amp;gt; /jcf/index.jsp&lt;br /&gt;
http://localhost:8080/jcf/board/index.html =&amp;gt; /jcf/index.jsp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*위와 같이 모든 서브 디렉토리에 대한 URL을 하나로 인식하여 처리한다는 것이 단점이다.&lt;br /&gt;
*정적인 페이지는 특정 디렉토리에만 존재하는 것이 아니라 JSP를 관리하는 모든 디렉토리에 존재할 수 있기 때문에 UrlFilenameViewController를 모든 서브 디렉토리에 대해서도 처리하는 것이 가능하도록 다음과 같이 구현할 수 있다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
.... 중간 생략 ....&lt;br /&gt;
&lt;br /&gt;
public class JcfUrlFilenameViewController implements Controller {&lt;br /&gt;
	protected final Log logger = LogFactory.getLog(getClass());&lt;br /&gt;
	&lt;br /&gt;
	public ModelAndView handleRequest(HttpServletRequest request,&lt;br /&gt;
			HttpServletResponse response) {&lt;br /&gt;
		String contextPath = request.getContextPath();&lt;br /&gt;
		String uri = request.getRequestURI();&lt;br /&gt;
		&lt;br /&gt;
		if( logger.isDebugEnabled() ) {&lt;br /&gt;
			logger.debug(&amp;quot;URI : &amp;quot; + uri);&lt;br /&gt;
			logger.debug(&amp;quot;ContextPath : &amp;quot; + contextPath);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		int begin = 0;&lt;br /&gt;
		if ((contextPath == null) || (contextPath.equals(&amp;quot;&amp;quot;))) {&lt;br /&gt;
			begin = 1;&lt;br /&gt;
		} else {&lt;br /&gt;
			begin = contextPath.length() + 1;&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		if( logger.isDebugEnabled() ) {&lt;br /&gt;
			logger.debug(&amp;quot;Begin : &amp;quot; + begin);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		int end;&lt;br /&gt;
		if (uri.indexOf(&amp;quot;;&amp;quot;) != -1) {&lt;br /&gt;
			end = uri.indexOf(&amp;quot;;&amp;quot;);&lt;br /&gt;
		} else if (uri.indexOf(&amp;quot;?&amp;quot;) != -1) {&lt;br /&gt;
			end = uri.indexOf(&amp;quot;?&amp;quot;);&lt;br /&gt;
		} else {&lt;br /&gt;
			end = uri.length();&lt;br /&gt;
		}&lt;br /&gt;
		String fileName = uri.substring(begin, end);&lt;br /&gt;
		if (fileName.indexOf(&amp;quot;.&amp;quot;) != -1) {&lt;br /&gt;
			fileName = fileName.substring(0, fileName.lastIndexOf(&amp;quot;.&amp;quot;));&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		for (Enumeration en = request.getParameterNames(); en.hasMoreElements();) {&lt;br /&gt;
			String attribute = (String) en.nextElement();&lt;br /&gt;
			Object attributeValue = request.getParameter(attribute);&lt;br /&gt;
			&lt;br /&gt;
			if( logger.isDebugEnabled() ) {&lt;br /&gt;
				logger.debug(&amp;quot;set Attribute in Request : &amp;quot; + attribute + &amp;quot;=&amp;quot; + attributeValue);&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			request.setAttribute(attribute, attributeValue);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return new ModelAndView(fileName);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*정적인 페이지에 접근할 때 사용할 확장자를 web.xml에 다음과 같이 추가한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
    &amp;lt;servlet-name&amp;gt;action&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
    &amp;lt;url-pattern&amp;gt;*.html&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
&amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*web.xml에 servlet-mapping을 추가했으므로 확장자가 &amp;quot;.html&amp;quot;에 해당하는 모든 URL은 DispatcherServlet이 처리하게 된다.&lt;br /&gt;
*구현된 JcfUrlFilenameViewController를 서블릿명-servlet.xml 설정파일에 다음과 같이 설정한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;beans&amp;gt;&lt;br /&gt;
	&amp;lt;bean name=&amp;quot;/**/*.html&amp;quot;	class=&amp;quot;com.daewoobrenic.jcf.web.JcfUrlFilenameViewController&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;handlerMapping&amp;quot; class=&amp;quot;org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;viewResolver&amp;quot; class=&amp;quot;org.springframework.web.servlet.view.InternalResourceViewResolver&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;viewClass&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;value&amp;gt;org.springframework.web.servlet.view.JstlView&amp;lt;/value&amp;gt;&lt;br /&gt;
		&amp;lt;/property&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;cache&amp;quot; value=&amp;quot;false&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;prefix&amp;quot; value=&amp;quot;/WEB-INF/jsp/&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;suffix&amp;quot; value=&amp;quot;.jsp&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*MyUrlFilenameViewController에서 사용한 빈 이름을 보면 별표(asterisk, *)를 사용하여 확장자가 &amp;quot;.html&amp;quot;에 해당하는 모든 URL에 대하여 MyUrlFilenameViewController을 매핑(Mapping)하도록 설정하고 있다.&lt;br /&gt;
*Spring MVC에서는 URL과 Controller를 매핑할 때 별표(*)를 사용하는 것이 가능하다.&lt;br /&gt;
&lt;br /&gt;
===MultiActionController===&lt;br /&gt;
*Spring MVC로 웹 애플리케이션을 개발하면 가장 큰 제약사항으로 하나의 페이지가 추가될 때마다 새로운 Controller를 하나씩 추가해야 하는 번거로움이 발생한다&lt;br /&gt;
*이와 같은 번거로움 뿐만아니라 페이지 수가 많아지면 많아질수록 관리해야될 Controller 클래스의 수도 같이 증가하게 되므로 빈 설정파일 또한 상당히 복잡해지기 때문에 Controller의 이 같은 문제점을 해결하기 위하여 Spring MVC는 MultiActionController를 제공한다.&lt;br /&gt;
*MultiActionController는 하나의 Controller를 구현함으로서 다수의 요청을 처리하는 것이 가능하도록 지원한다.&lt;br /&gt;
*Spring MVC에서는 입력 화면(또는 수정화면)에서 전달되는 입력 데이터를 비즈니스 계층에 전달하기 위하여 HttpServletRequest에 담긴 인자와 도메인 모델의 속성을 자동적으로 연결하는 데이터 바인딩을 지원하고 있다.&lt;br /&gt;
*MultiActionController를 이용하여 데이터바인딩을 처리하는 방법은 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class UserController extends MultiActionController {&lt;br /&gt;
	protected static final Log logger = LogFactory.getLog(UserController.class);&lt;br /&gt;
&lt;br /&gt;
	private UserService userService = null;&lt;br /&gt;
&lt;br /&gt;
	public void setUserService(UserService userService) {&lt;br /&gt;
		this.userService = userService;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
               .... 중간 생략 ....&lt;br /&gt;
&lt;br /&gt;
	public ModelAndView add(HttpServletRequest request,&lt;br /&gt;
			HttpServletResponse response) throws Exception {&lt;br /&gt;
		User command = new User();&lt;br /&gt;
		bind(request, command);&lt;br /&gt;
&lt;br /&gt;
		userService.addUser(command);&lt;br /&gt;
&lt;br /&gt;
		return dispatchView(request, response);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public ModelAndView update(HttpServletRequest request,&lt;br /&gt;
			HttpServletResponse response) throws Exception {&lt;br /&gt;
		User command = new User();&lt;br /&gt;
		bind(request, command);&lt;br /&gt;
&lt;br /&gt;
		userService.updateUser(command);&lt;br /&gt;
&lt;br /&gt;
		return dispatchView(request, response);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private ModelAndView dispatchView(HttpServletRequest request,&lt;br /&gt;
			HttpServletResponse response) throws Exception {&lt;br /&gt;
		HttpSession session = request.getSession();&lt;br /&gt;
&lt;br /&gt;
		if (session.getAttribute(&amp;quot;loginUser&amp;quot;) != null) {&lt;br /&gt;
			User loginUser = (User) session.getAttribute(&amp;quot;loginUser&amp;quot;);&lt;br /&gt;
			if (loginUser.isAdmin()) {&lt;br /&gt;
				return list(request, response);&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return new ModelAndView(&amp;quot;redirect:/index.html&amp;quot;);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*MultiActionController 클래스의 bind() 메써드를 이용하여 HttpServletRequest에 전달된 인자를 User 도메인 모델에 전달하고 있는 것을 확인할 수 있다.&lt;br /&gt;
*클라이언트가 입력한 데이터를 도메인 모델과 데이터 바인딩하기 위해서는 입력 화면에서 사용한 속성이름과 도메인 모델의 속성 이름이 같아야 한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;jsp&amp;quot;&amp;gt;&lt;br /&gt;
.... 중간 생략 ....&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;1&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
	bgcolor=&amp;quot;BBBBBB&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;tr&amp;gt;&lt;br /&gt;
		&amp;lt;td width=150 align=center bgcolor=&amp;quot;E6ECDE&amp;quot; height=&amp;quot;22&amp;quot;&amp;gt;사용자 아이디&amp;lt;/td&amp;gt;&lt;br /&gt;
		&amp;lt;td bgcolor=&amp;quot;ffffff&amp;quot; style=&amp;quot;padding-left:10&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;input type=&amp;quot;text&amp;quot; style=&amp;quot;width:150&amp;quot; name=&amp;quot;userId&amp;quot;/&amp;gt;&lt;br /&gt;
		&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;/tr&amp;gt;&lt;br /&gt;
	&amp;lt;tr&amp;gt;&lt;br /&gt;
		&amp;lt;td width=150 align=center bgcolor=&amp;quot;E6ECDE&amp;quot; height=&amp;quot;22&amp;quot;&amp;gt;비밀번호&amp;lt;/td&amp;gt;&lt;br /&gt;
		&amp;lt;td bgcolor=&amp;quot;ffffff&amp;quot; style=&amp;quot;padding-left:10&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;input type=&amp;quot;password&amp;quot; style=&amp;quot;width:150&amp;quot; name=&amp;quot;password&amp;quot;/&amp;gt;&lt;br /&gt;
		&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;/tr&amp;gt;&lt;br /&gt;
	&amp;lt;tr&amp;gt;&lt;br /&gt;
		&amp;lt;td width=150 align=center bgcolor=&amp;quot;E6ECDE&amp;quot; height=&amp;quot;22&amp;quot;&amp;gt;비밀번호 확인&amp;lt;/td&amp;gt;&lt;br /&gt;
		&amp;lt;td bgcolor=&amp;quot;ffffff&amp;quot; style=&amp;quot;padding-left:10&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;input type=&amp;quot;password&amp;quot; style=&amp;quot;width:150&amp;quot; name=&amp;quot;password2&amp;quot;/&amp;gt;&lt;br /&gt;
		&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;/tr&amp;gt;	&lt;br /&gt;
	&amp;lt;tr&amp;gt;&lt;br /&gt;
		&amp;lt;td width=150 align=center bgcolor=&amp;quot;E6ECDE&amp;quot; height=&amp;quot;22&amp;quot;&amp;gt;이름&amp;lt;/td&amp;gt;&lt;br /&gt;
		&amp;lt;td bgcolor=&amp;quot;ffffff&amp;quot; style=&amp;quot;padding-left:10&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;input type=&amp;quot;text&amp;quot; style=&amp;quot;width:240&amp;quot; name=&amp;quot;name&amp;quot;/&amp;gt;&lt;br /&gt;
		&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;/tr&amp;gt;&lt;br /&gt;
	&amp;lt;tr&amp;gt;&lt;br /&gt;
		&amp;lt;td width=150 align=center bgcolor=&amp;quot;E6ECDE&amp;quot; height=&amp;quot;22&amp;quot;&amp;gt;이메일 주소&amp;lt;/td&amp;gt;&lt;br /&gt;
		&amp;lt;td bgcolor=&amp;quot;ffffff&amp;quot; style=&amp;quot;padding-left:10&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;input type=&amp;quot;text&amp;quot; style=&amp;quot;width:240&amp;quot; name=&amp;quot;email&amp;quot;/&amp;gt;&lt;br /&gt;
		&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;/tr&amp;gt;&lt;br /&gt;
	&amp;lt;c:if test=&amp;quot;${ loginUser.admin }&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;tr&amp;gt;&lt;br /&gt;
		&amp;lt;td width=150 align=center bgcolor=&amp;quot;E6ECDE&amp;quot; height=&amp;quot;22&amp;quot;&amp;gt;Admin 유무&amp;lt;/td&amp;gt;&lt;br /&gt;
		&amp;lt;td bgcolor=&amp;quot;ffffff&amp;quot; style=&amp;quot;padding-left:10&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;input type=&amp;quot;checkbox&amp;quot; name=&amp;quot;admin&amp;quot; value=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;/td&amp;gt;&lt;br /&gt;
	&amp;lt;/tr&amp;gt;&lt;br /&gt;
	&amp;lt;/c:if&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
.... 중간 생략 ....&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
.... 중간 생략 ....&lt;br /&gt;
&lt;br /&gt;
public class User extends BaseObject {&lt;br /&gt;
	private String userId = null;&lt;br /&gt;
	private String password = null;&lt;br /&gt;
	private String password2 = null;&lt;br /&gt;
	private String name = null;&lt;br /&gt;
	private String email = null;&lt;br /&gt;
	private boolean admin = false;&lt;br /&gt;
&lt;br /&gt;
               .... 각 속성에 대한 setter, getter 메써드 ....&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*하나의 Controller에 사용자 관리 프로젝트의 모든 기능을 구현하도록 개발하는 것은 Controller 개발을 용이하게 할 뿐만 아니라 빈 설정파일이 단순해지기 때문에 개발 및 관리에 많은 장점이 된다.&lt;br /&gt;
*하지만 Spring MVC의 MultiActionController는 입력 데이터에 대한 유효성 체크 기능을 지원하지 않는다.&lt;br /&gt;
*Spring MVC에서 지원하는 유효성 체크기능을 사용하지 않고 데이터 바인딩 기능만을 이용하고자할 때는 MultiActionController를 이용하여 구현한다.&lt;br /&gt;
&lt;br /&gt;
===SimpleFormController===&lt;br /&gt;
*일반적으로 폼에 데이터를 넣고 submit 하는 목적으로 사용하는데 적합하다.&lt;br /&gt;
*클라이언트가 empInfo.jsp라는 empName, empAge, empSalary 필드가 있는 페이지를 요청한다고 가정하고 요청의 처리가 성공적으로 마치면 empSuccess.jsp이 클라이언트에게 출력된다.&lt;br /&gt;
*이것을 SimpleFormController로 다음과 같이 구현할 수 있다.&lt;br /&gt;
*먼저 Getter와 Setter를 이용하여 다음 내용을 정의하자.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class EmpInfo{&lt;br /&gt;
&lt;br /&gt;
    private String empName;&lt;br /&gt;
    private int empAge;&lt;br /&gt;
    private double empSalary;&lt;br /&gt;
&lt;br /&gt;
    // Getters and setters for the above properties.&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*다음은 SimpleFormController를 확장하여 클래스를 작성한다.&lt;br /&gt;
*여기서 doSubmitAction은 override된 것으로 폼이 submit 될때 호출된다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class EmpFormController extends SimpleFormController{&lt;br /&gt;
&lt;br /&gt;
    public EmpFormController(){&lt;br /&gt;
        setCommandClass(EmpInfo.class);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public void doSubmitAction(Object command){&lt;br /&gt;
        EmpInfo info = (EmpInfo)command;&lt;br /&gt;
        process(info);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    private void process(EmpInfo info){&lt;br /&gt;
        //Do some processing with this object.&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*설정파일에서 submission이 성공했을 경우에 대한 처리를 다음과 같이 정의한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;bean id = &amp;quot;empForm&amp;quot; class=&amp;quot;EmpFormController&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;formView&amp;quot;&amp;gt;&amp;lt;value&amp;gt;empInfo&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;successView&amp;quot;&amp;gt;&amp;lt;value&amp;gt;empSuccess&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*SimpleFormController는 접근하는 URL이 GET/POST에 따라서 서로 다른 방식으로 실행된다.&lt;br /&gt;
*SimpleFormController가 GET/POST에 따라 처리하는 과정을 살펴보면 다음 그림과 같다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringMVC_SimpleFormController_WorkFlow_GET.JPG|750px|thumb|center|GET 방식의 SimpleFormController 처리과정]]&lt;br /&gt;
&lt;br /&gt;
*위의 그림에서 보는 바와 같이 GET 방식으로 접근할 때 여러 단계를 거친 다음에 최종 화면을 출력한다.&lt;br /&gt;
*GET 방식으로 SimpleFormController에 접근할 때의 과정을 살펴보면 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. 처음으로 호출되는 메써드는formBackingObject() 메써드이다. formBackingObject() 메써드는 디폴트로 설정한 Command 클래스의 인스턴스를 생성한다. 만약 수정화면과 같이 데이터베이스로부터 데이터를 추출해야 하는 경우 이 메써드를 오버라이드(Override)해야한다.&lt;br /&gt;
2. Request 패러미터로 전달되는 모든 값은 String이다. 그러나 바인딩할 Command 클래스의 속성으로는 모든 타입을 가질 수 있다. 심지어 String을 Object 타입으로 바인딩해야 하는 경우도 있다. 이와 같이 Request 패러미터를 Command 클래스의 속성과 바인딩시키기 위하여 생성한 Custom Property Editor가 있다면 initBinder() 메써드에서 등록할 수 있다.&lt;br /&gt;
3. 빈 설정파일에서 bindOnNewForm 속성이 true로 설정되어 있다면 Request 패러미터와 Command 클래스의 데이터바인딩을 실행한다.&lt;br /&gt;
4. 빈 설정파일에서 sessionForm 속성이 true로 설정되어 있다면 Command 클래스를 세션에 저장한다.&lt;br /&gt;
5. referenceData() 메써드는 폼 화면을 구현하기 위하여 Command 클래스 이외에 다른 데이터가 필요할 때 오버라이드하여 새롭게 구현하는 것이 가능하다.&lt;br /&gt;
6. showForm() 메써드는 디폴트로 빈 설정파일에서 정의한 &amp;quot;formView&amp;quot; 속성에 해당하는 ModelAndView 객체를 반환한다. 만약 요청인자, 상태에 따라 다른 페이지로 이동하고자 한다면 이 메소드를 오버라이드하여 새롭게 구현하는 것이 가능하다.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Spring MVC에서는 GET 요청에 대한 워크플로우상에서 개발자들이 추가적인 기능을 구현할 수 있도록 지원하고 있다.&lt;br /&gt;
*POST 방식으로 접근할 때가 GET 방식으로 접근할 때보다 상당히 복잡한 워크플로우를 가지고 있다.&lt;br /&gt;
*그 이유는 POST 방식으로 폼 화면의 데이터를 전송하고 있기 때문에 데이터 바인딩, 데이터에 대한 유효성 체크 기능이 추가적으로 구현되어야 하기 때문이다.&lt;br /&gt;
*다음으로 POST 방식으로 SimpleFormController에 접근할 때의 과정을 살펴보면 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringMVC_SimpleFormController_WorkFlow_POST.JPG|650px|thumb|center|POST 방식의 SimpleFormController 처리과정]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. POST 방식으로 접근할 때의 첫 단계는 빈 설정파일에 sessionForm 속성이 true로 설정되어 있는지에 따라 나뉜다. sessionForm 속성이 true로 설정되어 있다면 세션에 저장되어 있는 Command 클래스를 반환하게 된다. 만약 Command 클래스가 세션에 존재하지 않는다면 handleInvalidSubmit() 메써드가 호출되면서 에러 페이지로 이동하게 된다.&lt;br /&gt;
2. sessionForm속성이 설정되어 있지 않다면(디폴트 false) GET 방식으로 접근할 때와 같이 formBackingObject(), initBinder() 메써드를 실행한다.&lt;br /&gt;
3. Request 패러미터와 Command 클래스의 데이터 바인딩을 진행한다.&lt;br /&gt;
4. 데이터 바인딩 후에 추가적인 구현이 필요하다면 onBind() 콜백 메써드를 오버라이드하여 구현하면 된다.&lt;br /&gt;
5. 빈 설정파일에 추가된 Validator가 존재한다면 Validator의 validate() 메써드를 호출함으로서 유효성 체크를 진행한다.&lt;br /&gt;
6. 유효성 체크까지 완료한 후 추가적인 구현이 필요하다면 onBindAndValidate() 콜백 메써드를 오버라이드하여 구현하면 된다.&lt;br /&gt;
7. BindException의 에러 리스트에 에러가 존재할 경우 showForm() 메써드를 호출하여 빈 설정파일의 formView 속성으로 정의되어 있는 페이지로 이동하게 된다.&lt;br /&gt;
8. BindException 에러 없이 정상적으로 처리될 경우 onSubmit() 또는 doSubmitAction() 메써드가 호출된다. onSubmit() 또는 doSubmitAction() 메써드의 디폴트 ModelAndView는 빈 설정파일의 successView 속성으로 정의되어 있는 페이지로 이동한다. 만약 Request 패러미터로 전달되는 값에 따라 다른 페이지로 이동해야한다면 오버라이드함으로서 구현하는 것이 가능하다.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*SimpleFormController는 개발자들에게 유연성을 제공하기 위하여 각 단계마다 콜백 메소드를 제공한다.&lt;br /&gt;
*개발자들은 SimpleFormController를 상속하는 하위 클래스에서 이 콜백 메소드를 오버라이딩(Overriding)함으로서 개발자들이 원하는 기능을 추가적으로 구현할 수 있다.&lt;br /&gt;
*SimpleFormController의 데이터 바인딩이나 유효성체크 등에 특별히 추가적으로 구현할 기능이 없다면 formBackingObject(),onSubmit() 메써드만을 오버라이드함으로서 쉽게 구현할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===CancellableFormController===&lt;br /&gt;
*CancellableFormController는 Form이 Cancel되었을 때 Cancel에 대한 처리를 제공한다.&lt;br /&gt;
*SimpleFormController에서 Cancel이 처리될 경우 대한 것만 추가된 것이다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class JcfCompleteFormController extends CancellableFormController{&lt;br /&gt;
&lt;br /&gt;
    public ModelAndView onCancel(){&lt;br /&gt;
        return new ModelAndView(&amp;quot;cancelView&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==ModelAndView 이해하기==&lt;br /&gt;
*ModelAndView는 컨트롤러에 의해 DispatcherServlet에 반환된다.&lt;br /&gt;
*이 클래스는 Model과 View 정보를 갖고 있는 컨테이너 클래스이다.&lt;br /&gt;
*View 기법은 org.springframework.web.servlet.View에 정의되어 있다.&lt;br /&gt;
*예를 들어 excel, Jasper Reports, pdf, xslt, Free Marker, Html, Tiles, velocity 등을 지원한다.&lt;br /&gt;
*Model과 View 객체를 다음과 같이 구현할 수 있다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
View pdfView = …;&lt;br /&gt;
Map modelData = new HashMap();&lt;br /&gt;
&lt;br /&gt;
ModelAndView mv = new ModelAndView(pdfView, modelData);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*다음 예제코드를 보자.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
ModelAndView mv = new ModelAndView(&amp;quot;jcfView&amp;quot;, someData);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*위 예제에서 someData가 jcfView에 전달된다. 여기서 view는 논리뷰이다.&lt;br /&gt;
*jcfView는 jcfView.jsp 또는 jcfView.pdf, jcfView.xml에 대응될 수 있다.&lt;br /&gt;
*논리뷰에 대응되는 물리뷰의 위치는 설정파일에서 정의된다.&lt;br /&gt;
&lt;br /&gt;
==ViewResolver 이해하여 적용하기==&lt;br /&gt;
*ViewResolver는 논리뷰와 물리뷰를 매핑한다.&lt;br /&gt;
*Spring MVC에서 지원하는 ViewResolver는 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. BeanNameViewResolver&lt;br /&gt;
2. FreeMarkerViewResolver&lt;br /&gt;
3. InternalResourceViewResolver&lt;br /&gt;
4. JasperReportsViewResolver&lt;br /&gt;
5. ResourceBundleViewResolver&lt;br /&gt;
6. UrlBasedViewResolver&lt;br /&gt;
7. VelocityLayoutViewResolver&lt;br /&gt;
8. VelocityViewResolver&lt;br /&gt;
9. XmlViewResolver&lt;br /&gt;
10. XsltViewResolver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*ViewResolver 구현 시 계층구조를 참고하여 용도에 맞는 ViewResolver를 선택해야 한다.&lt;br /&gt;
*다음은 ViewResolver Interface의 계층구조를 나타낸다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringMVC_ViewResolver.JPG|700px|thumb|center|ViewResolver Interface의 계층구조]]&lt;br /&gt;
&lt;br /&gt;
===InternalResourceViewResolver===&lt;br /&gt;
*InternalResourceViewResolver는 ModelAndView 폼에서 컨트롤러에 의해 리턴된 리소스의 논리적 이름을 Physical View Location에 매핑하려고 시도한다.&lt;br /&gt;
*단점은 뷰파일의 이름이 어플리케이션 컨텍스트 내에 명시되어야 한다는 것이다.&lt;br /&gt;
*따라서 동적으로 생성되는 뷰파일에 대한 처리는 불가능하다.&lt;br /&gt;
*다음 예제코드와 같이 구성된 Controller에서는 조건에 따라 서로 다른 ModelAndView 객체를 리턴한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class JcfController {&lt;br /&gt;
&lt;br /&gt;
    public void handle(){&lt;br /&gt;
        if(condition1()){&lt;br /&gt;
            return new ModelAndView(&amp;quot;jcfView1&amp;quot;);&lt;br /&gt;
        }else if (condition2()){&lt;br /&gt;
            return new ModelAndView(&amp;quot;jcfView2&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        return new ModelAndView(&amp;quot;jcfView3&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*만약 클라이언트의 Request가 condition1()을 만족한다면, View는 jcfView1.jsp 이고 condition2() 일 경우에는 jcfView2이다.&lt;br /&gt;
*이와 같은 동작이 정상적으로 이루어지기 위해서는 반드시 다음 설정파일 내용이 필요하다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;viewResolver&amp;quot; class=&amp;quot;org.springframework.web.servlet.view.InternalResourceViewResolver&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;prefix&amp;quot;&amp;gt;&amp;lt;value&amp;gt;/WEB-INF/&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;property name=&amp;quot;suffix&amp;quot;&amp;gt;&amp;lt;value&amp;gt;.jsp&amp;lt;/value&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*이것은 InternalResolverViewResolver가 논리뷰이름을 Physical Location에 매핑하는 방법을 보여준다.&lt;br /&gt;
*논리뷰이름이 jcfView1일 때, View 이름은 prefix + 논리뷰이름 + suffix이며, 여기서는 /WEB-INF/jcfView.jsp가 된다.&lt;br /&gt;
&lt;br /&gt;
===BeanNameViewResolver===&lt;br /&gt;
*InternalResourceViewResolver의 단점인 동적 뷰파일 처리의 문제점을 해결하기 위한 ViewResolver이다.&lt;br /&gt;
*BeanNameViewResolver는 Pdf 또는 엑셀 등의 View를 동적으로 생성할 수 있다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
return ModelAndView(&amp;quot;pdf&amp;quot;);&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*위와 같이 pdf를 생성해야 한는 ModelAndView인 경우 다음과 같은 설정파일을 정의한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;bean id=&amp;quot;beanNameResolver&amp;quot; class=&amp;quot;org.springframework.web.servlet.view.BeanNameViewResolver&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bean id=&amp;quot;pdf&amp;quot; class=&amp;quot;com.daewoobrenic.jcf.web.servlet.view.JcfPdfGenerator&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*이때 JcfPdfGenerator는 반드시 org.springframework.web.servlet.view.document.AbstractPdfView의 서브클래스이어야 한다.&lt;br /&gt;
&lt;br /&gt;
==View 구현하기==&lt;br /&gt;
*AbstractView 클래스를 상속받고 Abstract 메소드인 renderMergedOutputModel 메소드를 오버라이딩하여 클라이언트에게 제공하고자 하는 물리적인 뷰를 생성할 수 있도록 구현한다.&lt;br /&gt;
*View에서는 생성자나 XML 설정파일을 통해 View 클래스에 대한 초기값을 설정할 수 있다.&lt;br /&gt;
*Spring MVC에서 제공하는 View는 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringMVC_View.JPG|700px|thumb|center|View Interface의 계층구조]]&lt;br /&gt;
&lt;br /&gt;
==파일업로드 구현하기==&lt;br /&gt;
&lt;br /&gt;
=참고자료=&lt;br /&gt;
*[http://wiki.javajigi.net/display/SFL/Home 자바지기 Springframework 워크북]&lt;br /&gt;
*[http://static.springframework.org/spring/docs/2.5.x/reference/index.html SpringFramework Reference Manual]&lt;/div&gt;</description>
			<pubDate>Mon, 07 Jul 2008 07:30:27 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Spring_MVC_ControllerWorkFlow</comments>		</item>
		<item>
			<title>Code Module</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Code_Module</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=코드 테이블 생성=&lt;br /&gt;
* 코드의 아이디와 값 그리고 분류 카테고리를 가지는 간단한 코드 테이블을 생성한다.&lt;br /&gt;
* HSQLDB 기준으로 생성함(오라클의 경우 int --&amp;gt; NUMBER로, VARCHAR는 VARCHAR2로 변경해 준다.)&lt;br /&gt;
&amp;lt;code lang='sql'&amp;gt;&lt;br /&gt;
CREATE TABLE CODE(&lt;br /&gt;
	id 		int,&lt;br /&gt;
	name		varchar(20),&lt;br /&gt;
	description varchar(50),&lt;br /&gt;
	category	varchar(20),&lt;br /&gt;
	CONSTRAINT code_pk PRIMARY KEY(id)&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
INSERT INTO CODE(id, name, description, category) VALUES(1, 'SEOUL', '서울','user_address_code');&lt;br /&gt;
INSERT INTO CODE(id, name, description, category) VALUES(2, 'INCHEN', '인천','user_address_code');&lt;br /&gt;
INSERT INTO CODE(id, name, description, category) VALUES(3, 'PUSAN', '부산','user_address_code');&lt;br /&gt;
INSERT INTO CODE(id, name, description, category) VALUES(4, 'ULSAN', '울산','user_address_code');&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=MODEL 작성=&lt;br /&gt;
&amp;lt;code lagn='java'&amp;gt;&lt;br /&gt;
public class Code {&lt;br /&gt;
	private int id;&lt;br /&gt;
	private String category;&lt;br /&gt;
	private String name;&lt;br /&gt;
	private String description;&lt;br /&gt;
	&lt;br /&gt;
	public int getId() {return id;}&lt;br /&gt;
	public void setId(int id) {this.id = id;}&lt;br /&gt;
	public String getCategory() {return category;}&lt;br /&gt;
	public void setCategory(String category) {this.category = category;}&lt;br /&gt;
	public String getName() {return name;}&lt;br /&gt;
	public void setName(String name) {this.name = name;}&lt;br /&gt;
	public String getDescription() {return description;}&lt;br /&gt;
	public void setDescription(String description) {this.description = description;}	&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=SQL 작성=&lt;br /&gt;
* getCodes 문장만 작성한다.&lt;br /&gt;
* resultMap은 선택적으로 사용한다.&lt;br /&gt;
&amp;lt;code lang='xml'&amp;gt;&lt;br /&gt;
&amp;lt;sqlMap namespace=&amp;quot;code&amp;quot;&amp;gt;			&lt;br /&gt;
	&amp;lt;typeAlias alias=&amp;quot;code&amp;quot; type=&amp;quot;edu.code.model.Code&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;resultMap id=&amp;quot;code-resultMap&amp;quot; class=&amp;quot;code&amp;quot; &amp;gt;&lt;br /&gt;
		&amp;lt;result property=&amp;quot;id&amp;quot; column=&amp;quot;id&amp;quot;/&amp;gt;&lt;br /&gt;
		&amp;lt;result property=&amp;quot;category&amp;quot; column=&amp;quot;category&amp;quot;/&amp;gt;&lt;br /&gt;
    		&amp;lt;result property=&amp;quot;name&amp;quot; column=&amp;quot;name&amp;quot;/&amp;gt;&lt;br /&gt;
		&amp;lt;result property=&amp;quot;description&amp;quot; column=&amp;quot;description&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;/resultMap&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;statement id=&amp;quot;getCodes&amp;quot; parameterClass=&amp;quot;string&amp;quot; resultMap=&amp;quot;code-resultMap&amp;quot;&amp;gt;&lt;br /&gt;
		SELECT id, category, name, description&lt;br /&gt;
		FROM CODE&lt;br /&gt;
		WHERE category = #category#&lt;br /&gt;
	&amp;lt;/statement&amp;gt;&lt;br /&gt;
&amp;lt;/sqlMap&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* SQL CONFIG XML(sqlmap-config.xml) 파일에 정의를 추가한다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;sqlMapConfig&amp;gt;&lt;br /&gt;
	&amp;lt;settings cacheModelsEnabled=&amp;quot;true&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;sqlMap resource=&amp;quot;sample/user/dao/sqlmap/User.xml&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;sqlMap resource=&amp;quot;edu/code/dao/sqlmap/Code.xml&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/sqlMapConfig&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=DAO 작성=&lt;br /&gt;
* 카테고리를 파라미터로 받는 조회 메소드를 작성한다.&lt;br /&gt;
* jcf.dao.ibatis.BaseSqlMapClientDAO를 상속 받도록 한다.&lt;br /&gt;
&amp;lt;code lang='java'&amp;gt;&lt;br /&gt;
public class CodeDao extends BaseSqlMapClientDAO {&lt;br /&gt;
	public List getCodes(String category) {&lt;br /&gt;
		List codeList = executeQueryForList(&amp;quot;getCodes&amp;quot;, category);&lt;br /&gt;
		return codeList;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 작성된 CodeDao 클래스를 Spring 빈으로 정의한다(applicationContext-code.xml)&lt;br /&gt;
* CodeDao 클래스 정의에서는 상속 받은 BaseSqlMapClientDAO에서 필요로 하는 sqlMapClient를 프라퍼티로 가지도록 정의한다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;beans ..&amp;gt;&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;codeDao&amp;quot; class=&amp;quot;edu.code.dao.CodeDao&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;sqlMapClient&amp;quot; ref=&amp;quot;sqlMapClient&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= SERVICE 작성=&lt;br /&gt;
* 카테고리를 파라미터로 받는 서비스 조회 메소드를 작성한다.&lt;br /&gt;
* CodeDao를 프라퍼티로 선언하고 setter 메소드를 작성한다.&lt;br /&gt;
&amp;lt;code lang='java'&amp;gt;&lt;br /&gt;
public class CodeService {&lt;br /&gt;
	private CodeDao codeDao;&lt;br /&gt;
	&lt;br /&gt;
	public List getCodes(String category) {&lt;br /&gt;
		return codeDao.getCodes(category); &lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	/* getter &amp;amp; setter */&lt;br /&gt;
	public void setCodeDao(CodeDao codeDao) {this.codeDao = codeDao;}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 작성된 코드DAO 클래스를 Spring 빈으로 정의한다(applicationContext-code.xml)&lt;br /&gt;
* 로직상에서 호출하는 CodeDao를 DI 프라퍼티로 정의한다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;beans ..&amp;gt;&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;codeService&amp;quot; class=&amp;quot;edu.code.service.CodeService&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;codeDao&amp;quot; ref=&amp;quot;codeDao&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
	&amp;lt;bean id=&amp;quot;codeDao&amp;quot; class=&amp;quot;edu.code.dao.CodeDao&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;property name=&amp;quot;sqlMapClient&amp;quot; ref=&amp;quot;sqlMapClient&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</description>
			<pubDate>Thu, 03 Jul 2008 06:15:51 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Code_Module</comments>		</item>
		<item>
			<title>Jdk14 Conversion</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Jdk14_Conversion</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* Retrotranslator 1.2.7를 활용하겨 java1.4로 변환하기 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물: JCF 라이브러리 및 공통모듈 jdk1.4로 다운그레이드하기&lt;br /&gt;
*작성자: 서경진&lt;br /&gt;
*최초작성일 : 2008/07/03&lt;br /&gt;
*최종작성일 : 2008/07/03&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
*이 문서는 Java 1.4환경에서 JCF Framework와 공통모듈을 사용하기 위한 Tip을 제공한다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==JCF 라이브러리 jdk1.4로 다운그레이드하기==&lt;br /&gt;
JCF는 Java1.5를 기반으로 개발되었지만, MCI (Multi-Channel Interface)의 jcf.web.RequestContextHolder 클래스에서 사용하는 java.lang.ThreadLocal.remove() (rt.jar) 함수가 1.5 이상에서만 지원되는 것을 제외하면 java 1.4 환경에서의 구동이 가능하다.&lt;br /&gt;
java1.4 환경에서 안정적으로 JCF를 기반으로 어플리케이션을 개발하기 위해서는 소스의 수정없이 Retrotranslator를 활용하여 java1.5로 컴파일된 JCF 라이브러리를 java1.4로 변환하면 된다.&lt;br /&gt;
&lt;br /&gt;
===Retrotranslator 1.2.7를 활용하여 java1.4로 변환하기===&lt;br /&gt;
*Retrotranslator 다운받기: http://sourceforge.net/projects/retrotranslator&lt;br /&gt;
*JCF 라이브러리 다운받기: http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/JCF_Download&lt;br /&gt;
&lt;br /&gt;
*Retrotranslator와 JCF 라이브러리를 다운받아 아래와 같이 같은 디렉터리에 복사한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:Retrotranslator_jdk14_conversion.JPG|700px|thumb|center|디렉터리 구조]]&lt;br /&gt;
&lt;br /&gt;
*DOS Command를 통해 다음과 같은 명령을 실행한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
java -jar retrotranslator-transformer-1.2.7.jar -advanced -srcjar jcf-3.0.1-SNAPSHOT.jar -destjar jcf-3.0.1-SNAPSHOT-jdk14.jar&lt;br /&gt;
java -jar retrotranslator-transformer-1.2.7.jar -advanced -srcjar jcf-ibatis-sqlmap-3.0.1-SNAPSHOT.jar -destjar jcf-ibatis-sqlmap-3.0.1-SNAPSHOT-jdk14.jar&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*다음은 JCF 라이브러리가 Retrotranslator를 통해 java1.4용으로 변환된 결과이다.&lt;br /&gt;
&lt;br /&gt;
[[그림:Retrotranslator_jdk14_conversion_command.JPG|800px|thumb|center|변환 명령실행 결과]]&lt;br /&gt;
&lt;br /&gt;
*위의 과정을 통해 동일 디렉터리에 jcf-3.0.1-SNAPSHOT-jdk14.jar와 jcf-ibatis-sqlmap-3.0.1-SNAPSHOT-jdk14.jar 두 개의 라이브러리가 생성된다.&lt;br /&gt;
*java1.4 환경에서 JCF 기반의 어플리케이션을 개발할 경우, 기존에 있는 java1.5용 JCF 라이브러리를 제거하고 생성된 두 개의 라이브러리를 buildpath에 설정하여 java1.4로 컴파일하면 어플리케이션이 정상적으로 구동할 것이다.&lt;br /&gt;
&lt;br /&gt;
==JCF 공통모듈 jdk1.4로 다운그레이드하기==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===JCF 공통모듈의 메뉴관리가 참조하는 Tree.jar 라이브러리 다운그레이드하기===&lt;br /&gt;
*JCF 공통모듈에는 메뉴관리 모듈이 있는데, 메뉴관리는 Tree형 데이터 구조를 활용하기 위해 sourceforge에 공시된 Tree.jar라는 open source 라이브러리를 활용한다.&lt;br /&gt;
*Tree.jar는 다음 소스와 같이 java1.5 스팩인 jre1.5 이상에 포함된 rt.jar의 java.lang.Iterable과 GenericType &amp;lt;&amp;gt;을 사용한다.&lt;br /&gt;
*따라서 java1.4 환경에서는 구동이 불가능하다. (클래스를 찾을 수 없는 에러 발생)&lt;br /&gt;
*다음은 java1.5로 구현된 소스의 예제이다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public interface Tree&amp;lt;T&amp;gt; extends Iterable&amp;lt;T&amp;gt;, Serializable&lt;br /&gt;
{&lt;br /&gt;
	public abstract TreeRoot&amp;lt;T&amp;gt; getRoot();&lt;br /&gt;
	public abstract Iterator&amp;lt;T&amp;gt; iterator();&lt;br /&gt;
	public abstract Iterator&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; nodeIterator();&lt;br /&gt;
	public abstract List&amp;lt;T&amp;gt; getBreadthFirstList();&lt;br /&gt;
	public abstract List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; getBreadthFirstNodeList();&lt;br /&gt;
	public abstract List&amp;lt;T&amp;gt; getDepthFirstList();&lt;br /&gt;
	public abstract List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; getDepthFirstNodeList();&lt;br /&gt;
	public abstract List&amp;lt;T&amp;gt; getList();&lt;br /&gt;
	public abstract List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; getNodeList();&lt;br /&gt;
	public abstract int size();&lt;br /&gt;
	public abstract int depth();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ArrayTree&amp;lt;T&amp;gt; implements Tree&amp;lt;T&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	private static final long serialVersionUID = 7161315168915445688L;&lt;br /&gt;
	private TreeRoot&amp;lt;T&amp;gt; root;&lt;br /&gt;
	private final List&amp;lt;List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt;&amp;gt; levels = new ArrayList&amp;lt;List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt;&amp;gt;();&lt;br /&gt;
	&lt;br /&gt;
	public ArrayTree()&lt;br /&gt;
	{&lt;br /&gt;
		this(null);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public ArrayTree(final T element)&lt;br /&gt;
	{&lt;br /&gt;
		super();&lt;br /&gt;
		this.root = new ArrayTreeRoot&amp;lt;T&amp;gt;(this);&lt;br /&gt;
		this.root.setElement(element);&lt;br /&gt;
		this.saveNode(this.root, 0);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private void addLevel(final TreeNode&amp;lt;T&amp;gt; node) {&lt;br /&gt;
		List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; level = new ArrayList&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt;();&lt;br /&gt;
		level.add(node);&lt;br /&gt;
		this.levels.add(level);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	protected void saveNode(final TreeNode&amp;lt;T&amp;gt; node, final int depth) {&lt;br /&gt;
		if (depth &amp;gt;= this.levels.size()) {&lt;br /&gt;
			this.addLevel(node);&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			this.levels.get(depth).add(node);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	protected void removeNode(final TreeNode&amp;lt;T&amp;gt; node, final int depth) {&lt;br /&gt;
		if (depth &amp;lt; this.levels.size()) {&lt;br /&gt;
			this.levels.get(depth).remove(node);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	protected List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; getNodes(final int depth) {&lt;br /&gt;
		if (depth &amp;lt; this.levels.size()) {&lt;br /&gt;
			return this.levels.get(depth);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		return null;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public TreeRoot&amp;lt;T&amp;gt; getRoot()&lt;br /&gt;
	{&lt;br /&gt;
		return this.root;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public Iterator&amp;lt;T&amp;gt; iterator()&lt;br /&gt;
	{&lt;br /&gt;
		return this.getDepthFirstList().iterator();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public Iterator&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; nodeIterator()&lt;br /&gt;
	{&lt;br /&gt;
		return this.getBreadthFirstNodeList().iterator();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List&amp;lt;T&amp;gt; getBreadthFirstList()&lt;br /&gt;
	{&lt;br /&gt;
		final List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; nodes = this.getBreadthFirstNodeList();&lt;br /&gt;
		final List&amp;lt;T&amp;gt; elements = new ArrayList&amp;lt;T&amp;gt;(nodes.size());&lt;br /&gt;
		for (final TreeNode&amp;lt;T&amp;gt; node : nodes)&lt;br /&gt;
		{&lt;br /&gt;
			elements.add(node.getElement());&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		return Collections.unmodifiableList(elements);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; getBreadthFirstNodeList()&lt;br /&gt;
	{&lt;br /&gt;
		final List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; nodes = new LinkedList&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt;();&lt;br /&gt;
		for (List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; level : this.levels) {&lt;br /&gt;
			nodes.addAll(level);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		return Collections.unmodifiableList(nodes);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List&amp;lt;T&amp;gt; getDepthFirstList()&lt;br /&gt;
	{&lt;br /&gt;
		final List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; nodes = this.getDepthFirstNodeList();&lt;br /&gt;
		final List&amp;lt;T&amp;gt; elements = new ArrayList&amp;lt;T&amp;gt;(nodes.size());&lt;br /&gt;
		for (final TreeNode&amp;lt;T&amp;gt; node : nodes)&lt;br /&gt;
		{&lt;br /&gt;
			elements.add(node.getElement());&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		return Collections.unmodifiableList(elements);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; getDepthFirstNodeList()&lt;br /&gt;
	{&lt;br /&gt;
		final List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; nodes = new LinkedList&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt;();&lt;br /&gt;
		this.addDepthFirst(nodes, this.root);&lt;br /&gt;
		&lt;br /&gt;
		return Collections.unmodifiableList(nodes);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private void addDepthFirst(final List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; nodes, final TreeNode&amp;lt;T&amp;gt; node)&lt;br /&gt;
	{&lt;br /&gt;
		nodes.add(node);&lt;br /&gt;
		for (final TreeNode&amp;lt;T&amp;gt; child : node.getChildren())&lt;br /&gt;
		{&lt;br /&gt;
			this.addDepthFirst(nodes, child);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public int depth()&lt;br /&gt;
	{&lt;br /&gt;
		return this.levels.size() - 1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public int size()&lt;br /&gt;
	{&lt;br /&gt;
		int size = 0;&lt;br /&gt;
		for (List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; level : this.levels) {&lt;br /&gt;
			size += level.size();&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		return size;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List&amp;lt;T&amp;gt; getList()&lt;br /&gt;
	{&lt;br /&gt;
		return this.getBreadthFirstList();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List&amp;lt;TreeNode&amp;lt;T&amp;gt;&amp;gt; getNodeList()&lt;br /&gt;
	{&lt;br /&gt;
		return this.getBreadthFirstNodeList();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Tree.jar를 java1.4 환경에서 활용하기 위해서 소스코드를 java1.4 스팩에 맞도록 수정하였다.&lt;br /&gt;
*Iterable 클래스와 GenericType &amp;lt;&amp;gt;은 사용하지 않도록 모두 제거하였고 T와 같이 Type이 선언된 부분은 Object로 변경하였다.&lt;br /&gt;
*java1.5용 for문을 java1.4에 맞도록 수정하였다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
interface Tree extends Serializable&lt;br /&gt;
{&lt;br /&gt;
	public abstract TreeRoot getRoot();&lt;br /&gt;
	public abstract Iterator iterator();&lt;br /&gt;
	public abstract Iterator nodeIterator();&lt;br /&gt;
	public abstract List getBreadthFirstList();&lt;br /&gt;
	public abstract List getBreadthFirstNodeList();&lt;br /&gt;
	public abstract List getDepthFirstList();&lt;br /&gt;
	public abstract List getDepthFirstNodeList();&lt;br /&gt;
	public abstract List getList();&lt;br /&gt;
	public abstract List getNodeList();&lt;br /&gt;
	public abstract int size();&lt;br /&gt;
	public abstract int depth();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class ArrayTree implements Tree&lt;br /&gt;
{&lt;br /&gt;
	private static final long serialVersionUID = 7161315168915445688L;&lt;br /&gt;
	private TreeRoot root;&lt;br /&gt;
	private final List levels = new ArrayList();&lt;br /&gt;
&lt;br /&gt;
	public ArrayTree()&lt;br /&gt;
	{&lt;br /&gt;
		this(null);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public ArrayTree(final Object element)&lt;br /&gt;
	{&lt;br /&gt;
		super();&lt;br /&gt;
		this.root = new ArrayTreeRoot(this);&lt;br /&gt;
		this.root.setElement(element);&lt;br /&gt;
		this.saveNode(this.root, 0);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private void addLevel(final TreeNode node) {&lt;br /&gt;
		List level = new ArrayList();&lt;br /&gt;
		level.add(node);&lt;br /&gt;
		this.levels.add(level);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	protected void saveNode(final TreeNode node, final int depth) {&lt;br /&gt;
		if (depth &amp;gt;= this.levels.size()) {&lt;br /&gt;
			this.addLevel(node);&lt;br /&gt;
		}&lt;br /&gt;
		else {&lt;br /&gt;
			((ArrayList) this.levels.get(depth)).add(node);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	protected void removeNode(final TreeNode node, final int depth) {&lt;br /&gt;
		if (depth &amp;lt; this.levels.size()) {&lt;br /&gt;
			((ArrayList) this.levels.get(depth)).remove(node);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	protected List getNodes(final int depth) {&lt;br /&gt;
		if (depth &amp;lt; this.levels.size()) {&lt;br /&gt;
			return (List) this.levels.get(depth);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return null;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public TreeRoot getRoot()&lt;br /&gt;
	{&lt;br /&gt;
		return this.root;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public Iterator iterator()&lt;br /&gt;
	{&lt;br /&gt;
		return this.getDepthFirstList().iterator();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public Iterator nodeIterator()&lt;br /&gt;
	{&lt;br /&gt;
		return this.getBreadthFirstNodeList().iterator();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List getBreadthFirstList()&lt;br /&gt;
	{&lt;br /&gt;
		final List nodes = this.getBreadthFirstNodeList();&lt;br /&gt;
		final List elements = new ArrayList(nodes.size());&lt;br /&gt;
		for (Iterator iterator = nodes.iterator(); iterator.hasNext();) {&lt;br /&gt;
			TreeNode node = (TreeNode) iterator.next();&lt;br /&gt;
			elements.add(node.getElement());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return Collections.unmodifiableList(elements);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List getBreadthFirstNodeList()&lt;br /&gt;
	{&lt;br /&gt;
		final List nodes = new LinkedList();&lt;br /&gt;
		for (Iterator iterator = this.levels.iterator(); iterator.hasNext();) {&lt;br /&gt;
			List level = (List) iterator.next();&lt;br /&gt;
			nodes.addAll(level);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return Collections.unmodifiableList(nodes);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List getDepthFirstList()&lt;br /&gt;
	{&lt;br /&gt;
		final List nodes = this.getDepthFirstNodeList();&lt;br /&gt;
		final List elements = new ArrayList(nodes.size());&lt;br /&gt;
		for (Iterator iterator = nodes.iterator(); iterator.hasNext();) {&lt;br /&gt;
			TreeNode node = (TreeNode) iterator.next();&lt;br /&gt;
			elements.add(node.getElement());&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return Collections.unmodifiableList(elements);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List getDepthFirstNodeList()&lt;br /&gt;
	{&lt;br /&gt;
		final List nodes = new LinkedList();&lt;br /&gt;
		this.addDepthFirst(nodes, this.root);&lt;br /&gt;
&lt;br /&gt;
		return Collections.unmodifiableList(nodes);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private void addDepthFirst(final List nodes, final TreeNode node)&lt;br /&gt;
	{&lt;br /&gt;
		nodes.add(node);&lt;br /&gt;
		for (Iterator iterator = node.getChildren().iterator(); iterator.hasNext();) {&lt;br /&gt;
			TreeNode child = (TreeNode) iterator.next();&lt;br /&gt;
			this.addDepthFirst(nodes, child);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public int depth()&lt;br /&gt;
	{&lt;br /&gt;
		return this.levels.size() - 1;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public int size()&lt;br /&gt;
	{&lt;br /&gt;
		int size = 0;&lt;br /&gt;
		for (Iterator iterator = this.levels.iterator(); iterator.hasNext();) {&lt;br /&gt;
			List level = (List) iterator.next();&lt;br /&gt;
			size += level.size();&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return size;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List getList()&lt;br /&gt;
	{&lt;br /&gt;
		return this.getBreadthFirstList();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public List getNodeList()&lt;br /&gt;
	{&lt;br /&gt;
		return this.getBreadthFirstNodeList();&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*소스 수정이 끝나고 j2sdk1.4.2_17과 jre1.4.2_17로 컴파일을 한 후, Tree-1.0-jdk14.jar로 패키징하였다.&lt;br /&gt;
*패키징된 Tree-1.0-jdk14.jar 라이브러리는 Maven 저장소에 Artifact로 디플로이하여 Maven을 통한 활용이 가능하다.&lt;br /&gt;
&lt;br /&gt;
[[그림:Maven_repository_tree_jar_jdk14.JPG|700px|thumb|center|Maven 저장소에 Artifact로 디플로이된 Tree-1.0-jdk14.jar 라이브러리]]&lt;br /&gt;
&lt;br /&gt;
*Tree-1.0-jdk14.jar를 Maven에서 적용하기 위한 pom.xml&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
------ ARTIFACT EFFECTIVE METADATA BEGIN ------&lt;br /&gt;
&amp;lt;groupId&amp;gt;Tree&amp;lt;/groupId&amp;gt;&lt;br /&gt;
&amp;lt;artifactId&amp;gt;Tree&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
&amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;
------- ARTIFACT EFFECTIVE METADATA END -------&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&amp;lt;project&amp;gt;&lt;br /&gt;
  &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt;
  &amp;lt;groupId&amp;gt;Tree&amp;lt;/groupId&amp;gt;&lt;br /&gt;
  &amp;lt;artifactId&amp;gt;Tree&amp;lt;/artifactId&amp;gt;&lt;br /&gt;
  &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;
  &amp;lt;description&amp;gt;Auto generated POM&amp;lt;/description&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===메뉴관리 모듈 다운그레이드하기===&lt;br /&gt;
*Java 개발환경을 jdk 및 jre를 1.4.2._17로 변경한다.&lt;br /&gt;
*buildpath에 있는 Tree.jar를 Tree-1.0-jdk14.jar로 변경한다.&lt;br /&gt;
*메뉴모듈에 적용된 GenericType &amp;lt;&amp;gt;은 사용하지 않도록 모두 제거한다.&lt;br /&gt;
*GenericType으로 설정된 부분은 Casting(Type명)으로 형변환 에러를 방지한다.&lt;br /&gt;
*java1.5용 for문을 java1.4에서 사용할 수 있도록 수정한다.&lt;br /&gt;
*Java1.4로 컴파일한다.&lt;/div&gt;</description>
			<pubDate>Thu, 03 Jul 2008 00:59:48 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Jdk14_Conversion</comments>		</item>
		<item>
			<title>Spring MVC &amp; Java1.4 tip</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_MVC_%26_Java1.4_tip</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 설정파일의 간략화 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물:   Java 1.4에서 Spring MVC 간단하게 사용하기&lt;br /&gt;
*작성자:   나윤주&lt;br /&gt;
*최초작성일 : 2008/07/01&lt;br /&gt;
*최종작성일 : 2008/07/02&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
*이 문서는 Java 1.4환경에서 Spring Web MVC Framework를 간단하게 사용할 수 있는 Tip을 제공한다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==설정파일의 간략화==&lt;br /&gt;
*Arid와 ControllerClassNameHandlerMapping의 조합으로 Annotation을 사용할 수 없는 Java 1.4 환경에서 번거로울 수 있는 web controller의 설정을 줄이고, Controller 클래스의 수를 줄임으로써 개발의 편이성을 높일 수 있다.&lt;br /&gt;
*다음은 블로그 예제에 대하여 Java 1.4에서 SpringMVC를 사용하였을 때, arid와 coc를 적용하였을 때, Jave 5.0+에서 annotation을 사용하였을 때를 비교한 것이다.&lt;br /&gt;
&amp;lt;table border='1' align='center' width='700' cellspacing='0'&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align='center'&amp;gt;'''코드'''&amp;lt;/td&amp;gt;&amp;lt;td align='center'&amp;gt;'''Blog(Original)'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td align='center'&amp;gt;'''Blog(arid+coc)'''&amp;lt;/td&amp;gt;&amp;lt;td align='center'&amp;gt;'''Blog(java5.0+ annotation)'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td rowspan='2' align='center'&amp;gt;'''blog-servlet.xml'''&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;View Resolver bean 등록,&amp;lt;br&amp;gt;각 Controller-url 맵핑 bean 등록&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;Arid, mapping handler bean,&amp;lt;br&amp;gt;view name translator bean 등록&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;component scan,&amp;lt;br&amp;gt;view resolver bean 등록&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td align='center'&amp;gt;약 30 lines&amp;lt;/td&amp;gt;&amp;lt;td align='center'&amp;gt;약 20 lines&amp;lt;/td&amp;gt;&amp;lt;td align='center'&amp;gt;약 15 lines&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td rowspan='3' align='center'&amp;gt;'''Controller'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;blog.web.CreateBlogFormController,&amp;lt;br&amp;gt;blog.web.EditBlogFormController,&amp;lt;br&amp;gt;blog.web.FindBlogController&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;blog.web.BlogController&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;blog.web.BlogController&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;MultiActionController,&amp;lt;br&amp;gt;SimpleFormController 상속&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;td&amp;gt;MultiActionController 상속&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;@Controller 지정&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
{{경고|&lt;br /&gt;
*위 표는 Spring MVC를 이용하여 개발한 블로그의 예제에서 각 경우에 따라 설정파일 및 controller 파일을 최소화 하였을 때를 나타낸 것으로, 프로젝트 구조 및 성격에 따라 내용이 달라질 수 있다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Arid===&lt;br /&gt;
*&amp;lt;arid:define-bean /&amp;gt;&lt;br /&gt;
**클래스 및 클래스의 멤버변수를 bean으로 등록해주는 역할을 한다.&lt;br /&gt;
*arid 사용하기&lt;br /&gt;
**arid-framework.jar와 aspectjweaver.jar 클래스 파일이 필요하다.&lt;br /&gt;
**beans 정의에 arid를 추가해야 한다.&lt;br /&gt;
**web controller는 xxx-servlet.xml에서 설정한다.&lt;br /&gt;
**controller 클래스 멤버변수의 set 메소드의 작성이 필요하다.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
'''@Autowired == &amp;lt;arid:define-bean /&amp;gt; + setXXX()'''&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns:arid=&amp;quot;http://chrisrichardson.net/schema/arid&amp;quot;&lt;br /&gt;
    xsi:schemaLocation=&amp;quot;http://chrisrichardson.net/schema/arid http://chrisrichardson.net/schema/arid.xsd&amp;quot; &amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!-- auto registration and wiring of beans  --&amp;gt;&lt;br /&gt;
    &amp;lt;arid:define-beans package=&amp;quot;edu.blog&amp;quot; pattern=&amp;quot;*..web.*Controller&amp;quot; autowire=&amp;quot;byName&amp;quot;/&amp;gt; &lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*한계&lt;br /&gt;
**Spring MVC annotation 중 @Autowired를 커버할 수 있지만, Controller, RequestMapping 등의 다른 annotation을 대체할 순 없다.&lt;br /&gt;
{{정보|&lt;br /&gt;
*(참고) [[에리드(ARID)|Arid]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===ControllerClassNameHandlerMapping===&lt;br /&gt;
*url과 클래스 맵핑의 관계를 자동으로 지정해주는 Handler Mapper이다.&lt;br /&gt;
*Conversion of Configuration(CoC)의 개념이다.&lt;br /&gt;
*ControllerClassNameHandlerMapping을 적용하지 않은 경우 Controller class에 대한 url을 직접 지정해주어야 한다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;bean name=&amp;quot;/findBlogs.do&amp;quot; class=&amp;quot;blog.web.FindBlogController&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;blogService&amp;quot; ref=&amp;quot;blogService&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*ControllerClassNameHandlerMapping을 적용한 경우 Controller class의 이름이 url로 자동 매핑된다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;bean class=&amp;quot;blog.web.FindBlogController&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;property name=&amp;quot;blogService&amp;quot; ref=&amp;quot;blogService&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*한계&lt;br /&gt;
**ControllerClassNameHandlerMapping을 사용하더라도, 각 controller 파일에 대해 bean 등록을 직접 해주어야 한다.&lt;br /&gt;
**클래스 및 메소드의 이름이 url로 사용되므로, 클래스 및 메소드 이름 결정에 주의해야 한다.&lt;br /&gt;
**Controller의 종류에 따라 url 매핑의 형태가 다르므로, jsp 소스 코드 관리에 주의해야 한다.&lt;br /&gt;
***MultiActionController의 경우 '''''/클래스이름/메소드이름.확장자'''''로 매핑되며, 다른 Controller의 경우 '''''/클래스이름.확장자'''''로 매핑된다.&lt;br /&gt;
&lt;br /&gt;
==Arid + ControllerClassNameHandlerMapping==&lt;br /&gt;
*Arid의 자동 bean 등록과 ControllerClassNameHandlerMapping의 url 자동 매핑의 기능을 사용하여 설정파일을 간략하게 사용할 수 있다.&lt;br /&gt;
*Web Controller는 MultiActionController를 상속받아 사용함으로써 Controller 클래스의 수를 줄일 수 있다.&lt;br /&gt;
===servlet 설정===&lt;br /&gt;
*Arid와 ControllerClassNameHandlerMapping의 설정 만으로 기존의 url-controller class 설정을 모두 생략할 수 있다.&lt;br /&gt;
*InternalResourceViewResolver는 Controller에서 ModelAndView 타입이 아닌 ModelMap 타입으로 반환하더라도 알맞은 View를 선택하여 보여주도록 해준다.&lt;br /&gt;
**stripLeadingSlash 속성은 false로 설정을 해야 requestContext 이후의 정확한 url 매핑이 이루어진다. (stripLeadingSlash의 default value는 true이다.)&lt;br /&gt;
**InternalResourceViewResolver를 사용할 경우 suffix를 지정하기 위해 사용한 InternalResourceViewResolver를 중복으로 사용하지 않아도 된다. (단, 특정 viewClass를 지정하거나 InternalResourceViewResolver에서 필요한 속성을 설정하기 위해서는 지정해준다.)&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- blog-servlet.xml --&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
    xmlns:jee=&amp;quot;http://www.springframework.org/schema/jee&amp;quot; xmlns:tx=&amp;quot;http://www.springframework.org/schema/tx&amp;quot;&lt;br /&gt;
    xmlns:aop=&amp;quot;http://www.springframework.org/schema/aop&amp;quot; xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
    xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot; &lt;br /&gt;
    xmlns:arid=&amp;quot;http://chrisrichardson.net/schema/arid&amp;quot;&lt;br /&gt;
    xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd&lt;br /&gt;
	         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd&lt;br /&gt;
	         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd&lt;br /&gt;
	         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd&lt;br /&gt;
	         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd&lt;br /&gt;
	         http://chrisrichardson.net/schema/arid http://chrisrichardson.net/schema/arid.xsd&amp;quot; &amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!-- auto registration and wiring of beans  --&amp;gt;&lt;br /&gt;
    &amp;lt;arid:define-beans package=&amp;quot;edu.blog&amp;quot; pattern=&amp;quot;*..web.*Controller&amp;quot; autowire=&amp;quot;byName&amp;quot;/&amp;gt; &lt;br /&gt;
    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping&amp;quot;/&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
    &amp;lt;bean id=&amp;quot;viewNameTranslator&amp;quot; class=&amp;quot;org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator&amp;quot;&amp;gt;&lt;br /&gt;
    	&amp;lt;property name=&amp;quot;stripLeadingSlash&amp;quot; value=&amp;quot;false&amp;quot;/&amp;gt;&lt;br /&gt;
    	&amp;lt;property name=&amp;quot;suffix&amp;quot; value=&amp;quot;.jsp&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;  &lt;br /&gt;
	&lt;br /&gt;
    &amp;lt;!-- view &amp;amp; resolver &lt;br /&gt;
    &amp;lt;bean id=&amp;quot;viewResolver&amp;quot; class=&amp;quot;org.springframework.web.servlet.view.InternalResourceViewResolver&amp;quot;&amp;gt;&lt;br /&gt;
    	&amp;lt;property name=&amp;quot;suffix&amp;quot; value=&amp;quot;.jsp&amp;quot;/&amp;gt;&lt;br /&gt;
    	&amp;lt;property name=&amp;quot;viewClass&amp;quot; value=&amp;quot;org.springframework.web.servlet.view.JstlView&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
    --&amp;gt;&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Web Controller===&lt;br /&gt;
*하나의 controller에서 처리하기 위해 MultiActionController를 사용하고, 메소드 형태의 혼란을 줄이기 위해 같은 형태의 메소드를 사용하였다.&lt;br /&gt;
*다른 레이어와 연계가 필요한 멤버변수(blogService)는 setXxx 함수로 설정을 해준다.&lt;br /&gt;
*서블릿에서 InternalResourceViewResolver를 사용하지 않을 경우, 반환형을 ModelAndView로 하여 view 이름을 지정해주어야 한다.&lt;br /&gt;
*deleteBlog()와 같이 직접 view로 반환하지 않는 메소드는 return type이 Map/ModelAndView형태가 아니어도 된다.&lt;br /&gt;
**redirect/forword 키워드로 알맞은 url로 변환해준다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* BlogController.java */&lt;br /&gt;
/* 패키지 선언 및 import 생략 */&lt;br /&gt;
public class BlogController extends MultiActionController {&lt;br /&gt;
	private BlogService blogService;&lt;br /&gt;
&lt;br /&gt;
	public void setBlogService(BlogService blogService) {&lt;br /&gt;
		this.blogService = blogService;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public Map findBlogs(HttpServletRequest request,&lt;br /&gt;
			HttpServletResponse response) throws Exception {&lt;br /&gt;
		Collection blogList = blogService.findBlogs();&lt;br /&gt;
		return new ModelMap(&amp;quot;blogList&amp;quot;, blogList);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public String deleteBlog(HttpServletRequest request,&lt;br /&gt;
			HttpServletResponse response) throws Exception {&lt;br /&gt;
		blogService.deleteBlog(Integer.parseInt((String)request.getParameter(&amp;quot;blogId&amp;quot;)));	&lt;br /&gt;
		return &amp;quot;redirect:findBlogs.do&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*get 형태의 파라미터는 request.getParameter()로, post 형태의 form 관련 파라미터는 bind() 함수로 설정할 수 있다.&lt;br /&gt;
*SessionAttributes Annotation과 같이 하나의 blog 모델을 유지할 수 없기 때문에, View에서는 Controller에서 넘겨준 모델의 모든 정보를 다시 설정하여 보내주도록 해야한다. (blog 예제 소스 참고)&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
	public Map createBlog(HttpServletRequest request, &lt;br /&gt;
			HttpServletResponse response) throws Exception {&lt;br /&gt;
		Blog blog = new Blog();&lt;br /&gt;
		blog.setRegDate(new Date());&lt;br /&gt;
		return new ModelMap(&amp;quot;blog&amp;quot;, blog);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public String addBlog(HttpServletRequest request, &lt;br /&gt;
			HttpServletResponse response) throws Exception {&lt;br /&gt;
		Blog blog = new Blog();&lt;br /&gt;
		bind(request, blog);&lt;br /&gt;
		blogService.createBlog(blog);&lt;br /&gt;
		return &amp;quot;redirect:findBlogs.do&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
	/* 중간 생략 */&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*MultiActionController로부터 override한 initBinder 함수는 form 관련 속성 값들에 대한 설정이 필요할 때 사용한다.&lt;br /&gt;
**이 예제에서는 Date Type과 String Type의 변환을 위해 initBind() 메소드를 사용하였다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
	// Override&lt;br /&gt;
	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {&lt;br /&gt;
		DateFormat df = new SimpleDateFormat(&amp;quot;yyyy-MM-dd HH:mm:ss&amp;quot;);&lt;br /&gt;
		CustomDateEditor dateEdit = new CustomDateEditor(df, false);&lt;br /&gt;
		binder.registerCustomEditor(Date.class, dateEdit);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Spring MVC Blog 예제 다운로드==&lt;br /&gt;
*SpringMVC + springframework + iBatis으로 이루어진 예제이다.&lt;br /&gt;
*[[media:blog_arid_coc.zip|Spring MVC Blog 예제 다운로드]]&lt;br /&gt;
*데이터베이스는 Oracle을 사용하였다. &lt;br /&gt;
{{정보|&lt;br /&gt;
*예제 실행을 위해서는 JDK, 이클립스, 톰캣 등의 개발환경이 필요하다. ([[개인 개발환경]] 참고) &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==참고자료==&lt;br /&gt;
*[http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html Spring Web MVC Framework]&lt;br /&gt;
*[http://code.google.com/p/aridpojos/ Arid Pojo]&lt;/div&gt;</description>
			<pubDate>Tue, 01 Jul 2008 09:02:13 GMT</pubDate>			<dc:creator>Stardust</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Spring_MVC_%26_Java1.4_tip</comments>		</item>
		<item>
			<title>Spring MVC JSON</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_MVC_JSON</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* ViewResolver */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물: Quick Start에서 SpringMVC/JSON/Ext-js 개발하기&lt;br /&gt;
*작성자: 서경진&lt;br /&gt;
*최초작성일 : 2008/07/04&lt;br /&gt;
*최종작성일 : 2008/07/14&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
* 이 문서에 해당하는 프로젝트는 Maven Project이므로 M2 Plugin을 활용한 라이브러리 관리 및 Build 및 Deploy 관리가 가능하다.&lt;br /&gt;
* Quick Start는 jetty와 hsql 기반이지만 이 프로젝트는 tomcat과 postgresql로 구현되었으므로 mvn에서 Build 및 Deploy를 위한 명령을 제공한다.&lt;br /&gt;
}}&lt;br /&gt;
{{경고|&lt;br /&gt;
*이 문서는 현재 작성중에 있습니다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
=프로젝트 환경 구축하기=&lt;br /&gt;
*다음 Quick Start 매뉴얼에 따라 Spring MVC 기반으로 Ext-js, JSON을 적용한 웹 어플리케이션 환경을 구축할 수 있다.&lt;br /&gt;
&lt;br /&gt;
{{정보|&lt;br /&gt;
*JCF Quick Start로 프로젝트 환경설치: http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/JCFQuickStart&lt;br /&gt;
*프로젝트 생성에서 SpringMVC + Spring + IBatis 선택 후 프로젝트 구성: http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/QuickStart:SpringMVCSpringIBatis&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
*Local PC에 Maven을 위한 라이브러리 Repository를 설정하기 위하여 해당 사용자의 개인디렉터리에 있는 .m2 폴더에 설정파일(setting.xml)에 사용자의 환경에 맞도록 설정한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:Maven_LocalRepository_Configuration.JPG|600px|thumb|center|Maven Local Repository 설정파일]]&lt;br /&gt;
&lt;br /&gt;
*다음은 .m2 디렉터리에 있는 setting.xml에 설정된 내용이다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;settings xmlns=&amp;quot;http://maven.apache.org/POM/4.0.0&amp;quot; xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
    xsi:schemaLocation=&amp;quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;localRepository&amp;gt;d:\maven\repository&amp;lt;/localRepository&amp;gt; &amp;lt;!--내 PC의 Local Repository가 사용할 디렉터리의 위치정보를 설정한다.--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;mirrors&amp;gt;&lt;br /&gt;
        &amp;lt;mirror&amp;gt;&lt;br /&gt;
            &amp;lt;id&amp;gt;mirror-of-central&amp;lt;/id&amp;gt;&lt;br /&gt;
            &amp;lt;mirrorOf&amp;gt;*&amp;lt;/mirrorOf&amp;gt;&lt;br /&gt;
            &amp;lt;name&amp;gt;Mirror of central repository&amp;lt;/name&amp;gt;&lt;br /&gt;
            &amp;lt;url&amp;gt;http://scm.dev.daewoobrenic.co.kr/artifactory/repo&amp;lt;/url&amp;gt; &amp;lt;!--central의 cache 역할을 수행하는 repository의 위치정보를 설정한다.--&amp;gt;&lt;br /&gt;
        &amp;lt;/mirror&amp;gt;&lt;br /&gt;
    &amp;lt;/mirrors&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;profiles&amp;gt;&lt;br /&gt;
        &amp;lt;profile&amp;gt;&lt;br /&gt;
            &amp;lt;id&amp;gt;mirroringCentral&amp;lt;/id&amp;gt;&lt;br /&gt;
            &amp;lt;activation&amp;gt;&lt;br /&gt;
                &amp;lt;activeByDefault&amp;gt;true&amp;lt;/activeByDefault&amp;gt;&lt;br /&gt;
            &amp;lt;/activation&amp;gt;&lt;br /&gt;
            &amp;lt;repositories&amp;gt;&lt;br /&gt;
                &amp;lt;repository&amp;gt;&lt;br /&gt;
                    &amp;lt;id&amp;gt;central&amp;lt;/id&amp;gt;&lt;br /&gt;
                    &amp;lt;url&amp;gt;http://scm.dev.daewoobrenic.co.kr/artifactory/repo&amp;lt;/url&amp;gt;&lt;br /&gt;
                    &amp;lt;releases&amp;gt;&lt;br /&gt;
                        &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;
                    &amp;lt;/releases&amp;gt;&lt;br /&gt;
                    &amp;lt;snapshots&amp;gt;&lt;br /&gt;
                        &amp;lt;enabled&amp;gt;false&amp;lt;/enabled&amp;gt;&lt;br /&gt;
                    &amp;lt;/snapshots&amp;gt;&lt;br /&gt;
                &amp;lt;/repository&amp;gt;&lt;br /&gt;
                &amp;lt;repository&amp;gt;&lt;br /&gt;
                    &amp;lt;id&amp;gt;snapshots&amp;lt;/id&amp;gt;&lt;br /&gt;
                    &amp;lt;url&amp;gt;http://scm.dev.daewoobrenic.co.kr/artifactory/repo&amp;lt;/url&amp;gt;&lt;br /&gt;
                    &amp;lt;releases&amp;gt;&lt;br /&gt;
                        &amp;lt;enabled&amp;gt;false&amp;lt;/enabled&amp;gt;&lt;br /&gt;
                    &amp;lt;/releases&amp;gt;&lt;br /&gt;
                    &amp;lt;snapshots&amp;gt;&lt;br /&gt;
                        &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;
                    &amp;lt;/snapshots&amp;gt;&lt;br /&gt;
                &amp;lt;/repository&amp;gt;&lt;br /&gt;
            &amp;lt;/repositories&amp;gt;&lt;br /&gt;
            &amp;lt;pluginRepositories&amp;gt;&lt;br /&gt;
                &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;
                    &amp;lt;id&amp;gt;central&amp;lt;/id&amp;gt;&lt;br /&gt;
                    &amp;lt;url&amp;gt;http://scm.dev.daewoobrenic.co.kr/artifactory/plugins-releases&amp;lt;/url&amp;gt;&lt;br /&gt;
                    &amp;lt;releases&amp;gt;&lt;br /&gt;
                        &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;
                    &amp;lt;/releases&amp;gt;&lt;br /&gt;
                    &amp;lt;snapshots&amp;gt;&lt;br /&gt;
                        &amp;lt;enabled&amp;gt;false&amp;lt;/enabled&amp;gt;&lt;br /&gt;
                    &amp;lt;/snapshots&amp;gt;&lt;br /&gt;
                &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;
                &amp;lt;pluginRepository&amp;gt;&lt;br /&gt;
                    &amp;lt;id&amp;gt;snapshots&amp;lt;/id&amp;gt;&lt;br /&gt;
                    &amp;lt;url&amp;gt;http://scm.dev.daewoobrenic.co.kr/artifactory/plugins-snapshots&amp;lt;/url&amp;gt;&lt;br /&gt;
                    &amp;lt;releases&amp;gt;&lt;br /&gt;
                        &amp;lt;enabled&amp;gt;false&amp;lt;/enabled&amp;gt;&lt;br /&gt;
                    &amp;lt;/releases&amp;gt;&lt;br /&gt;
                    &amp;lt;snapshots&amp;gt;&lt;br /&gt;
                        &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;&lt;br /&gt;
                    &amp;lt;/snapshots&amp;gt;&lt;br /&gt;
                &amp;lt;/pluginRepository&amp;gt;&lt;br /&gt;
            &amp;lt;/pluginRepositories&amp;gt;&lt;br /&gt;
        &amp;lt;/profile&amp;gt;&lt;br /&gt;
        &amp;lt;profile&amp;gt;&lt;br /&gt;
            &amp;lt;id&amp;gt;oracle&amp;lt;/id&amp;gt;&lt;br /&gt;
            &amp;lt;properties&amp;gt;&lt;br /&gt;
                &amp;lt;db.groupId&amp;gt;com.oracle&amp;lt;/db.groupId&amp;gt;&lt;br /&gt;
                &amp;lt;db.artifactId&amp;gt;ojdbc14&amp;lt;/db.artifactId&amp;gt;&lt;br /&gt;
                &amp;lt;db.version&amp;gt;10.2.0.3.0&amp;lt;/db.version&amp;gt;&lt;br /&gt;
                &amp;lt;jdbc.driverClassName&amp;gt;oracle.jdbc.driver.OracleDriver&amp;lt;/jdbc.driverClassName&amp;gt;&lt;br /&gt;
                &amp;lt;jdbc.url&amp;gt;jdbc:oracle:thin:@DB서버IP:포트번호:SID&amp;lt;/jdbc.url&amp;gt;&lt;br /&gt;
                &amp;lt;jdbc.username&amp;gt;사용자ID&amp;lt;/jdbc.username&amp;gt;&lt;br /&gt;
                &amp;lt;jdbc.password&amp;gt;패스워드&amp;lt;/jdbc.password&amp;gt;&lt;br /&gt;
            &amp;lt;/properties&amp;gt;&lt;br /&gt;
        &amp;lt;/profile&amp;gt;&lt;br /&gt;
    &amp;lt;/profiles&amp;gt;&lt;br /&gt;
&amp;lt;/settings&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*로컬 저장소를 &amp;lt;localRepository&amp;gt;d:\maven\repository&amp;lt;/localRepository&amp;gt;와 같이 저장하면 다음과 같이 Maven 저장소에서 받은 라이브러리가 이 위치에 저장된다.&lt;br /&gt;
*이와 같이 로컬 저장소를 설정하지 않으면 디폴트인 .m2 디렉터리에 라이브러리가 저장된다.&lt;br /&gt;
&lt;br /&gt;
[[그림:Maven_LocalRealRepository.JPG|800px|thumb|center|로컬 저장소에 저장된 라이브러리]]&lt;br /&gt;
&lt;br /&gt;
*command(cmd.exe) 콘솔을 실행시켜서 다음과 같이 명령을 입력하면 pom.xml에 정의된 hsql에 table을 생성하여 jetty가 구동된다.&lt;br /&gt;
*위에서 정의된 내용에 따라 memo 웹 어플리케이션이 구동되고 다음과 같이 웹브라우저로 확인이 된다면 SpringMVC + Spring + IBatis 아키텍처를 가진 Maven 프로젝트 기반으로 개발할 수 있는 환경이 구축된 것이다.&lt;br /&gt;
&lt;br /&gt;
[[그림:MavenProject_MemoApplication.JPG|580px|thumb|center|memo 웹 어플리케이션 구동 화면]]&lt;br /&gt;
&lt;br /&gt;
{{정보|&lt;br /&gt;
*샘플 웹 어플리케이션의 개발환경&lt;br /&gt;
**UI: Ext-js 2.0, JSP&lt;br /&gt;
**Presentation Tier: Spring MVC, Spring MVC Annotation (SpringFramework 2.5.4)&lt;br /&gt;
**Business Tier: SpringFramework 2.5.4&lt;br /&gt;
**Persistence Tier: ibatis 2.3.0&lt;br /&gt;
**DB: PostgreSQL 8.3.3&lt;br /&gt;
**IDE: Eclipse Platform 3.3.0 (WTP, DTP 적용)&lt;br /&gt;
**Build &amp;amp; Deploy: Maven&lt;br /&gt;
**WAS: Tomcat 5.0&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
*위의 개발환경 정보에 따라 예제 어플리케이션의 개발은 jetty 환경이 아닌 Tomcat 환경에서 구현된다.&lt;br /&gt;
*따라서 소스개발 이후 Tomcat을 구동시키기 전에 다음과 같은 일련의 명령을 DOS Command 콘솔에서 실행해야 한다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
해당프로젝트위치&amp;gt; mvn compiler:compile&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   : 수정된 내용에 대하여 Maven 기반의 컴파일을 수행한다. (Target에 저장)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
해당프로젝트위치&amp;gt; mvn war:inplace&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   : Tomcat 환경에서 구동하기 위해 Web Root (src/main/webapp/WEB-INF의 lib와 classes 디렉터리에 라이브러리와 클래스를 복사한다.)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
해당프로젝트위치&amp;gt; mvn eclipse:eclipse&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   : pom.xml로부터 eclipse 프로젝트 파일(.project)을 생성한다. 즉 라이브러리를 buildpath에 설정한다.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Quick Start에서 SpringMVC/JSON/Ext-js로 개발할 간단한 웹 어플리케이션은 다음과 같다.&lt;br /&gt;
&lt;br /&gt;
[[그림:MavenProject_DSOMApplication.JPG|850px|thumb|center|Ext-js 기반 샘플 웹 어플리케이션 화면]]&lt;br /&gt;
&lt;br /&gt;
*위의 샘플 웹 어플리케이션은 상단의 메뉴바에서 해당 메뉴를 클릭하면 부서리스트 조회화면이 우측 Div에 출력된다.&lt;br /&gt;
*우측 상단에 조회버튼을 클릭하면 서버에서 부서리스트를 조회하여 그 결과를 다음과 같이 JSON 데이터로 출력한다.&lt;br /&gt;
&lt;br /&gt;
[[그림:MavenProject_JsonResponse.JPG|700px|thumb|center|조회 Request에 대한 JSON Response]]&lt;br /&gt;
&lt;br /&gt;
*JSON 데이터를 받으면 위의 샘플 웹 어플리케이션 화면과 같이 데이터를 그리드에 바인딩한다.&lt;br /&gt;
&lt;br /&gt;
=Spring MVC Request Lifecycle=&lt;br /&gt;
*샘플 웹 어플리케이션 구현은 Spring MVC Request Lifecycle을 기반으로 순서대로 진행될 것이다.&lt;br /&gt;
&lt;br /&gt;
[[그림:SpringMVC_JsonView_Request_Sequence.jpg|820px|thumb|center|SpringMVC Request 처리 Sequence Diagram]]&lt;br /&gt;
&lt;br /&gt;
*Spring MVC 기반의 웹 어플리케이션은 아키텍처 구성에 따라 일반적으로 다음과 같은 순서대로 설정파일을 구성한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. Request에 따른 DispatcherServlet의 요청 패턴을 정의 및 설정한다. =&amp;gt; web.xml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
2. DispatcherServlet이 참조할 HandlerMapping을 설정한다. =&amp;gt; 서블릿명-servlet.xml (필요하다면 새로운 HandlerMapping 구현 가능)&lt;br /&gt;
   (명시적으로 설정하지 않으면 Spring MVC는 BeanNameUrlHandlerMapping을 디폴트 HandlerMapping으로 설정)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
3. HandlerMapping에 Controller mapping에 대한 정보를 설정한다.&lt;br /&gt;
3.1 Annotation을 사용하지 않는 경우, 서블릿명-servlet.xml에 mapping 정보를 설정한다.&lt;br /&gt;
3.2 Annotation을 사용하는 경우, Spring MVC Annotation을 사용하여 해당 클래스에 설정한다.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
4. View를 처리하기 위한 ViewResolver 및 View에 대하여 설정한다.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
5. Spring의 Application Context에 Controller, Service, Dao를 등록하기 위해 설정한다.&lt;br /&gt;
5.1 Annotation을 사용하지 않는 경우,&lt;br /&gt;
5.1.1 Controller를 Bean으로 등록한다.: 서블릿명-servlet.xml의 HandlerMapping에 설정된 Controller 클래스를 등록한다.&lt;br /&gt;
5.1.2 Service와 Dao를 모두 Bean으로 등록한다.&lt;br /&gt;
&lt;br /&gt;
5.2 Annotation을 사용하는 경우,&lt;br /&gt;
5.2.1 Controller 클래스에 @Controller Annotation을 적용하고 서블릿명-servlet.xml의 Controller에 대한 Component 스캐닝을 통해 자동으로 bean을 등록한다.&lt;br /&gt;
5.2.2 Service 클래스에 @Component Annotation을 적용하고 applicationContext-어플리케이션명.xml의 Service에 대한 Component 스캐닝을 통해 자동으로 bean을 등록한다.&lt;br /&gt;
5.2.3 Dao 클래스는 SqlMapClient에 대한 등록문제로 Annotation을 사용하지 않는 방법과 같이 applicationContext-어플리케이션명.xml에 Bean으로 직접 등록한다.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*위에 명시된 순서는 아키텍처 구조나 적용된 구성요소에 따라 변경이 필요할 수 있다.&lt;br /&gt;
&lt;br /&gt;
=연동 설정방법=&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. Request에 따른 DispatcherServlet의 요청 패턴을 정의 및 설정한다. =&amp;gt; web.xml&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Request에 따른 DispatcherServlet의 요청 패턴 정의 및 설정&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1. JSTL을 활용한 JSP 페이지를 출력할 경우 .action 패턴 적용&lt;br /&gt;
2. JSON을 활용한 Ext-js 페이지를 출력할 경우 .json 패턴 적용&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*웹 설정파일인 web.xml에 다음과 같이 설정한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;web-app id=&amp;quot;WebApp_ID&amp;quot; version=&amp;quot;2.4&amp;quot; xmlns=&amp;quot;http://java.sun.com/xml/ns/j2ee&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;context-param&amp;gt;&lt;br /&gt;
		&amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;&lt;br /&gt;
		&amp;lt;param-value&amp;gt;classpath:applicationContext*.xml&amp;lt;/param-value&amp;gt;&lt;br /&gt;
	&amp;lt;/context-param&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;listener&amp;gt;&lt;br /&gt;
		&amp;lt;listener-class&amp;gt;&lt;br /&gt;
			org.springframework.web.context.ContextLoaderListener&amp;lt;/listener-class&amp;gt;&lt;br /&gt;
	&amp;lt;/listener&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;filter&amp;gt;&lt;br /&gt;
		&amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
		&amp;lt;filter-class&amp;gt;&lt;br /&gt;
			org.springframework.web.filter.CharacterEncodingFilter&amp;lt;/filter-class&amp;gt;&lt;br /&gt;
		&amp;lt;init-param&amp;gt;&lt;br /&gt;
			&amp;lt;param-name&amp;gt;encoding&amp;lt;/param-name&amp;gt;&lt;br /&gt;
			&amp;lt;param-value&amp;gt;UTF-8&amp;lt;/param-value&amp;gt;&lt;br /&gt;
		&amp;lt;/init-param&amp;gt;&lt;br /&gt;
	&amp;lt;/filter&amp;gt;&lt;br /&gt;
	&amp;lt;filter-mapping&amp;gt;&lt;br /&gt;
		&amp;lt;filter-name&amp;gt;characterEncodingFilter&amp;lt;/filter-name&amp;gt;&lt;br /&gt;
		&amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
	&amp;lt;/filter-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;servlet&amp;gt;&lt;br /&gt;
		&amp;lt;servlet-name&amp;gt;jsonview&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
		&amp;lt;servlet-class&amp;gt;&lt;br /&gt;
			org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
	&amp;lt;/servlet&amp;gt;&lt;br /&gt;
	&amp;lt;servlet&amp;gt;&lt;br /&gt;
		&amp;lt;servlet-name&amp;gt;annotated&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
		&amp;lt;servlet-class&amp;gt;&lt;br /&gt;
			org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
	&amp;lt;/servlet&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
		&amp;lt;servlet-name&amp;gt;jsonview&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
		&amp;lt;url-pattern&amp;gt;*.json&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
	&amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
	&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
		&amp;lt;servlet-name&amp;gt;annotated&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
		&amp;lt;url-pattern&amp;gt;*.action&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
	&amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&amp;lt;/web-app&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
2. DispatcherServlet이 참조할 HandlerMapping을 설정한다. =&amp;gt; 서블릿명-servlet.xml (필요하다면 새로운 HandlerMapping 구현 가능)&lt;br /&gt;
   (명시적으로 설정하지 않으면 Spring MVC는 BeanNameUrlHandlerMapping을 디폴트 HandlerMapping으로 설정)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*HandlerMapping으로 BeanNameUrlHandlerMapping을 사용할 경우는 서블릿명-servlet.xml에 명시적으로 설정할 필요가 없다.&lt;br /&gt;
*만약 BeanNameUrlHandlerMapping이 아닌 다른 HandlerMapping을 사용할 경우에는 다음과 같이 명시적으로 설정한다.&lt;br /&gt;
*다음은 Spring MVC 매뉴얼에 있는 SimpleUrlHandlerMapping을 적용하는 방법이다.&lt;br /&gt;
&lt;br /&gt;
*web.xml&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;web-app&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
    &amp;lt;servlet&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;sample&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!-- maps the sample dispatcher to *.form --&amp;gt;&lt;br /&gt;
    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;sample&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;*.form&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!-- maps the sample dispatcher to *.html --&amp;gt;&lt;br /&gt;
    &amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
        &amp;lt;servlet-name&amp;gt;sample&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
        &amp;lt;url-pattern&amp;gt;*.html&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
    &amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
    ...&lt;br /&gt;
&amp;lt;/web-app&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*서블릿명-servlet.xml&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;beans&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
    &amp;lt;!-- no 'id' required, HandlerMapping beans are automatically detected by the DispatcherServlet --&amp;gt;&lt;br /&gt;
    &amp;lt;bean class=&amp;quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;property name=&amp;quot;mappings&amp;quot;&amp;gt;&lt;br /&gt;
            &amp;lt;value&amp;gt;&lt;br /&gt;
                /*/account.form=editAccountFormController&lt;br /&gt;
                /*/editaccount.form=editAccountFormController&lt;br /&gt;
                /ex/view*.html=helpController&lt;br /&gt;
                /**/help.html=helpController&lt;br /&gt;
            &amp;lt;/value&amp;gt;&lt;br /&gt;
        &amp;lt;/property&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;bean id=&amp;quot;helpController&amp;quot;&lt;br /&gt;
          class=&amp;quot;org.springframework.web.servlet.mvc.UrlFilenameViewController&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;bean id=&amp;quot;editAccountFormController&amp;quot;&lt;br /&gt;
          class=&amp;quot;org.springframework.web.servlet.mvc.SimpleFormController&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;property name=&amp;quot;formView&amp;quot; value=&amp;quot;account&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;property name=&amp;quot;successView&amp;quot; value=&amp;quot;account-created&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;property name=&amp;quot;commandName&amp;quot; value=&amp;quot;Account&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;property name=&amp;quot;commandClass&amp;quot; value=&amp;quot;samples.Account&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;beans&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
3. HandlerMapping에 Controller mapping에 대한 정보를 설정한다.&lt;br /&gt;
3.1 Annotation을 사용하지 않는 경우, 서블릿명-servlet.xml에 mapping 정보를 설정한다.&lt;br /&gt;
3.2 Annotation을 사용하는 경우, Spring MVC Annotation을 사용하여 해당 클래스에 설정한다.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Controller==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==ViewResolver==&lt;br /&gt;
&lt;br /&gt;
===JstlViewResolver===&lt;br /&gt;
&lt;br /&gt;
===XmlViewResolver===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MiplatformViewResolver===&lt;br /&gt;
&lt;br /&gt;
==View==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===JstlView===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===JsonView===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===MiplatformView===&lt;/div&gt;</description>
			<pubDate>Sat, 28 Jun 2008 04:47:16 GMT</pubDate>			<dc:creator>Kyoung94</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Spring_MVC_JSON</comments>		</item>
		<item>
			<title>로그인 세션 체크하는 커스텀 인터셉터 만들기</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%EB%A1%9C%EA%B7%B8%EC%9D%B8_%EC%84%B8%EC%85%98_%EC%B2%B4%ED%81%AC%ED%95%98%EB%8A%94_%EC%BB%A4%EC%8A%A4%ED%85%80_%EC%9D%B8%ED%84%B0%EC%85%89%ED%84%B0_%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 작업 개요 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물:   세션 체크하는 커스텀 인터셉터Spring MVC 개요&lt;br /&gt;
*작성자:   정광선&lt;br /&gt;
*최초작성일 : 2008/06/25&lt;br /&gt;
*최종작성일 : 2008/06/25&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
* 스트럿츠2에서 세션 검사하는 커스텀 인터셉터를 작성해 본다. &lt;br /&gt;
}}&lt;br /&gt;
{{경고|&lt;br /&gt;
* 권한별 요청 접근 처리가 아니며, 또한 모든 웹 요청이 아니라 스트럿츠 액션에 대한 요청만 처리하는 모듈 예제이다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==작업 개요==&lt;br /&gt;
* 로그인 했는지 검사하여, 로그인 하지 않았다면, 로그인 페이지나 특정 XML 메세지를 보내기 위한 인터셉터를 작성한다.&lt;br /&gt;
* 액션 요청에 대해서만 검증할 것이기 때문에 인터셉터에서의 적용이 적합하겠다.&lt;br /&gt;
* 적용 작업은 아래와 같다.&lt;br /&gt;
** 커스텀 인터셉터 작성하기&lt;br /&gt;
** struts.xml에 인터셉터 정의하여 적용하기&lt;br /&gt;
* [[media:custom_interceptor_session_check.png|처리 프로세스 플로우차트 보기]]&lt;br /&gt;
&lt;br /&gt;
== 커스텀 인터셉터 작성하기 ==&lt;br /&gt;
* // TODO 부분(2군데..)는 해당 애플리케이션에 맞게 작성해 주어야 하겠다.&lt;br /&gt;
** 첫번째는 proccessDeniedResponse() 메소드에 있으며, 마이플랫폼 메세지를 던져주는 부분이다.&lt;br /&gt;
** 두번째는 isLogined()메소드에 있으며, 세션상에 로그인 정보를 검사하는 부분이다.&lt;br /&gt;
* 소스 설명&lt;br /&gt;
** 인터셉터가 작동하는 메인 메소드는 intercept(ActionInvocation invocation) 메소드이다.&lt;br /&gt;
*** 여기서 허용 URL인지, 로그인 했는지 검사하는 것과 요청을 거부하는 프로세스를 처리한다.&lt;br /&gt;
** excludeActions 변수는 로그인 했는지 검사하는 것에서 제외하기 위한 액션들이 있는 경우 사용한다.&lt;br /&gt;
** redirectWebPage 변수는 일반 웹 요청시 액션 수행 거부(로그인 하지 않음)에 대해 라디이렉트 할 페이지를 지정한다.&lt;br /&gt;
*** 이와 마찬가지로 마이플랫폼 요청에 대한 거부 메세지도 파라미터화 하여 처리할 수 있겠다.&lt;br /&gt;
&amp;lt;code lang='java'&amp;gt;&lt;br /&gt;
public class LoginSessionCheckInterceptor extends AbstractInterceptor{&lt;br /&gt;
&lt;br /&gt;
    private static Log log = LogFactory.getLog(LoginSessionCheckInterceptor.class);&lt;br /&gt;
	&lt;br /&gt;
    protected Set excludeActions = null;&lt;br /&gt;
    &lt;br /&gt;
    protected String redirectWebPage = &amp;quot;/index.html&amp;quot;; // default page if not setted by param.    &lt;br /&gt;
&lt;br /&gt;
    public void setExcludeActions(String excludeActions) {&lt;br /&gt;
        this.excludeActions = TextParseUtil.commaDelimitedStringToSet(excludeActions);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
	public void setRedirectWebPage(String redirectWebPage) {&lt;br /&gt;
		if( StringUtils.isNotBlank(redirectWebPage)) this.redirectWebPage = redirectWebPage;&lt;br /&gt;
	}&lt;br /&gt;
    &lt;br /&gt;
	/**&lt;br /&gt;
	 * check and deny the request unless rquested action is available action without login or has authenticated session.  &lt;br /&gt;
	 * &lt;br /&gt;
	 */&lt;br /&gt;
	public String intercept(ActionInvocation invocation) throws Exception {&lt;br /&gt;
		&lt;br /&gt;
		if( isAvailableActionWithoutLogin() ){ // check if action is available action without login&lt;br /&gt;
			return invocation.invoke(); // execute action&lt;br /&gt;
		}&lt;br /&gt;
		else{&lt;br /&gt;
			if( isLogined()){ // check if logged in or not&lt;br /&gt;
				return invocation.invoke(); // execute action&lt;br /&gt;
			}&lt;br /&gt;
			else{&lt;br /&gt;
				proccessDeniedResponse(); // redirect to login page, or send denial xml message&lt;br /&gt;
				return null;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	private void proccessDeniedResponse() throws IOException { &lt;br /&gt;
		if( isMiplatformRequest(ServletActionContext.getRequest()) ){&lt;br /&gt;
			// TODO send MiResponse denial message&lt;br /&gt;
			// example is following :&lt;br /&gt;
			// 		MiResponse miresponse = new MiResponse(ServletActionContext.getResponse());&lt;br /&gt;
			// 		miresponse.error(&amp;quot;-1&amp;quot;,&amp;quot;sessionout&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
		else{&lt;br /&gt;
			String redirectUrl = null;&lt;br /&gt;
			if( redirectWebPage.startsWith(&amp;quot;/&amp;quot;) || redirectWebPage.startsWith(&amp;quot;\\&amp;quot;)){&lt;br /&gt;
				redirectUrl = ServletActionContext.getRequest().getContextPath() + redirectWebPage;&lt;br /&gt;
			}else{&lt;br /&gt;
				redirectUrl = ServletActionContext.getRequest().getContextPath() + &amp;quot;/&amp;quot; +redirectWebPage;&lt;br /&gt;
			}			&lt;br /&gt;
			ServletActionContext.getResponse().sendRedirect(redirectUrl);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private boolean isMiplatformRequest(HttpServletRequest request) {&lt;br /&gt;
		String agent = request.getHeader(&amp;quot;User-Agent&amp;quot;);		&lt;br /&gt;
		if( agent != null &amp;amp;&amp;amp; ( agent.indexOf(&amp;quot;MiPlatform&amp;quot;) != -1 ) ){&lt;br /&gt;
			return true;&lt;br /&gt;
		}else{&lt;br /&gt;
			return false;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private boolean isLogined() {&lt;br /&gt;
		HttpSession session = ServletActionContext.getRequest().getSession(false);&lt;br /&gt;
		if( null == session) return false;&lt;br /&gt;
		&lt;br /&gt;
		// TODO check if session is logined session.&lt;br /&gt;
		// example is following : &lt;br /&gt;
		// 		if( isLogedin(session) ) return true;&lt;br /&gt;
		// 		else return false;&lt;br /&gt;
		&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private boolean isAvailableActionWithoutLogin() {&lt;br /&gt;
		String requestedResouece = getRequestedResource(ServletActionContext.getRequest());&lt;br /&gt;
		if( log.isDebugEnabled() ) log.debug(&amp;quot;Requested action resource : &amp;quot; + requestedResouece);&lt;br /&gt;
		&lt;br /&gt;
		String action = null;&lt;br /&gt;
		Iterator excludeActionsIter = excludeActions.iterator();&lt;br /&gt;
		while( excludeActionsIter.hasNext() ){&lt;br /&gt;
			action = (String) excludeActionsIter.next();&lt;br /&gt;
			if( requestedResouece.equals(action) ) return true;	&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private String getRequestedResource(HttpServletRequest request){&lt;br /&gt;
		String requestedResouece = null;&lt;br /&gt;
		&lt;br /&gt;
		String contextPath = request.getContextPath();&lt;br /&gt;
		String requestedUri = request.getRequestURI();&lt;br /&gt;
		&lt;br /&gt;
		if( &amp;quot;/&amp;quot;.equals(contextPath) ){&lt;br /&gt;
			requestedResouece = requestedUri;&lt;br /&gt;
		}&lt;br /&gt;
		else{&lt;br /&gt;
			requestedResouece = requestedUri.substring(contextPath.length());&lt;br /&gt;
		}		&lt;br /&gt;
		return requestedResouece;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 인터셉터의 적용 ==&lt;br /&gt;
* struts.xml에 우리가 작성한 인터셉터를 정의하고, 이를 이용하여 인터셉터 스택을 만든다.&lt;br /&gt;
* 정의가 끝나면 common 패키지를 상속하는 다른 모든 스트럿츠2 패키지들을 모두 디폴트 인터셉터 스택이 commonStack이 될 것이다.&lt;br /&gt;
** 여기서는 스트럿츠의 디폴트 인터셉터 스택을 다소 최적화하여 사용하고 있다.&lt;br /&gt;
** loginCheck 인터셉터의 정의 부분과 스택에서 사용하는 부분을 주의하여 살펴 본다.&lt;br /&gt;
** excludeActions 파라미터에는 샘플로 login.action과 /lab1/hello2.action은 로그인을 하지 않아도 수행할 수 있는 액션으로 정의해 놓았다.&lt;br /&gt;
** excludeActions 아래에 &amp;lt;param name=&amp;quot;redirectWebPage&amp;quot;&amp;gt;/login.jsp&amp;lt;/param&amp;gt;를 추가 작성하면, 로그인 하지 않고 접근하는 액션 일반 웹 액션 요청들을 거부하고 login.jsp로 리다이렉트 하게 될 것이다.&lt;br /&gt;
** [과제] 웹 요청 말고도 마이플랫폼 요청을 거부하는 경우에 사용하는 에러코드와 에러메시지도 파라미터로 처리하도록 개선해 보자.&lt;br /&gt;
&amp;lt;code lang='xml'&amp;gt;&lt;br /&gt;
&amp;lt;struts&amp;gt;&lt;br /&gt;
	&amp;lt;package name=&amp;quot;common&amp;quot; extends=&amp;quot;struts-default&amp;quot; namespace=&amp;quot;&amp;quot;&amp;gt;	&lt;br /&gt;
		&amp;lt;interceptors&amp;gt;&lt;br /&gt;
			&amp;lt;interceptor name=&amp;quot;loginCheck&amp;quot; class=&amp;quot;kr.ac.catholic.web.struts2.interceptor.LoginSessionCheckInterceptor&amp;quot;/&amp;gt;&lt;br /&gt;
			&amp;lt;interceptor-stack name=&amp;quot;commonStack&amp;quot;&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;exception&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;loginCheck&amp;quot;&amp;gt;&lt;br /&gt;
			                	&amp;lt;param name=&amp;quot;excludeActions&amp;quot;&amp;gt;login.action, /lab1/hello2.action&amp;lt;/param&amp;gt;&lt;br /&gt;
			                &amp;lt;/interceptor-ref&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;alias&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;servletConfig&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;prepare&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;i18n&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;chain&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;debugging&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;fileUpload&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;checkbox&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;staticParams&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;params&amp;quot;&amp;gt;&lt;br /&gt;
			                  &amp;lt;param name=&amp;quot;excludeParams&amp;quot;&amp;gt;dojo\..*&amp;lt;/param&amp;gt;&lt;br /&gt;
			                &amp;lt;/interceptor-ref&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;conversionError&amp;quot;/&amp;gt;&lt;br /&gt;
			                &amp;lt;interceptor-ref name=&amp;quot;validation&amp;quot;&amp;gt;&lt;br /&gt;
			                    &amp;lt;param name=&amp;quot;excludeMethods&amp;quot;&amp;gt;input,back,cancel,browse&amp;lt;/param&amp;gt;&lt;br /&gt;
			                &amp;lt;/interceptor-ref&amp;gt;&lt;br /&gt;
			&amp;lt;/interceptor-stack&amp;gt;&lt;br /&gt;
		&amp;lt;/interceptors&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
		&amp;lt;default-interceptor-ref name=&amp;quot;commonStack&amp;quot;/&amp;gt;&lt;br /&gt;
		&lt;br /&gt;
	&amp;lt;/package&amp;gt;&lt;br /&gt;
&amp;lt;/struts&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</description>
			<pubDate>Wed, 25 Jun 2008 06:50:16 GMT</pubDate>			<dc:creator>Purple</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:%EB%A1%9C%EA%B7%B8%EC%9D%B8_%EC%84%B8%EC%85%98_%EC%B2%B4%ED%81%AC%ED%95%98%EB%8A%94_%EC%BB%A4%EC%8A%A4%ED%85%80_%EC%9D%B8%ED%84%B0%EC%85%89%ED%84%B0_%EB%A7%8C%EB%93%A4%EA%B8%B0</comments>		</item>
		<item>
			<title>Spring MVC Annotation</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_MVC_Annotation</link>
			<description>&lt;p&gt;바꾼내용 간추리기: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물:   Spring MVC Annotation&lt;br /&gt;
*작성자:   나윤주&lt;br /&gt;
*최초작성일 : 2008/06/24&lt;br /&gt;
*최종작성일 : 2008/06/24&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
*이 문서는 Java 5+환경을 사용하는 Spring Web MVC Framework에서 적용할 수 있는 Annotation에 관한 것이다.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Spring MVC Annotation==&lt;br /&gt;
*Spring Web MVC Framework는 Java 5+ 부터 annotation을 제공한다. annotation의 사용으로 설정파일을 간결화하고, View 페이지와 객체 또는 메소드의 맵핑을 명확하게 할 수 있다.&lt;br /&gt;
&lt;br /&gt;
===@Controller===&lt;br /&gt;
*Controller annotation으로 Controller interface 및 class의 기능을 간단하게 사용할 수 있다.&lt;br /&gt;
**Annotation을 사용하지 않고, Controller를 직접 상속받아 쓰는 경우 필요한 xml 설정을 생략할 수 있다.&lt;br /&gt;
**SimpleFormController, MultiActionController 등 Controller의 종류를 명시하지 않고 @Controller 설정만으로 사용할 수 있다.&lt;br /&gt;
*xxx-servlet.xml 파일에서 component-scan 으로 web controller가 있는 패키지를 명시해 줌으로써, 별도의 bean 설정을 하지 않아도 @Controller로 등록된 클래스 파일에 대한 bean을 자동으로 생성해준다.&lt;br /&gt;
**Controller로 사용하고자 하는 클래스에 @Controller 지정해주면 component-scan으로 자동 등록된다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- blog-servlet.xml --&amp;gt;&lt;br /&gt;
&amp;lt;context:component-scan base-package=&amp;quot;blog.web&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* BlogController.java */&lt;br /&gt;
package blog.web;&lt;br /&gt;
&lt;br /&gt;
/* 기타 package import .. */&lt;br /&gt;
import org.springframework.stereotype.Controller;&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
public class BlogController {&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===@RequestMapping===&lt;br /&gt;
*RequestMapping annotation은 url을 클래스 또는 메소드와 맵핑시켜주는 역할을 한다.&lt;br /&gt;
**Annotation을 쓰지 않을때 지정했던 Controller 등록을 위한 url bean 설정을 생략할 수 있다.&lt;br /&gt;
*class에 하나의 url 맵핑을 할 경우, 클래스 위에 @RequestMapping(&amp;quot;/url&amp;quot;)을 지정하며, GET 또는 POST 방식 등의 옵션을 줄 수 있다.&lt;br /&gt;
**해당되는 메소드가 실행된 후, return 페이지가 따로 정의되어 있지 않으면 @RequestMapping(&amp;quot;/url&amp;quot;)에서 설정된 url로 다시 돌아간다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* 중간생략 */&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
@RequestMapping(&amp;quot;/helloWorld&amp;quot;)&lt;br /&gt;
public class helloController {&lt;br /&gt;
	/* 중간생략 */&lt;br /&gt;
	&lt;br /&gt;
	@RequestMapping(method=RequestMethod.GET)&lt;br /&gt;
	public returntype getController() {&lt;br /&gt;
		/* .... */&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	@RequestMapping(method=RequestMethod.POST)&lt;br /&gt;
	public returntype postController() {&lt;br /&gt;
		/* .... */&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* 중간생략 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*메소드별로 url 맵핑을 할 경우는 메소드 위에 @RequestMapping(&amp;quot;/url&amp;quot;)로 지정한다.&lt;br /&gt;
*return 페이지가 지정되지 않은 경우 원래의 맵핑되었던 url로 돌아간다.&lt;br /&gt;
**return type을 String으로 하여 redirect:url또는 forward:url을 사용하여 다른 페이지로 넘길 수 있다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* BlogController.java */&lt;br /&gt;
package blog.web;&lt;br /&gt;
&lt;br /&gt;
/* 중간생략 */&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
public class BlogController {&lt;br /&gt;
	/* 중간생략 */&lt;br /&gt;
	&lt;br /&gt;
	@RequestMapping(&amp;quot;/createBlog&amp;quot;)&lt;br /&gt;
	public ModelMap createBlogHandler() {&lt;br /&gt;
		blog = new Blog();&lt;br /&gt;
		return new ModelMap(blog);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* 중간생략 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===@RequestParam===&lt;br /&gt;
*RequestParam annotation은 key=value 형태로 화면에서 넘어오는 파라미터를 맵핑된 메소드의 파라미터로 지정해준다.&lt;br /&gt;
*주로 get 방식으로 들어오는 request에서 사용한다.&lt;br /&gt;
**아래 예제코드에서 xxx/editBlog.do?blogId=3 과 같이 접근할 때, editBlogHandler 메소드의 파라미터인 blogId에는 3이 셋팅된다.&lt;br /&gt;
**필수 요건이 아닐 경우, @RequestParam(value=&amp;quot;id&amp;quot;, required=&amp;quot;false&amp;quot;)와 같이 옵션을 주고 사용할 수 있다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* BlogController.java */&lt;br /&gt;
package blog.web;&lt;br /&gt;
&lt;br /&gt;
/* 중간생략 */&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
public class BlogController {&lt;br /&gt;
	/* 중간생략 */&lt;br /&gt;
	&lt;br /&gt;
	@RequestMapping(&amp;quot;/editBlog&amp;quot;)&lt;br /&gt;
	public ModelMap editBlogHandler(@RequestParam(&amp;quot;blogId&amp;quot;) int blogId) {&lt;br /&gt;
		blog = blogService.findBlog(blogId); &lt;br /&gt;
		return new ModelMap(blog);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* 중간생략 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===@ModelAttribute===&lt;br /&gt;
*ModelAttribute annotation은 화면의 form 속성으로 넘어온 model을 맵핑된 메소드의 파라미터로 지정해주는 역할을 한다.&lt;br /&gt;
*주로 POST 타입으로 넘어오는 form 속성의 model 값을 받아올 때 사용된다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* BlogController.java */&lt;br /&gt;
package blog.web;&lt;br /&gt;
&lt;br /&gt;
/* 중간생략 */&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
public class BlogController {&lt;br /&gt;
	/* 중간생략 */&lt;br /&gt;
	&lt;br /&gt;
	@RequestMapping(&amp;quot;/updateBlog&amp;quot;)&lt;br /&gt;
	public String updateBlogHandler(@ModelAttribute(&amp;quot;blog&amp;quot;) Blog blog) {&lt;br /&gt;
		blogService.updateBlog(blog);&lt;br /&gt;
		return &amp;quot;redirect:findBlogs.do&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* 중간생략 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===@SessionAttributes===&lt;br /&gt;
*SessionAttributes annotation은 세션상에서 model의 정보를 유지하고 싶을 경우 사용할 수 있다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* BlogController.java */&lt;br /&gt;
package blog.web;&lt;br /&gt;
&lt;br /&gt;
/* 중간생략 */&lt;br /&gt;
&lt;br /&gt;
@Controller&lt;br /&gt;
@SessionAttributes(&amp;quot;blog&amp;quot;)&lt;br /&gt;
public class BlogController {&lt;br /&gt;
	/* 중간생략 */&lt;br /&gt;
&lt;br /&gt;
	@RequestMapping(&amp;quot;/createBlog&amp;quot;)&lt;br /&gt;
	public ModelMap createBlogHandler() {&lt;br /&gt;
		blog = new Blog();&lt;br /&gt;
		blog.setRegDate(new Date());&lt;br /&gt;
		return new ModelMap(blog);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* 중간생략 */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===@InitBinder===&lt;br /&gt;
@InitBinder annotation은 WebDataBinder를 초기화하는 메소드를 지정할 수 있는 설정을 제공한다. 일반적으로 WebDataBinder는 annotated handler 메소드의 command와 form 객체 인자를 조작하는데 사용된다. Initbinder 메소드는 command/form 객체와 validation result 객체와 대응하는 것을 제외하고 RequestMapping을 지원하는 모든 인자를 지원한다. Initbinder 메소드가 필수적으로 반환값을 가질 필요는 없으며, 일반적으로 이런 경우에 void를 선언한다.&lt;br /&gt;
특별한 인자는 WebDataBinder와 WebRequest 또는 Locale의 조합으로 이루어지며, 이러한 조건이 만족되면 context-specific editors를 등록하는 것이 허용된다.&lt;br /&gt;
&lt;br /&gt;
*'''WebDataBinder''' : WebDataBinder는 web request parameter를 JavaBean 객체에 바인딩하는 특정한 DataBinder이다. WebDataBinder는 웹 환경이 필요하지만, Servlet API에 의존적이지 않다. Servlet API에 의존적인 ServletRequestDataBinder와 같이 특정한 DataBinder를 위한 더 많은 base classs를 제공한다.&lt;br /&gt;
&lt;br /&gt;
*'''RequestMapping''' : RequestMapping annotation은 web request를 특정한 handler class와/나 handler method에 매핑하는 역할을 수행한다. 대응하는 HandlerMapping (for type level annotations)과/이나 HandlerAdapter (for method level annotations)가 dispatcher에 존재한다면, @RequestMapping이 처리될 것이다.&lt;br /&gt;
&lt;br /&gt;
*'''WebRequest''' : WebRequest는 웹 요청에 대한 Generic interface이다. 주로 일반 request metadata에 generic web request interceptors의 접근을 허용하여 metadata에 대한 처리를 하기 위한 것이지 request 자체를 처리하기 위한 것은 아니다.&lt;br /&gt;
&lt;br /&gt;
*@InitBinder 예제&lt;br /&gt;
다음의 InitBinder는 Request에 포함된 JSON 데이터를 binding하여 처리하는 역할을 수행한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
......&lt;br /&gt;
@InitBinder&lt;br /&gt;
	protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {&lt;br /&gt;
&lt;br /&gt;
		if (logger.isDebugEnabled()) {&lt;br /&gt;
			logger.debug(&amp;quot;entering 'initBinder' method...&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		JsonWriterConfiguratorTemplateRegistry registry = JsonWriterConfiguratorTemplateRegistry.load(request);&lt;br /&gt;
		registry.registerConfiguratorTemplate(new JsonlibJsonWriterConfiguratorTemplate() {&lt;br /&gt;
			@Override&lt;br /&gt;
			public JsonConfig getJsonConfig() {&lt;br /&gt;
				JsonConfig config = new JsonConfig();&lt;br /&gt;
&lt;br /&gt;
				// Exclude all date properties&lt;br /&gt;
				config.setJsonPropertyFilter(new PropertyFilter() {&lt;br /&gt;
					public boolean apply(Object source, String name, Object value) {&lt;br /&gt;
						if (value != null &amp;amp;&amp;amp; Date.class.isAssignableFrom(value.getClass())) {&lt;br /&gt;
							return true;&lt;br /&gt;
						}&lt;br /&gt;
						return false;&lt;br /&gt;
					}&lt;br /&gt;
				});&lt;br /&gt;
				return config;&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
	}&lt;br /&gt;
......&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Spring MVC Annotation의 장점과 단점==&lt;br /&gt;
&lt;br /&gt;
===장점===&lt;br /&gt;
*XML 설정파일에 대한 설정을 최소화할 수 있다.&lt;br /&gt;
*설정방법이 단순하다.&lt;br /&gt;
*관리해야 하는 XML 설정파일의 개수가 감소한다.&lt;br /&gt;
*대상 클래스에서 Auto Completion을 통한 구현이 가능하다.&lt;br /&gt;
*개발자가 설정되는 대상 클래스와 메소드에 대한 정확한 이해(매핑, 파라미터, 모델, 폼 등) 후 적용하므로 유지보수 및 관리가 용이해 진다.&lt;br /&gt;
*개발자적 입장에서 보았을 때, 보기 명확하며 편안하다.&lt;br /&gt;
&lt;br /&gt;
===단점===&lt;br /&gt;
*Java1.5 이상의 환경에서 지원된다.&lt;br /&gt;
*XML 설정파일에서 제공되는 다양한 property 설정이 불가능하다.&lt;br /&gt;
*Annotation의 적절한 사용을 위한 진입장벽이 발생한다. (Learning Curve: 일정 기간의 학습이 필요함)&lt;br /&gt;
*Annotation의 내부 구조 이해가 어렵다.&lt;br /&gt;
*현재까지 Annotation 사용을 위한 Reference가 부족하다.&lt;br /&gt;
&lt;br /&gt;
==Spring MVC Blog 예제 다운로드==&lt;br /&gt;
*SpringMVC + springframework + Hibernate3으로 이루어진 예제이다.&lt;br /&gt;
*[[media:blog_annotation.zip|Spring MVC Blog 예제 다운로드]]&lt;br /&gt;
*데이터베이스는 hsql을 사용하였다. 예제를 실행시키기 전에 data 폴더안의 server.bat 파일을 먼저 실행시켜 데이터베이스를 띄워야한다. &lt;br /&gt;
{{정보|&lt;br /&gt;
*예제 실행을 위해서는 JDK, 이클립스, 톰캣 등의 개발환경이 필요하다. ([[개인 개발환경]] 참고) &lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
*(참고) [[Annotation|Springframework와 관련된 Annotation]]&lt;br /&gt;
*(참고) [[어노테이션 기반 설정|annotation 기반 설정(component-scan 등)]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==참고자료==&lt;br /&gt;
*[http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html Spring Web MVC Framework]&lt;/div&gt;</description>
			<pubDate>Tue, 24 Jun 2008 05:26:30 GMT</pubDate>			<dc:creator>Stardust</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Spring_MVC_Annotation</comments>		</item>
		<item>
			<title>Spring MVC Basic</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Spring_MVC_Basic</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* Spring MVC 소개 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{팁|&lt;br /&gt;
*산출물:   Spring MVC 개요&lt;br /&gt;
*작성자:   나윤주&lt;br /&gt;
*최초작성일 : 2008/06/23&lt;br /&gt;
*최종작성일 : 2008/06/27&lt;br /&gt;
'''Copyright © 2008 Daewoo Information Systems Co., Ltd.'''&lt;br /&gt;
}}&lt;br /&gt;
{{정보|&lt;br /&gt;
*이 문서는 Spring Framework에서 제공되는 Web MVC Framework인 Spring MVC에 관한 것입니다. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Spring MVC 소개==&lt;br /&gt;
*Web MVC framework은 Spring Reference의 Chapter 13. Web MVC framework에서 언급한 대로 다음과 같은 설계사상을 가지고 있다.&lt;br /&gt;
**'Spring's Web MVC framework is designed around a DispatcherServlet that dispatches requests to handlers, with configurable handler mappings, view resolution, locale and theme resolution as well as support for upload files.' (원문: http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html). Web MVC framework는 Request를 Handler에 전달하는 역할을 담당하는 DispatcherServlet과 연동하는 구성요소로 설계된다.&lt;br /&gt;
**그 요소는 설정이 가능한 handler mapping, view resolution, locale and theme resolution 그리고 파일업로드를 지원하는 요소로 구성된다.&lt;br /&gt;
**'''설계의 핵심사상은 최소의 설정으로 패턴화된 다양한 Mapper, Handler 그리고 View를 제공하는 것'''으로서 간단한 설정을 통해 다양한 Request를 mapping하는 Mapper와 mapping된 Request를 처리하는 Handler, 그리고 비즈니스 모듈을 통해 처리된 컨텐츠를 다양한 View로 처리할 수 있는 기반을 제공한다.&lt;br /&gt;
*다음 그림은 SpringMVC의 설계사상을 기반으로 구성된 대상 클래스의 Lifecycle과 처리흐름을 나타낸다.&lt;br /&gt;
&lt;br /&gt;
[[그림:springMVCArchitecture.jpg|700px|thumb|Spring web MVC Framework의 Lifecycle과 workflow|center]]&lt;br /&gt;
&lt;br /&gt;
*Spring web MVC Framework는 기존에 사용되는 Struts, Servlet 등과 같이 웹 어플리케이션의 Presentation Tier에 적용된다. Spring web MVC Framework는 웹 어플리케이션 개발에서 구현과 설정을 간결하고 유연성있게 해준다. &lt;br /&gt;
*Struts와 비교해 보았을때, Struts의 Action 맵핑 대신 CommandController, FormController, MultiActionController 등 상황에 맞는 Controller를 사용할 수 있다. 또한, Java 5+ 이상에서는 annotation을 사용할 수 있어, 설정을 최소화 할 수 있게 해준다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Controller종류&lt;br /&gt;
    * AbstractCommandController : Request 파라미터를 가진 commond 객체를 활용할 경우에 사용한다.&lt;br /&gt;
    * MultiActionController : 동일 클래스에서 다양한 이름의 메소드를 정의하고 맵핑하는 경우에 사용한다.&lt;br /&gt;
    * SimpleFormController: 정의된 다중 form을 처리할 때 사용한다.&lt;br /&gt;
    * AbstractWizardFormController: wizard를 처리할 때 사용한다.&lt;br /&gt;
          o method : onBind(), validatePage(), getTargetPage()&lt;br /&gt;
          o parameter : _target,_finish,_cancel,_page&lt;br /&gt;
    * AbstractFormController: Simple과 AbstractWizardFormController의 부모 클래스로, 사용하기 위해서 프로그래밍을 통해 before/after view 이름이 설정되어야 한다.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Spring MVC의 동작==&lt;br /&gt;
[[그림:springMVCworkflow.png|600px|thumb|Spring web MVC Framework의 workflow|center]]&lt;br /&gt;
&lt;br /&gt;
*Spring web MVC Framework는 크게 Dispatcher Servlet, Controller, View Template로 구성되어 있다. ([http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html Spring Reference] 참고)&lt;br /&gt;
&lt;br /&gt;
===Dispatcher Servlet===&lt;br /&gt;
*Spring web MVC Framework의 Dispatcher Servlet은 다른 web MVC Framework와 마찬가지로 사용자의 요청을 url에 따라 정의된 Controller에 전달하고 요청에 따른 결과를 사용자에게 보여주는 역할을 한다.&lt;br /&gt;
*Dispatcher servlet은 org.springframework.web.servlet.DispatcherServle에 의해 표현되며, 클라이언트 요청을 처리하기 위한 Front Controller Design Pattern이다.&lt;br /&gt;
*클라이언트에서 요청한 모든 URL에 대하여 이 서블릿은 클라이언트의 Request가 Controller에 가기전에 해당 Request를 가로챈다.&lt;br /&gt;
*Web Configuration File은 Dispatcher Servlet이 클라이언트의 Request에 대하여 invoked 되도록 정의되어 있다.&lt;br /&gt;
*Web Configuration File인 web.xml에서 서블릿 맵핑을 시켜줌으로써 사용할 수 있다.&lt;br /&gt;
**아래의 코드와 같이 설정할 경우, &amp;lt;servlet-name&amp;gt;과 맵핑되는 blog-servlet.xml 파일이 요청되며, *.do의 url 요청은 모두 DispatcherServlet을 거치게 된다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;servlet&amp;gt;&lt;br /&gt;
	&amp;lt;servlet-name&amp;gt;blog&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
	&amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
	&amp;lt;load-on-startup&amp;gt;2&amp;lt;/load-on-startup&amp;gt;&lt;br /&gt;
&amp;lt;/servlet&amp;gt;&lt;br /&gt;
&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
	&amp;lt;servlet-name&amp;gt;blog&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
	&amp;lt;url-pattern&amp;gt;*.do&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
&amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*blog-servlet.xml은 빈으로 등록하는 url과 맵핑되는 Controller를 지정해주는 역할을 하게 된다.&lt;br /&gt;
**예제코드에서 보는 것과 같이 /createBlog.do라는 url로 접근을 하면, blog.web.CreateBlogController 클래스의 메소드가 실행된다.&lt;br /&gt;
**지정된 Controller 클래스는 Controller 인터페이스 또는 특정 Controller 클래스를 상속된다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;beans xmlns=&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;br /&gt;
		xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
		xmlns:p=&amp;quot;http://www.springframework.org/schema/p&amp;quot; &lt;br /&gt;
		xmlns:context=&amp;quot;http://www.springframework.org/schema/context&amp;quot;&lt;br /&gt;
		xsi:schemaLocation=&amp;quot;http://www.springframework.org/schema/beans &lt;br /&gt;
			http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&lt;br /&gt;
			http://www.springframework.org/schema/context&lt;br /&gt;
			http://www.springframework.org/schema/context/spring-context-2.5.xsd&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;!-- the application context definition for the blog DispatcherServlet --&amp;gt;&lt;br /&gt;
	&amp;lt;bean name=&amp;quot;/createBlog.do&amp;quot; class=&amp;quot;blog.web.CreateBlogController&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;bean name=&amp;quot;/findBlogs.do&amp;quot; class=&amp;quot;blog.web.FindBlogsController&amp;quot;/&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
&amp;lt;/beans&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====다중 DispatcherServlet 적용하기====&lt;br /&gt;
&lt;br /&gt;
*클라이언트의 Request에 대한 다양한 servlet-mapping을 제공하기 위해 다중 DispatcherServlet 클래스를 등록하고 매핑정보를 web.xml에 설정한다.&lt;br /&gt;
*예를 들어, JstlView(JSP에서 JSTL을 활용하는 경우)와 JsonView(Ext-js에서 JSON을 활용하는 경우)를 동시에 하나의 웹 어플리케이션에서 활용하는 경우, 다음과 같이 설정하여 적용할 수 있다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;servlet&amp;gt;&lt;br /&gt;
	&amp;lt;servlet-name&amp;gt;blog&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
	&amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
&amp;lt;/servlet&amp;gt;&lt;br /&gt;
&amp;lt;servlet&amp;gt;&lt;br /&gt;
	&amp;lt;servlet-name&amp;gt;blog2&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
	&amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;&lt;br /&gt;
&amp;lt;/servlet&amp;gt;&lt;br /&gt;
&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
	&amp;lt;servlet-name&amp;gt;blog&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
	&amp;lt;url-pattern&amp;gt;*.do&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
&amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;
	&amp;lt;servlet-name&amp;gt;blog2&amp;lt;/servlet-name&amp;gt;&lt;br /&gt;
	&amp;lt;url-pattern&amp;gt;*.json&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;
&amp;lt;/servlet-mapping&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Controller===&lt;br /&gt;
*web MVC 모델에서, Controller는 전달받은 사용자의 요청을 서비스로 연결해주는 역할을 한다. 또한, 서비스로부터 받은 요청 결과를 다시 사용자에게 전달해 준다. Spring web MVC Framework의 최상위 Controller는 interface로 제공되고, 각 역할에 따라 Form에 관련된 Controller, command에 관련된 Controller 클래스 등을 제공한다. Controller interface는 ModelAndView 타입의 반환 값을 가지는 handleRequest method를 포함하며, 이 메소드에서 사용자에게 전달할 응답 결과를 ModelAndMap 형태로 하여 반환한다.&lt;br /&gt;
*Web controller를 사용하기 위해서는 xxx-servlet.xml 파일에 controller 등록이 필요하다.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
*'''Controller''' interface의 사용&lt;br /&gt;
**handleRequest 메소드를 override하여, 이 FindBlogController가 해야하는 동작을 정의한다.&lt;br /&gt;
**아래의 코드는 findBlogs.do라는 url 요청이 들어오면 blog.web.FindBlogController 클래스의 handleRequest가 수행된다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- blog-servlet.xml --&amp;gt;&lt;br /&gt;
&amp;lt;bean name=&amp;quot;/findBlogs.do&amp;quot; class=&amp;quot;blog.web.FindBlogController&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;property name=&amp;quot;blogService&amp;quot; ref=&amp;quot;blogService&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* FindBlogController.java */&lt;br /&gt;
/* package 정의 및 import */&lt;br /&gt;
public class FindBlogController implements Controller {&lt;br /&gt;
	private BlogService blogService;             // 서비스 클래스 정의&lt;br /&gt;
&lt;br /&gt;
	public ModelAndView handleRequest(HttpServletRequest request,&lt;br /&gt;
			HttpServletResponse response) throws Exception {&lt;br /&gt;
&lt;br /&gt;
		Collection&amp;lt;Blog&amp;gt; blogList = blogService.findBlogs();&lt;br /&gt;
		return new ModelAndView(&amp;quot;findBlogs&amp;quot;, &amp;quot;blogList&amp;quot;, blogList);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void setBlogService(BlogService blogService) {&lt;br /&gt;
		this.blogService = blogService;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''SimpleFormController''' class의 사용&lt;br /&gt;
**화면의 form 태그와 관련된 동작을 수행할 때 사용한다.&lt;br /&gt;
**formBackingObject 메소드는 form 화면을 보여주기 위한 값 설정에, onSubmit 메소드는 화면의 form 결과를 전달하기 위해 사용한다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;jsp&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- createBlog.jsp --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;form:form name=&amp;quot;blogForm&amp;quot; commandName=&amp;quot;create&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;!-- 중간 생략 --&amp;gt;&lt;br /&gt;
&amp;lt;/form:form&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- blog-servlet.xml --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;bean name=&amp;quot;/createBlog.do&amp;quot; class=&amp;quot;blog.web.CreateBlogFormController&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;property name=&amp;quot;blogService&amp;quot; ref=&amp;quot;blogService&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;property name=&amp;quot;commandClass&amp;quot; value=&amp;quot;blog.model.Blog&amp;quot;/&amp;gt;&lt;br /&gt;
	&amp;lt;property name=&amp;quot;commandName&amp;quot; value=&amp;quot;create&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* CreateBlogFormController.java */&lt;br /&gt;
/* package 정의 및 import */&lt;br /&gt;
public class CreateBlogFormController extends SimpleFormController {&lt;br /&gt;
	private BlogService blogService;             // 서비스 클래스 정의&lt;br /&gt;
	&lt;br /&gt;
	protected ModelAndView onSubmit(Object command) throws Exception {&lt;br /&gt;
		Blog blog = (Blog) command;&lt;br /&gt;
		blogService.createBlog(blog);&lt;br /&gt;
		return new ModelAndView(new RedirectView(&amp;quot;findBlogs.do&amp;quot;));&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	protected Object formBackingObject(HttpServletRequest request)&lt;br /&gt;
			throws Exception {&lt;br /&gt;
		Blog blog = new  Blog();&lt;br /&gt;
		blog.setRegDate(new Date());&lt;br /&gt;
		return blog;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void setBlogService(BlogService blogService) {&lt;br /&gt;
		this.blogService = blogService;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''MultiActionController''' class의 사용&lt;br /&gt;
**하나의 controller 클래스에서 다양한 요청을 처리하기 위해 사용한다.&lt;br /&gt;
**다음과 같은 형태로 메소드를 작성 해야한다.&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
public [ModelAndView | Map | void] anyMeaningfulName(HttpServletRequest, HttpServletResponse [, Exception | AnyObject]);&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
**메소드 이름은 맵핑하고자 하는 url 이름과 같게하여 작성한다.&lt;br /&gt;
**아래의 예제는 위의 FindBlogController 클래스를 변형하여 findBlogs와 deleteBlog를 수행할 수 있게 하였다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- blog-servlet.xml --&amp;gt;&lt;br /&gt;
&amp;lt;bean name=&amp;quot;/findBlogs.do&amp;quot; class=&amp;quot;blog.web.FindBlogController&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;property name=&amp;quot;blogService&amp;quot; ref=&amp;quot;blogService&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;bean name=&amp;quot;/deleteBlog.do&amp;quot; class=&amp;quot;blog.web.FindBlogController&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;property name=&amp;quot;blogService&amp;quot; ref=&amp;quot;blogService&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* FindBlogController.java */&lt;br /&gt;
/* package 정의 및 import */&lt;br /&gt;
public class FindBlogController extends MultiActionController {	&lt;br /&gt;
	private BlogService blogService;             // 서비스 클래스 정의&lt;br /&gt;
&lt;br /&gt;
	public ModelAndView findBlogs(HttpServletRequest request,&lt;br /&gt;
			HttpServletResponse response) throws Exception {&lt;br /&gt;
		Collection&amp;lt;Blog&amp;gt; blogList = blogService.findBlogs();&lt;br /&gt;
		return new ModelAndView(&amp;quot;findBlogs&amp;quot;, &amp;quot;blogList&amp;quot;, blogList);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public ModelAndView deleteBlog(HttpServletRequest request,&lt;br /&gt;
			HttpServletResponse response) throws Exception {&lt;br /&gt;
		blogService.deleteBlog(Integer.parseInt((String)request.getParameter(&amp;quot;blogId&amp;quot;)));&lt;br /&gt;
		return new ModelAndView(new RedirectView(&amp;quot;findBlogs.do&amp;quot;));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	public void setBlogService(BlogService blogService) {&lt;br /&gt;
		this.blogService = blogService;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===View Template===&lt;br /&gt;
*사용자의 요청을 Controller에 전달하고, 또 Controller에서 전달받은 응답 결과를 화면에 보여주기 위해, spring form 태그와 jstl 태그 등을 사용하여 View 페이지를 작성 할 수 있다.&lt;br /&gt;
&lt;br /&gt;
==Spring MVC의 예외처리==&lt;br /&gt;
*Spring MVC에서 제공하는 예외처리는 발생하는 예외에 따라 적절한 에러 페이지를 보여주고 싶을 때 사용할 수 있다.&lt;br /&gt;
**springframework의 샘플 코드 중 아래의 petclinic 예제에서는 DataAccessException 또는 TransactionException가 발생할 경우 dataAccessFailure.jsp 페이지로 예외를 넘겨준다.&lt;br /&gt;
*HandlerExceptionResolvers interface를 구현하여 사용자 예외를 직접 처리 할 수 있고, SimpleMappingExceptionResolver class를 사용하여 이미 정의된 예외에 대한 처리를 할 수 있다.&lt;br /&gt;
&amp;lt;code lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!-- petclinic-servlet.xml of springframework petclinc sample code --&amp;gt;&lt;br /&gt;
&amp;lt;bean class=&amp;quot;org.springframework.web.servlet.handler.SimpleMappingExceptionResolver&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;property name=&amp;quot;exceptionMappings&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;props&amp;gt;&lt;br /&gt;
			&amp;lt;prop key=&amp;quot;org.springframework.dao.DataAccessException&amp;quot;&amp;gt;dataAccessFailure&amp;lt;/prop&amp;gt;&lt;br /&gt;
			&amp;lt;prop key=&amp;quot;org.springframework.transaction.TransactionException&amp;quot;&amp;gt;dataAccessFailure&amp;lt;/prop&amp;gt;&lt;br /&gt;
		&amp;lt;/props&amp;gt;&lt;br /&gt;
	&amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Spring MVC Blog 예제 다운로드==&lt;br /&gt;
*SpringMVC + springframework + Hibernate3으로 이루어진 예제이다.&lt;br /&gt;
*[[media:blog2.zip|Spring MVC Blog 예제 다운로드]]&lt;br /&gt;
*데이터베이스는 hsql을 사용하였다. 예제를 실행시키기 전에 data 폴더안의 server.bat 파일을 먼저 실행시켜 데이터베이스를 띄워야한다.&lt;br /&gt;
{{정보|&lt;br /&gt;
*예제 실행을 위해서는 JDK, 이클립스, 톰캣 등의 개발환경이 필요하다. ([[개인 개발환경]] 참고) &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==참고자료==&lt;br /&gt;
*[http://www.springframework.org Springframework]&lt;br /&gt;
*[http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html Spring Web MVC Framework]&lt;br /&gt;
*[http://www.habuma.com/spring/SpringMVCandSecurity.pdf Spring MVC &amp;amp; Spring Security]&lt;br /&gt;
*[http://www.flickr.com/photos/60896767@N00/89101625/sizes/l/ Spring MVC Request LifeCycle 그림]&lt;/div&gt;</description>
			<pubDate>Mon, 23 Jun 2008 08:34:06 GMT</pubDate>			<dc:creator>Stardust</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Spring_MVC_Basic</comments>		</item>
		<item>
			<title>Ext-JS CRUD</title>
			<link>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Ext-JS_CRUD</link>
			<description>&lt;p&gt;바꾼내용 간추리기: /* 저장하기 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Ext-js기반의 CRUD만들기=&lt;br /&gt;
==조회하기==&lt;br /&gt;
*js파일의 findData함수&lt;br /&gt;
&amp;lt;code lang='javascript'&amp;gt;&lt;br /&gt;
function findData() {&lt;br /&gt;
	&lt;br /&gt;
	params = &amp;quot;{&amp;quot; &lt;br /&gt;
		+ 'deptCoder:\&amp;quot;' + Ext.get('shDeptCode').dom.value + &amp;quot;\&amp;quot;,&amp;quot;&lt;br /&gt;
           	+ 'deptNamer:\&amp;quot;' + Ext.get('shDeptName').dom.value + &amp;quot;\&amp;quot;,&amp;quot;&lt;br /&gt;
           	+ 'custCoder:\&amp;quot;' + Ext.get('shCustCode').dom.value + &amp;quot;\&amp;quot;&amp;quot;&lt;br /&gt;
           	+ &amp;quot;}&amp;quot;&lt;br /&gt;
           	&lt;br /&gt;
		Ext.Ajax.request({&lt;br /&gt;
		    url: '/mdms/deptInfo/findDeptSpecs.action',&lt;br /&gt;
		    jsonData: params,&lt;br /&gt;
		    headers: {&lt;br /&gt;
            	'Content-Type': 'application/json'&lt;br /&gt;
        	},		               &lt;br /&gt;
		    success: function( r, o ) {&lt;br /&gt;
		    	alert(r.responseText);	    	&lt;br /&gt;
		    	try {&lt;br /&gt;
		    		specStore.loadData(Ext.decode(r.responseText));&lt;br /&gt;
		    	&lt;br /&gt;
		    	} catch(e) {&lt;br /&gt;
		    	}&lt;br /&gt;
	    	},&lt;br /&gt;
			failure: function( r, o ) {&lt;br /&gt;
			alert(&amp;quot;ERR&amp;quot;+r.responseText);&lt;br /&gt;
			}&lt;br /&gt;
		})&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*struts.xml&lt;br /&gt;
&amp;lt;code lang='xml'&amp;gt;&lt;br /&gt;
&amp;lt;action name=&amp;quot;findDeptSpecs&amp;quot; class=&amp;quot;com.daewoobrenic.dsom.mm.action.DeptInfoAction&amp;quot; method=&amp;quot;findDeptSpecs&amp;quot;&amp;gt;	&lt;br /&gt;
		&amp;lt;/action&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
*action&lt;br /&gt;
&amp;lt;code lang='java'&amp;gt;&lt;br /&gt;
	public String findDeptSpecs() {&lt;br /&gt;
&lt;br /&gt;
		deptMasts = new ArrayList();&lt;br /&gt;
		Map searchMap = (Map) InChannel.getVariables();&lt;br /&gt;
		deptMasts.add(deptInfoService.viewDeptMast(searchMap));&lt;br /&gt;
		deptSpecs = deptInfoService.viewDeptSpecs(searchMap);&lt;br /&gt;
		OutChannel.setDataSet(&amp;quot;deptSpecs&amp;quot;, deptSpecs);&lt;br /&gt;
		OutChannel.send();&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==추가/삭제(그리드 적용시)==&lt;br /&gt;
*그리드에서 셀추가는 화면에서만 이루어지는 것이므로 js파일만 다음과 같이 작성 하면된다.&lt;br /&gt;
**추가)EditorGridPanel에 tbar로 그리드에 '''추가''' 버튼 넣고 insertHandler함수 호출하기&lt;br /&gt;
***insertHandler&lt;br /&gt;
&amp;lt;code lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
	function insertHandler(btn) { &lt;br /&gt;
			var code = new Code({ //초기값 셋팅&lt;br /&gt;
        	flag: 'insert',&lt;br /&gt;
            id: ' ',&lt;br /&gt;
            name: '',&lt;br /&gt;
            inUse: '사용', &lt;br /&gt;
            parentId: '',&lt;br /&gt;
            description: '',&lt;br /&gt;
            indoor: false&lt;br /&gt;
        });&lt;br /&gt;
		  gridForm.stopEditing();&lt;br /&gt;
                 codeStore.insert(0, code); &lt;br /&gt;
              gridForm.startEditing(0, 0);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
**삭제)EditorGridPanel에 tbar로 그리드에 '''삭제''' 버튼 넣고 공통 스트립트의 deleteGridRow함수에 EditorGridPanel 넘기면 삭제완료&lt;br /&gt;
** 그리드 부분 소스&lt;br /&gt;
&amp;lt;code lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
 var gridForm = new Ext.grid.EditorGridPanel({&lt;br /&gt;
		id: 'company-form',&lt;br /&gt;
        store: codeStore,&lt;br /&gt;
        cm: colModel,&lt;br /&gt;
         sm: sm,&lt;br /&gt;
     	renderTo: 'upperWork_grid', &lt;br /&gt;
    	autoExpandColumn: 'desc',&lt;br /&gt;
        width:700,&lt;br /&gt;
        autoWidth: true,&lt;br /&gt;
        height:350,&lt;br /&gt;
        title:'CI 분류목록',&lt;br /&gt;
        clicksToEdit:2,&lt;br /&gt;
        frame:true,&lt;br /&gt;
        bbar: new Ext.PagingToolbar({&lt;br /&gt;
            pageSize: 10,&lt;br /&gt;
            store: codeStore,&lt;br /&gt;
            displayInfo: true,&lt;br /&gt;
            displayMsg: 'Displaying topics {0} - {1} of {2}',&lt;br /&gt;
            emptyMsg: &amp;quot;No topics to display&amp;quot;&lt;br /&gt;
        }),&lt;br /&gt;
       	tbar: [{&lt;br /&gt;
				text: '추가',&lt;br /&gt;
				handler: insertHandler,//함수호출&lt;br /&gt;
				iconCls: 'blist'&lt;br /&gt;
			}, {&lt;br /&gt;
				text: '삭제',&lt;br /&gt;
				     handler : function(){&lt;br /&gt;
                  deleteGridRow(gridForm);&lt;br /&gt;
                 },&lt;br /&gt;
				iconCls: 'blist'&lt;br /&gt;
			}]         &lt;br /&gt;
    });            &lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==저장하기==&lt;br /&gt;
*화면에서 저장 버튼을 누르면  화면에서만 입력과 수정, 삭제되었던 데이터들이 한꺼번에 서버에 날라가고 서비스에 각각 해당되는 Dao를 호출한다.&lt;br /&gt;
**js파일이 saveData()&lt;br /&gt;
&amp;lt;code lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
	function saveData() {&lt;br /&gt;
		var param = createGridData(codeStore);&lt;br /&gt;
	    param = &amp;quot;{&amp;quot; +  '&amp;quot;codeList&amp;quot;:' + param + &amp;quot;}&amp;quot; //codeList은 action에서 받는 dataSet이름&lt;br /&gt;
		Ext.Ajax.request({&lt;br /&gt;
	    	url: '/dsom/comCode/saveComCodeList.action',&lt;br /&gt;
	    	jsonData: param,&lt;br /&gt;
		    headers: {&lt;br /&gt;
            	'Content-Type': 'application/json'&lt;br /&gt;
        	},&lt;br /&gt;
	    	success: function( r, o ) {&lt;br /&gt;
	    		setMessage(&amp;quot;success&amp;quot;);&lt;br /&gt;
	    		codeStore.commitChanges();&lt;br /&gt;
			},&lt;br /&gt;
			failure: function( r, o ) {&lt;br /&gt;
			setMessage(&amp;quot;ERR&amp;quot;);&lt;br /&gt;
			}&lt;br /&gt;
		})&lt;br /&gt;
		&lt;br /&gt;
	}&lt;br /&gt;
	&amp;lt;/code&amp;gt;&lt;br /&gt;
**action의 saveComCodeList()&lt;br /&gt;
***InChannel.getDataSetList메소드에 해당되는 모델 클래스(Code.class), 와 js파일에서 넘긴 dataSet(codeList) 넘김&lt;br /&gt;
&amp;lt;code lang='java'&amp;gt;&lt;br /&gt;
	public String saveComCodeList(){&lt;br /&gt;
		codeList = new ArrayList();&lt;br /&gt;
		codeList = InChannel.getDataSetList(Code.class, &amp;quot;codeList&amp;quot;);&lt;br /&gt;
		codeService.saveComCodeList(codeList);&lt;br /&gt;
		return null;	&lt;br /&gt;
	}&lt;br /&gt;
	&amp;lt;/code&amp;gt;&lt;br /&gt;
**service의 saveComCodeList()&lt;br /&gt;
***받은 list를 for으로 돌려 insert, update, delete 중에 해당되는 Dao를 호출함.&lt;br /&gt;
&amp;lt;code lang='java'&amp;gt;&lt;br /&gt;
	public void saveComCodeList(List codeList) {&lt;br /&gt;
		// TODO Auto-generated method stub&lt;br /&gt;
		// Flag로 수정인지 조회인지, 삭제인지 파악&lt;br /&gt;
		for (int i = 0; i &amp;lt; codeList.size(); i++) {&lt;br /&gt;
			code = (Code) codeList.get(i);&lt;br /&gt;
			System.out.println(code.getFlag());&lt;br /&gt;
			if (Constant.USER_STATUS_INSERT.equalsIgnoreCase(code.getFlag()))&lt;br /&gt;
				codeDao.createCode(code);&lt;br /&gt;
			else if (Constant.USER_STATUS_UPDATE.equalsIgnoreCase(code&lt;br /&gt;
					.getFlag()))&lt;br /&gt;
				codeDao.updateCode(code);&lt;br /&gt;
			else if (Constant.USER_STATUS_DELETE.equalsIgnoreCase(code&lt;br /&gt;
					.getFlag()))&lt;br /&gt;
				codeDao.deleteCode(code.getId());&lt;br /&gt;
			else&lt;br /&gt;
				throw new BusinessException(&amp;quot;Row Status&amp;quot; + code.getFlag()&lt;br /&gt;
						+ &amp;quot; is not appropriate.&amp;quot;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
	&amp;lt;/code&amp;gt;&lt;/div&gt;</description>
			<pubDate>Mon, 23 Jun 2008 01:02:59 GMT</pubDate>			<dc:creator>Alsdkzz</dc:creator>			<comments>http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/%ED%86%A0%EB%A1%A0:Ext-JS_CRUD</comments>		</item>
	</channel>
</rss>