반응형

국세청 전자세금계산서   http://www.esero.go.kr/    

싸이빌  http://cybill.co.kr/  월 50건무료. 200건 11,000원.  무제한 22,000원 . 기업연동 및 구축전문

얼마에요  http://www.tax2tax.co.kr    70건 1만원/ 140건 2만원/ 기간제한은 없슴.

이지폼   http://www.easyform.co.kr   건당  일반 200원,  회원 110원.

KT 세무로   http://semuro.com 1건에서30건까지는건당300원,31건에서60건까지는200원61건

이상은150원

스피드빌  http://www.speedbill.co.kr/  매월20건4,000원[초과건당300원],매월 50건

10,000원[초과건당 220원]

트루비즈   http://www.truebiz.co.kr/   월 30회- 5천원/ 월60회 -1만원/ 월100회- 1만5

천원/ 월10회이하 년 3만원/

다이렉트 빌   http://directbill.co.kr     월1만원 - 무제한 발송/ 월 30건 5천원/

메이크빌  http://www.makebill.co.kr 월 10건-년3만원/월25건-년5만원/월50건-매월1만원/

월500건-매월 9만원

LG데이콤  http://www.webtax21.com   월 50건 - 월1만원/ 추가 건당 200원/

sERP /WEBcash   http://www.taxbill365.com/   건당 100원/

IT 경영연구소   http://www.erpm.kr/   월  3만원. 프로그램안에서 발송

가비아빌  http://www.gabiabill.com/   월 1만원 - 무제한 발송

엔택스  http://www.entax.co.kr   [무료회계프로그램]   건당 50원/

이지스 효성   http://www.allthegate.com    건당 500원/ 포인트충전후 차감방식

바로빌 http://www.barobill.co.kr/  (한달10건-3,300원/30건-5,500원/50건-9,900원)요금

제 이용안할시1건-550원

한국무역정보통신   http://www.ktneterp.co.kr   ERP사용료 4만원에 전자세금계산서 포함

예정.


반응형

'개발도 하냐?' 카테고리의 다른 글

자동화 빌드도구 ANT  (0) 2009.11.04
JEUS 설정  (0) 2009.11.04
Anyframe Doc  (0) 2009.09.16
JSP_MVC 형식  (0) 2009.09.16
Eclipse + JEUS  (0) 2009.08.19
반응형

국내는 active x 방식이 대다수라 판단됩니다.

================= active X =======================================================================

Shift Soft :  GAUCE
                 초기 x-internet 대안 솔루션이 없을 경우 선두에서 많은 솔루션을 납품.
                 그리드 통계나 undo기능등은 인상적이었으나, report 기능과 복잡한 스크립트가 단점
      

tobe soft : MIFlaform
                GAUCE를 만든 핵심멤버가 만든  솔루션.
                빌더형식의 IDE툴이 존재하며,
                한번 개발한 애플리케이션을 Web, C/S는 물론 Mobile 환경(PDA)에서
                동시에 사용가능
                x-internet 대안으로 좋은 평가를 받고 있습니다.

아이비 리더스 : IBSheet (http://www.ibleaders.co.kr)
                역시 x-internet 제품으로 직접 코딩한적은 없지만, 개발 완료물은 상당한 완성도를 보여주었습니다.


국내 그리드 컴포넌트 중에서는 IBSheet가 최고라는 평을 받고있으며
직접 써본신 분들의 이야기를 빌리자면, 맥시멈 생산성이 나오기까지의 시간이 조금 걸리긴 하나
매뉴얼이 잘 되어 있으며, 보름정도 학습하고 코딩을 병행한다면 상당히 빠른 개발을 할 수 있다고 합니다.


다음은 현재 트랜드에 따라 ACTIVE x를 지양(비스타,보안문제)하는 제품(AJAX)들입니다.

Ntobi Grid (www.nitobi.com/products/grid/)
                   GRID기능이 강력.
                   copy & paste : EXCEL데이터를 전체선택해 그리드에 바로붙이는 기능.(또는 반대)
                   몇개의 샘플은 익스플로어를 다운시키는 심각한 버그발견

dojo ToolKit : 간단한 예제와 최적화가 잘되어있어 손쉽게 배울수있음. 디자인은 조금 손봐야..

EXT (YUI) http://extjs.com/               
             : 모듈형식으로 제작되어 쉽게 커스터마이징이 가능함.
               UI또한 미려합니다.

 

이상으로 간단하게 개인적인 의견을 써봤습니다.

PS : 외국 AJAX Tool들의 대세는 fish eye인가...;;
반응형

'삽질로그' 카테고리의 다른 글

오랜만에 find 쓸일이 생겨서..  (0) 2009.11.23
HTML 테이블 CSS  (0) 2009.11.04
ADOBE FLEX Builder 3 CDKEY  (0) 2009.08.31
DNS 서버  (0) 2009.08.02
태그클라우드 만들기  (3) 2009.07.31
반응형

 

Anyframe Java

 

 

Template Guide

 

 

 

 

 

 

Anyframe Java

Ver. 3.2.0

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Preface

문서는 Anyframe Template 대한 내용을 담고 있으며, 작성자나 검증자의 실수로 인해 오류가 있을 수도 있음에 양해를 구합니다. 문서에 심각한 오류가 있다고 판단될 경우 Anyframe 포럼에 등록해 주시면 담당자가 적절한 조치를 취할 있도록 것입니다. 문서는 개인적인 용도로 사용될 있으며, 다른 사람에게 배포되어야 하는 경우 반드시 이와 같은 Copyright Notice 포함하도록 합니다. 내용에 대한 자유로운 추가 수정 작업은 허용하나, 문서의 상업적인 사용은 허용하지 않습니다. 상업적 사용시 반드시 Anyframe Portal Site 통해 요청하셔야 함에 유의하시기 바랍니다.

 

 

Copyright 2008, www.anyframejava.org - Site maintained by SAMSUNG SDS

 

 

제 1 장    개 요    5

1.1 목 적    5

1.2 유의사항    5

제 2 장    설치하기    6

2.1 설치 환경    6

2.2 Template 설치    6

2.2.1 Basic Template설치    6

2.2.2 MiPlatform Template설치    7

2.3. Template실행    9

제 3 장    Basic Template 소개    11

3.1. 개 요    11

3.2. 구 현    11

3.2.1. 비즈니스 레이어    11

3.2.2. 프리젠테이션 레이어    13

제 4 장    MiPlatform Template 소개    15

4.1. 개요    15

4.2. 구 현    15

4.2.1. 비즈니스 레이어    15

4.2.2. 프리젠테이션 레이어    17

제 5 장    Base Framework    19

5.1. Spring IoC    19

5.2. Spring AOP    20

5.3. Hibernate    23

5.4. Query 서비스    26

5.5. MiPQueryService    28

5.6. Spring MVC    30

5.7. MiPlatform    34

5.8. 기타    36

별첨-1. 주요 클래스 다이어그램 Category @Basic Template    38

별첨-2. 주요 클래스 다이어그램 Category @MiPlatform Template    39

제 1 장    개 요

1.1 목 적

Anyframe Java에 대한 대표적인 적용 방안을 제시함으로써 Anyframe Java를 기반으로 어플리케이션을 개발하는 프로젝트에 효과적인 개발구조 가이드를 제시하고 개발 초기에 해당 프로젝트에서 개발 템플릿을 정의하는데 소요되는 시간을 줄이고자 구현 기준 샘플 프로젝트를 Template으로 제공하고, 설치에서부터 구현 기능 및 활용 서비스에 대한 설명을 하고자 한다.

Anyframe Java 3.2.0 (jdk 1.4)은 다음과 같이 기본 템플릿과 MiPlatform 템플릿 두 가지로 제공된다. 또한 기본 템플릿은 웹 어플리케이션에 따라 두 가지로 나뉜다.

 

  • 기본 템플릿
    • 서비스 어플리케이션 : Spring 기반, QueryService, Hibernate를 이용한 DB Access Layer
    • 웹 어플리케이션
      • SpringMVC 기반, JSP를 이용하여 구현
      • Struts 기반, JSP를 이용하여 구현
  • MiPlatform 템플릿
    • 서비스 어플리케이션 : Spring 기반, MiPQueryService를 이용한 DB Access Layer
    • 웹 어플리케이션 : SpringMVC 기반, MiPlatform을 이용하여 구현

 

1.2 유의사항

문서에서 사용된 코드와 아키텍처 스타일은 다양한 프레임워크 기능의 사용예와 아키텍처의 유연성을 고려한 샘플이며 성능에 최적화되어 제공하는 것은 아니므로 실제로 프레임워크를 적용하여 프로젝트 수행 디자인 코드와 성능에 대한 여러 요구 사항들(주로 비기능적인 요구조건) 적절히 고려하여 어플리케이션을 구축하여야 한다

 

제 2 장    설치하기

2.1 설치 환경

JDK: JDK 1.4.2 이상

Web Container: Tomcat 5.0.28 이상, WebLogic 8.1.6 이상

DataBase: HSQL DB 1.8.0.4 이상, Oracle 8i 이상

IDE : Eclipse 3.3 이상(프레임워크에서 제공하는 플러그인이 포함된 Eclipse 권장)

Anyframe : Anyframe Core / Web 3.2.0 이상

Anyframe 설치는 Anyframe Portal Site의 설치문서 참고

※ MiPlatform의 경우 MiPlatform 클라이언트 프로그램이 설치되어야 한다. MiPlatform은 상용프로그램이므로 사용자가 S/W를 구입하여 설치하였다고 가정한다.

2.2 Template 설치

2.2.1 Basic Template설치

  • 압축파일 해제
    - 적당한 폴더를 선택하여 템플릿 압축 해제 실시
    à [템플릿 압축해제 폴더]
  • Eclipse 실행
  • 프로젝트 Import
  1. Eclipse 메뉴의 File – Import 선택
  2. Existing Projects into Workspace 선택 후 Next 버튼 클릭
  3. Select root directory의 Browse버튼 클릭 하고 [템플릿 압축해제 폴더] 선택
  4. 하단 Projects 리스트에서 "anyframe-template-service", "anyframe-template-web-struts", "anyframe-template-web-springmvc"를 선택하고 Finish 버튼 클릭
  • 라이브러리 설정
  1. Anyframe Core와 Web 설치 폴더의 모든 jar 파일을 [템플릿 압축해제 폴더]/anyframe-template-web-struts/src/webapp/WEB_INF/lib와 [템플릿 압축해제 폴더]/anyframe-template-web-springmvc/src/webapp/WEB_INF/lib로 복사
  2. Eclipse 메뉴의 Window – Preferences선택
  3. 좌측의 트리 메뉴에서 Java – Build Path – User Libraries 선택
  4. New 버튼 클릭하고 User Library Name에 'TEMPLATE_LIB' 입력
  5. 우측의 Add JARs 버튼을 클릭하여 Anyframe Core와 Web 설치 폴더의 모든 jar 파일을 선택
  • Web Container 설정
  1. Eclipse 메뉴의 Window – Preferences선택
  2. 좌측의 트리 메뉴에서 Server – Installed Runtimes 선택
  3. Add 버튼 클릭하고 Apache Tomcat 5.0 선택하고 Next 버튼 클릭
  4. Browse 버튼을 클릭하여 설치된 Tomcat Root 폴더를 선택

    ※ Eclipse의 default JRE 버전이 JDK 1.4일 경우 Tomcat 5.0을,

JDK 1.5일 경우 Tomcat 5.5 버전을 사용한다.

 

  • 사용자 환경에 맞추어 서비스 배포
  1. Eclipse에서 anyframe-template-service프로젝트의 build.xml파일을 열어서 anyframe.lib의 위치를 Anyframe Core와 Web 설치 폴더로 변경
    (artifacts.dir 변수는 오픈 소스 자바 코드 코드커버리지 툴킷인 emma를 사용하기 위한 변수로, emma를 통해 생성되는 리포트 파일이 만들어질 위치이다.)
  2. Eclipse의 Package Explorer에서 build.xml을 선택하고 마우스 오른쪽 버튼을 클릭하여 Run As – Ant Build를 선택하고 all target을 선택하여 Run 버튼 클릭

※ 템플릿을 구성하는 서비스 코드 및 속성 정의가 변경 됐을 경우 all target을 실행시키면 자신의 환경에 수정 내용을 배포할 수 있다.

※ Junit 테스트와 emma를 통한 리포팅을 모두 적용하려면 test target을 실행시키면 된다.

2.2.2 MiPlatform Template설치

  1. 압축파일 해제
    - 적당한 폴더를 선택하여 템플릿 압축 해제 실시
    à [템플릿 압축해제 폴더]
  2. Eclipse 실행
  3. 프로젝트 Import
    1. Eclipse 메뉴의 File – Import 선택
    2. Existing Projects into Workspace 선택 후 Next 버튼 클릭
    3. Select root directory의 Browse버튼 클릭 하고 [템플릿 압축해제 폴더] 선택
    4. 하단 Projects 리스트에서 "anyframe-template-mi-service","anyframe-template-mi-web"를 선택하고 Finish 버튼 클릭

     

  4. 라이브러리 설정
    1. Anyframe Core와 Web 설치 폴더의 모든 jar 파일을 [템플릿 압축해제 폴더]/anyframe-template-mi-web/src/webapp/WEB_INF/lib로 복사
    2. Eclipse 메뉴의 Window – Preferences선택
    3. 좌측의 트리 메뉴에서 Java – Build Path – User Libraries 선택
    4. New 버튼 클릭하고 User Library Name에 'TEMPLATE_LIB' 입력
    5. 우측의 Add JARs 버튼을 클릭하여 Anyframe Core와 Web 설치 폴더의 모든 jar 파일을 선택
      ※ MiPlatform을 사용할 경우 MiPlatform의 library가 필요하다. MiPlatform은 상용소프트웨어이므로 구매하여 추가하기 바란다.

 

  1. Web Container 설정
    1. Eclipse 메뉴의 Window – Preferences선택
    2. 좌측의 트리 메뉴에서 Server – Installed Runtimes 선택
    3. Add 버튼 클릭하고 Apache Tomcat 5.0 선택하고 Next 버튼 클릭
    4. Browse 버튼을 클릭하여 설치된 Tomcat Root 폴더를 선택

    ※ Eclipse의 default JRE 버전이 JDK 1.4일 경우 Tomcat 5.0을,

JDK 1.5일 경우 Tomcat 5.5 버전을 사용한다.

 

  1. 사용자 환경에 맞추어 서비스 배포
    1. Eclipse에서 anyframe-template-mi-service프로젝트의 build.xml파일을 열어서 anyframe.lib의 위치를 Anyframe Core와 Web 설치 폴더로 변경
    2. Eclipse의 Package Explorer에서 build.xml을 선택하고 마우스 오른쪽 버튼을 클릭하여 Run As – Ant Build를 선택하고 all target을 선택하여 Run 버튼 클릭

    ※ 템플릿을 구성하는 서비스 코드 및 속성 정의가 변경 됐을 경우 all target을 실행시키면 자신의 환경에 수정 내용을 배포할 수 있다.

2.3. Template실행

  1. 테이블 및 데이터 생성
  • Hsql DB의 경우,
    • [템플릿 압축해제 폴더]/anyframe-template-service/DATABASE/db 폴더 (MiPlatform Template의 경우 [템플릿 압축해제 폴더]/anyframe-template-mi-service/DATABASE/db 폴더)의 insertvalue.sql의 내용을 sampledb.script의 기존 내용(DDL)에 이어 붙여 넣은 후 runHsqlDB.cmd 파일 실행
  • Oracle DB의 경우,
    • [템플릿 압축해제 폴더]/anyframe-template-service/DATABASE/db 폴더의 templateDB.sql을 이용하여 테이블 및 데이터 생성

    

※ 사용하는 DBMS의 종류에 따라 Data Source 설정을 바꿔야 한다.

anyframe-template-service/src/main/resources/spring/common/context-

datasource.xml 파일에 있는 dataSource의 속성을 사용자의 환경에 맞게

수정한 후 build.xml을 선택하고 마우스 오른쪽 버튼을 클릭하여

Run As – Ant Build 를 실행해 다시 배포한다.

 

  1. Web Container 구동
    1. Eclipse의 Package Explorer에서 anyframe-template-web-springmvc 또는 anyframe-template-web-struts 프로젝트 선택
      MiPlatform Template의 경우 anyframe-template-mi-web 프로젝트 선택.
    2. src/webapp/login.jsp를 선택하고 마우스 오른쪽 버튼을 클릭하여 Run AS – Run on Server 을 선택하여 실행. 또는 Internet Explorer에서 anyframe-template-web-springmvc 또는 anyframe-template-web-struts 프로젝트의 주소를 입력하여 로그인 화면이 나타나는 것을 확인.
      MiPlatform Template의 경우 anyframe-template-mi-web 프로젝트 주소.
      예)
      http://localhost:8080/anyframe-template-web-springmvc
      http://localhost:8080/anyframe-template-mi-web
  2. 실행 결과

① 로그인 할 수 있는 화면

② ID, Password에 'test/test123'을 입력하고 Login 버튼 클릭 시 Welcome

페이지로 이동

③ 좌측 메뉴를 클릭하여 이용

제 3 장    Basic Template 소개

3.1. 개 요

Anyframe Template은 기본적으로 Eclipse의 프로젝트 형태로 제공된다. Anyframe Basic Template은 비즈니스 레이어를 구현한 Service(anyframe-template-service)프로젝트와 프리젠테이션 레이어를 구현한 Web(anyframe-template-web-springmvc와 anyframe-template-web-struts)프로젝트로 구성되어 있다.

Service프로젝트는 Anyframe Core 3.2.0의 Spring IoC, Spring AOP, Hibernate, Query 서비스를 이용하여 구현하였고, Web프로젝트는 Spring MVC를 기반으로 구현한 것과 Struts기반으로 구현한 것, 이렇게 두 가지로 구성되어 있다.

Template에서 구현한 서비스는 제품(Product)의 등록, 수정, 삭제, 조회 및 분류체계(Category)의 등록, 수정, 삭제, 조회 기능으로 일반적으로 많이 사용되는 기능을 중심으로 하되 확대가 용이한 구조로 구현하였다.

3.2. 구 현

3.2.1. 비즈니스 레이어

비즈니스 서비스는 아래 그림과 같이 도메인 모델, 서비스 인터페이스 클래스, 서비스 구현클래스, DAO 인터페이스 클래스 및 DAO 구현 클래스로 구성되어 있다

1) 제품(Product) 관련 클래스

종류

클래스

클래스 설명

도메인 모델

Product 

Product 테이블 컬럼과 동일한 멤버변수와 그에 대한 Setter/Getter 메소드로 구성

서비스 인터페이스

ProductService 

Product 관리 기능을 제공하기 위한 인터페이스로 Create/Find/Update/Remove 기본 CRUD 메소드에 카테고리별 제품 수량 정보 추출을 위한 countProductListByCategory 카테고리별 제품 리스트 제공을 위한 findProductList 메소드로 구성

서비스 구현

ProductServiceImpl

ProductService implements 하는 클래스로 ProductDAO 메소드를 호출하여 DB처리를 하도록 하고, IIdGenerationService 이용하여 Product 정보를 생성하고, MessageSource 이용하여 오류메세지를 처리하는 기능 구현

Spring IoC 활용

DAO 인터페이스

ProductDAO 

Product관련 DB 조작하기 위한 메소드를 정의한 인터페이스

DAO 구현

ProductDAOHibernateImpl 

ProductDAO implements 하는 클래스로 HibernateDaoSupport 상속받아서 DB 조작하고 propertiesService 이용하여 findProductList 메소드내에서 Page관련 정보를 처리함

Hibernate 활용, Spring IoC 활용

ProductDAOQueryImpl

ProductDAO implements 하는 클래스로 AbstractDAO 상속받아서 DB 조작하고 propertiesService 이용하여 findProductList내에서 Page관련 정보를 처리함

Query서비스 활용, Spring IoC 활용

※ Category 관련 클래스와 Code 관련 클래스도 동일하게 구성.

 

2) 공통(Common) 클래스

종류

클래스

클래스 설명

Data Transfer Object

SearchVO

검색 기능과 관련된 정보를 가진 클래스로 멤버변수의 Setter/Getter 메소드로 구성

서비스구현

EmpException

BaseException 상속받은 클래스. 여러가지 입력 파라미터를 받는 생성자로 구성

EmpUtil 

Null 처리를 위한 메소드 여러가지 String utility 메소드를 담고 있음

ExceptionTransfer

Exception 발생되었을 Spring AOP 의해 transfer 메소드가 호출된다. Exception 별로 정의된 메시지를 MessageSource 이용하여 처리를 하도록

Spring AOP, Spring IoC 활용

LoggingAspect 

클래스의 메소드가 호출 되었을 Spring AOP 의해 beforeLogging 메소드가 실행된다. 호출된 클래스와 메소드명 그리고 호출 시점에 입력된 parameter 값까지 추출하여 Logging하는 클래스임

Spring AOP, Spring IoC 활용

※ 이외, 클래스들은 Security 관련 클래스로 서비스 인터페이스 클래스인 AuthenticationService와 그 구현클래스인 DBAuthenticationService, java.util.Properties를 상속받은 Credential 클래스로 구성되어 있다.

 

3.2.2. 프리젠테이션 레이어

Anyframe Basic Template에서 제공하는 프리젠테이션 레이어 어플리케이션은 Spring MVC 기반으로 구현된 것과 Struts를 기반으로 구현된 것, 두 가지가 있다. 이 중 Spring MVC 기반으로 구현된 Template에 대해서 설명하도록 한다. Spring MVC 기반의 프리젠테이션 레이어는 아래 그림 같이 DispatcherServlet, Interceptor, Controller, JSP, Custom Tag Library로 구성되어 있다.

 

 

 

 

 

 

 

 

 

 

 

[프리젠테이션 레이어 구성]

 

1) 제품(Product) 관련 구성요소

종류

구성요소

Controller 

ProductController.java

Product 도메인에 관련된 기본 CRUD 기능을 호출하는 각각의 addView(), add(), get(), update(), list(), delete() 메소드로 구성되며 double submit 방지 기능이 적용되어 있지 않다.

JSP 

addProduct.jsp

제품 등록을 위한 화면으로 ProductController add()메소드를 호출하여 제품등록처리를 한다

listProduct.jsp

제품리스트를 조회하기 위한 화면으로 ProductController

list()메소드를 호출하여 리스트를 보여준다

updateProduct.jsp

제품 수정을 위한 화면으로 ProductController get()메소드를 이용하여 내용을 조회하고 update()메소드를 호출하여 수정되도록 한다

Config File 

product-servlet.xml

제품(Product)관련 웹페이지 요청에 대한 ProductController 매핑정보가 정의 되어 있으며, ProductController Bean에서 사용하는 서비스 Bean정보와 프로퍼티 정보가 정의되어 있다.

2) 카테고리(Category) 관련 구성요소

종류

구성요소

Controller 

CategoryController.java

카테고리 도메인에 관련된 기본 CRUD 기능을 호출하는 각각의 add(), update(), list(), delete() 메소드로 구성되며 Add, Update, Delete 대한 double submit 방지 기능이 적용되어 있다

JSP 

addCategory.jsp

카테고리 등록을 위한 화면으로 CategoryController add()메소드를 호출하여 제품등록처리를 한다

listCategory.jsp

카테고리 리스트를 조회하기 위한 화면으로 CategoryController

list()메소드를 호출하여 리스트를 보여준다

updateCategory.jsp

카테고리 수정을 위한 화면으로 CategoryController get()메소드를 이용하여 내용을 조회하고 update()메소드를 호출하여 수정되도록 한다

Config File 

category-servlet.xml

카테고리 관련 웹페이지 요청에 대한 CategoryController 매핑정보가 정의 되어 있으며, CategoryController Bean에서 사용하는 서비스 Bean정보와 프로퍼티 정보가 정의되어 있다.

 

3) 공통(Common) 구성요소

종류

구성요소

Interceptor 

AuthorizationInterceptor.java

페이지 권한처리를 위한 인터셉터로 세션에서 로그인 아이디를 받아서 권한 정의된 사용자 여부를 체크

LoginInterceptor.java

중간접속 차단을 위해 만든 Login여부 체크 인터셉터

Config File 

common-servlet.xml

Spring MVC에서 제공하는 기본적인 Resolver들을 정의하여 사용한다. (ex> viewResolver, paramResolver, handlerMapping)

security-servlet.xml

사용자 로그인에 관련된 매핑 정보가 정의되어 있다.

 

제 4 장    MiPlatform Template 소개

4.1. 개요

Anyframe MiPlatform Template은 비즈니스 레이어를 구성하는 Service(anyframe-template-mi-service)프로젝트와 프리젠테이션 레이어를 구성하는 Web(anyframe-template-mi-web)프로젝트로 구성되어 있다.

Service프로젝트는 Anyframe Core 3.2.0의 Spring IoC, Spring AOP, MiPQueryService를 이용하여 구현하였고, Web프로젝트는 Anyframe Web 3.2.0의 Spring MVC를 기반으로 구현되어 있다.

Template에서 구현한 서비스는 분류체계(Category)의 등록, 수정, 삭제, 조회 기능으로 일반적으로 많이 사용되는 기능을 중심으로 하되 확대가 용이한 구조로 구현하였다. 단, MiPlatform을 이용한 화면 구성(jsp, xml)에 대해서는 MiPlatform에서 제공하는 툴을 이용하도록 한다.

 

4.2. 구 현

4.2.1. 비즈니스 레이어

비즈니스 서비스는 아래 그림과 같이 서비스 인터페이스 클래스, 서비스 구현클래스, DAO 클래스로 구성되어 있다.

1) 분류체계(Category) 관련 클래스

종류

클래스

클래스 설명

서비스 인터페이스

서비스 구현

CategoryService

Category관리 기능을 제공하기 위한 인터페이스로 CRUD 작업을 하는 saveAll메소드에 카테고리 리스트 제공을 위한 findProductList 메소드로 구성

CategoryServiceImpl

CategoryService implements 하는 클래스로 CategoryDAO 메소드를 호출하여 DB처리를 하도록 한다.

Spring IoC 활용

DAO 클래스

CategoryDAO 

Category 관련 DB 조작하는 로직을 수행하고 IIdGenerationService 사용하여 유일한 아이디를 생성한다.

MiPQueryService활용, Spring IoC 활용

 

2) 공통(Common) 클래스

종류

클래스

클래스 설명

도메인 모델

SearchVO 

검색 기능과 관련된 정보를 가진 클래스로 멤버변수의 Setter/Getter 메소드로 구성

서비스구현

EmpException

BaseException 상속받은 클래스. 여러가지 입력 파라미터를 받는 생성자로 구성

ExceptionTransfer

Exception 발생되었을 Spring AOP 의해 transfer 메소드가 호출된다. Exception 별로 정의된 메시지를 MessageSource 이용하여 처리를 하도록

Spring AOP, Spring IoC 활용

LoggingAspect 

클래스의 메소드가 호출 되었을 Spring AOP 의해 beforeLogging 메소드가 실행된다. 호출된 클래스와 메소드명 그리고 호출 시점에 입력된 parameter 값까지 추출하여 Logging하는 클래스임

Spring AOP, Spring IoC 활용

※ 이외, 클래스들은 Security 관련 클래스로 서비스 인터페이스 클래스인 AuthenticationService와 그 구현클래스인 DBAuthenticationService, java.util.Properties를 상속받은 Credential 클래스로 구성되어 있다.

4.2.2. 프리젠테이션 레이어

MiPlatform Template의 프레젠테이션 레이어는 Spring MVC 기반으로 작성되어 있어 아래 그림 같이 DispatcherServlet, Interceptor, Controller 로 구성되어 있다.

 

 

 

 

 

 

 

 

 

 

 

[프레젠테이션 레이어 구성]

 

1) 카테고리(Category) 관련 구성요소

종류

구성요소

Controller 

CategoryMiPController.java

Category 도메인에 관련된 리스트 출력을 위한 getCategoryLIst()메소드와, 데이터의 일괄 저장을 위한create, update, delete 기능을 동시에 처리하는 updateCategory() 메소드가 정의되어 있다.

Config File 

category -servlet.xml

Category 관련 웹페이지 요청에 대한 Category관련 Controller 대한 매핑정보가 정의 되어 있으며, Controller Bean에서 사용하는 서비스 Bean정보와 프로퍼티 정보가 정의되어 있다.

 

2) 공통(Common) 구성요소

종류

구성요소

Interceptor 

LoginInterceptor.java

중간접속 차단을 위해 만든 Login여부 체크 인터셉터

Config File 

common-servlet.xml

Spring MVC에서 제공하는 기본적인 Resolver들을 정의하여 사용한다. (ex> viewResolver, paramResolver, handlerMapping)

security-servlet.xml

사용자 로그인에 관련된 매핑 정보가 정의되어 있다.

 

제 5 장    Base Framework

본 문서에서는 템플릿에서 활용하고 있는 기능들에 대해서 개발자들이 꼭 알아야 할 사항에 대해서만 기술하므로, 여기서 언급하는 내용에 대한 자세한 가이드는 Anyframe Java 매뉴얼 참고하기 바란다.

5.1. Spring IoC

  1. 개 요
    한 클래스가 특정 작업을 수행하기 위해 필요한 다른 클래스들을 직접 생성하거나 획득하지 않고, 이러한 의존성들을 외부에 정의하고 컨테이너에 의해 공급받는 방법을 IoC(Inversion of Control)라고 한다. 이는 Spring Framework의 핵심적인 개념으로 템플릿에서는 모든 클래스에서 외부 클래스를 참조할 때 이 방법을 이용하고 있다.

 

  1. 서비스 사용 설명
    1. 서비스 속성 정의 파일 생성
      [템플릿 압축해제 폴더]/src/main/resource/spring/common/*.xml
      [템플릿 압축해제 폴더]/src/main/resource/spring/hibernate/*.xml
      [템플릿 압축해제 폴더]/src/main/resource/spring/query/*.xml
    2. 서비스 속성 정의 파일에 bean class 선언
    3. 서비스 속성 정의 파일에 클래스에서 참조하는 다른 클래스 정의
    4. bean class에서 사용하기 위한 Setter 정의

     

     

     

5.2. Spring AOP

  1. 개 요
    비즈니스 로직이 구현된 코드를 수정하지 않고서 특정 클래스 및 메소드를 패턴 매칭 방법으로 정의하여 지정된 패턴이 실행되는 시점에 필요한 공통 작업을 수행하게 해주는 서비스로 템플릿에서는 Logging, Exception, Transaction 등의 처리를 수행하는 샘플을 제시함

 

  1. Logging Aspect
    1. 서비스 속성 정의 파일 생성
      [템플릿 압축해제 폴더]/src/main/resource/spring/common/context-aspect.xml
    2. 서비스 속성 정의 파일에 Logging처리 Class 선언
    3. 서비스 속성 정의 파일에 수행시점을 패턴매칭방법으로 정의
    4. 서비스 속성 정의 파일에 동작시점과 수행 메소드 선언
    5. Logging처리 Class에 수행 메소드 구현

     

     

     

     

 

  1. Exception Aspect
    1. 서비스 속성 정의 파일 생성
      [템플릿 압축해제 폴더]/src/main/resource/spring/common/context-aspect.xml
    2. 서비스 속성 정의 파일에 Exception처리 Class 선언
    3. 서비스 속성 정의 파일에 수행시점을 패턴매칭방법으로 정의
    4. 서비스 속성 정의 파일에 동작시점과 수행 메소드 선언
    5. Exception처리 Class에 수행 메소드 구현
      구현 기능 : Exception을 EmpException, Exception으로 구분하여 처리하며. Exception을 throw하기 전에 ERROR 레벨의 로그를 남김. 각 Exception을 구현 클래스에서 처리하지 않고 정해진 규칙에 맞게 해당하는 Exception key를 찾아 처리함. 따라서 메소드 별 특정 값에 대한 로그 처리는 개별적으로 구현 필요함

     

     

  2. Transaction 관리
    1. 서비스 속성 정의 파일 생성
      [템플릿 압축해제 폴더]/src/main/resource/spring/hibernate/context-transaction.xml
      [템플릿 압축해제 폴더]/src/main/resource/spring/query/context-transaction.xml
    2. 서비스 속성 정의 파일에 Transaction처리 Class 선언
    3. 서비스 속성 정의 파일에 수행시점을 패턴매칭방법으로 정의
    4. 서비스 속성 정의 파일에 동작시점과 수행 메소드 선언

     

     

5.3. Hibernate

  1. 개 요
    Hibernate는 객체지향모델링(Object Oriented Modeling)과 관계형 데이터 모델링 (Relational Data Modeling) 사이의 불일치를 해결해 주는 ORM 도구로 특정 플랫폼에 의존적인 제약을 정의하고 있지 않기 때문에 POJO 기반의 개발이 가능하고 또한 Java에서 지원하는 다양한 Collection 유형을 지원함으로써 객체 모델링을 관계형 모델링으로 매칭하는데 따르는 제약을 최소화하고 있다. 본 Template에서는 Hibernate를 활용하여 CRUD를 구현하는 샘플을 제시함.

 

  1. 서비스 사용 설명
    1. 서비스 속성 정의 파일 생성
      [템플릿 압축해제 폴더]/src/main/resource/spring/hibernate/context-hibernate.xml
    2. 서비스 속성 정의 파일에 매핑 정의 파일 위치 지정
    3. 서비스 속성 정의 파일에 dynamicHibernateService를 위한 설정 파일 지정
    4. 매핑정의 파일 설정(②에서 위치 지정한): hibernate 툴 이용해 자동생성 가능
      [템플릿 압축해제 폴더]/src/main/resource/hibernate/Category.hbm.xml
      테이블 컬럼과의 매핑정보 정의
      CRUD외 Query 정의 (CRUD는 Query 정의 없이 가능)
    5. dynamicHibernateService를 위한 설정 파일 정의(③에서 파일 지정한)
    6. DAO 클래스에서의 사용

     

     

     

     

  2. DataSource 서비스 설정 (Hibernate와 Query에서 모두 사용함)
    1. 서비스 속성 정의 파일 생성
      [템플릿 압축해제 폴더]/src/main/resource/spring/common/context-datasource.xml
    2. DB 관련 정보 설정(HSQL 설정 정보)

    아래QueryService의 'DataSource 서비스 설정'설명 참고.

     

     

     

     

5.4. Query 서비스

  1. 개 요
    쿼리 문이나 객체의 입력만으로 DB 데이터 조작을 가능하게 하는 서비스로 JDBC(Java Database Connectivity)를 이용한 데이터 액세스 수행 부분을 추상화함으로써 간편한 데이터 액세스 방법을 제공하고, JDBC 사용시 발생할 수 있는 공통 에러를 줄여주게 된다. 본 Template에서는 DAO 클래스에서 Query 서비스에서 제공하는 AbstractDAO를 상속받아 CRUD를 구현하는 샘플을 제시함.

 

  1. 서비스 사용 설명
    1. 서비스 속성 정의 파일 생성
    2. 서비스 속성 정의 파일에 매핑 정의 파일 위치 지정
    3. 매핑정의 파일 설정(②에서 위치 지정한)
    4. DAO 클래스에서의 사용

     

     

     

    QueryService의 AbstractDAO에서 제공하는 메소드들을 사용하면 DAO클래스를 간단하게 만들 수 있다. 자세한 내용은 Anyframe Java의 Query서비스 매뉴얼 참고.

     

     

     

     

     

     

 

  1. DataSource 서비스 설정 (Hibernate와 Query에서 모두 사용함)
    1. 서비스 속성 정의 파일 생성
      [템플릿 압축해제 폴더]/src/main/resource/spring/common/context-datasource.xml
    2. DB 관련 정보 설정(HSQL 설정 정보)
    3. Anyframe에서 제공하는 ID Generation 서비스가 사용하는 DataSource는 따로 분리.

     

     

5.5. MiPQueryService

  1. 개 요
    MiPQueryService는 MiPlatform 기반 개발을 위해 Query 서비스를 확장한 서비스이며 query작성만으로 Table에 특정 Data를 insert, update, delete, select할 수 있다.
    기본적으로 QueryService를 확장한 것이기 때문에 설정방법은 QueryService와 유사하다. 설정 XML의 자세한 속성 정보들은 Anyframe Java 의 매뉴얼을 참고하기 바란다.

 

  1. 기본 서비스 사용 설명
    1. 서비스 속성 정의 파일 생성
      [MiPlatform 템플릿 압축해제 폴더]/src/main/resource/spring/context-query.xml
    2. 서비스 속성 정의 파일에 매핑 정의 파일 위치 지정
    3. 매핑 정의 파일 설정(②에서 위치 지정한)
    4. DAO 클래스에서 사용

     

     

    ※ MiPQueryService를 이용해 DB에 값을 전달하기 전, 후에 특정 값을 셋팅해야 하는 경우가 있다. 이 때 위의 CategoryMiPActionCommand 클래스처럼 anyframe.core.query.ria.mip.IMiPActionCommand를 구현한 클래스를 통해 필요한 비즈니스 로직을 추가할 수 있다.

     

5.6. Spring MVC

  1. 개 요
    Spring MVC를 이용하여 프리젠테이션 레이어를 개발 할 때에는 크게 Controller와 Config 파일(Mapping XML), JSP(Custom Tag) 세 개의 파일을 작성해야 한다. 또한 필요에 따라 Interceptor, Validator등을 구현할 수 있다.

 

  1. 기본 서비스 사용 설명
    1. Config 파일(Mapping) 작성
      ⓐ Control Class 정의, ⓑ 호출 Service Bean 정의 ⓒ 사용 프로퍼티 정의
      ⓓ 중복 서브밋 방지 프로퍼티 정의 – 이중 저장 방지를 위한 기능 구현
    2. Controller 구현
      ⓐ Service Bean Setter 정의, ⓑ 폼 입력 데이터 바인딩, ⓒ ModelAndView 객체 리턴
    3. JSP 구현

     

     

     

     

     

     

     

     

     

     

  2. Interceptor 구현
    1. Config 파일(Mapping)에 Interceptor 정의
    2. Interceptor 구현

     

     

     

     

  3. Anyframe Tag Library 사용
    1. Page Navigator Tag 사용
    2. Message Tag 사용

     

 

5.7. MiPlatform

  1. 개 요
    SpringMVC와 MiPlatform을 이용하여 Presentation Layer를 개발 할 때에는 크게 Controller와 Config 파일(Mapping XML), MiPlatform 관련 화면 구성 파일(이는 MiPlatform에서 제공하는 툴을 사용하여 별도로 작성)을 작성해야 한다.

 

  1. 기본 서비스 사용 설명
    1. Config파일(Mapping XML) 작성
      Control Class 정의, 호출 Service Bean 정의
    2. Controller구현
      Service Bean Setter 정의, 비즈니스 서비스 호출 후 Dataset 생성,
      ds_access에 리턴할 Dataset 셋팅

     

     

     

 

5.8. 기타

본 Template은 설명된 서비스 외에도 PropertiesService, IdGenerationService, MessageSource를 이용하여 구현되었다. 각각에 대한 사용 방법은 아래와 같다.

 

  1. Properties Service
    변경 사항이 빈번한 property(여기에선 PAGE_SIZEPAGE_UNIT)에 대해 소스가 아닌 XML에 정의하여 관리할 수 있다.


  2. ID Generation Service
    TableIdGenerationService를 사용하여 Table기반의 유일한 Id를 자동 생성시킬 수 있도록 작성하였다.

 

 

 

  1. MessageSource
    프로젝트에 맞는 message 정의 properties파일을 만들고 이 properties 파일의 위치를 MessageSource bean에서 정의한다.

 



 

 

별첨-1. 주요 클래스 다이어그램
Category @Basic Template

 

별첨-2. 주요 클래스 다이어그램
Category @MiPlatform Template

 

반응형

'개발도 하냐?' 카테고리의 다른 글

JEUS 설정  (0) 2009.11.04
전자세금계산서/세금계산서 업체 정보리스트  (0) 2009.10.29
JSP_MVC 형식  (0) 2009.09.16
Eclipse + JEUS  (0) 2009.08.19
약도 만들기  (0) 2009.08.14
반응형

MVC의 개요

기존의 모델1 개발방식에 익숙하신 분들을 위해서 보다 효율적이고 유지보수하기 편한 MVC기법으로 웹프로그래밍 하는 방법에 대해서

강좌를 시작하려고 합니다.

그럼 기존의 모델1과 MVC는 도대체 뭐가 다르냐고 반문하시는 분들이 계실겁니다.

크게 다른점은 모델1의 경우에 jsp파일 하나에 모든 내용이 다 들어간다는것과 MVC는 그러한 부분을 각각의 특성에 맞게 분리했다는겁니다.

그럼 뭘 어떻게 분리하냐가 중요하겠죠.. 여기서 MVC 즉 Model, View, Controller에 대한 이해가 필요합니다.

View는 다들 잘 알다시피 html태그라고 생각하시면 됩니다. Model은 간단하게 데이타베이스에 쿼리하는 부분이라고 할수있습니다.

나머지 Controller 는 2개를 연결시켜주는 역할이라고 보시면 됩니다.

의미상으로는 아주 간단합니다. 앞으로 진행할 강좌는 다음과 같은 단계에 걸쳐 진행하도록 하겠습니다.

1.이클립스에서 톰캣을 활용한 웹프로그래밍 환경구축하기
2.모델1 기법으로 게시판 리스트 화면 만들기(List.jsp)
3.MVC 기법으로 게시판 리스트 화면 만들기
4.위의 2개의 구조를 비교분석하기

다음강좌에서 뵙겠습니다..

 

MVC 첫번째강좌 - 모델1 기법으로 게시판 리스트 만들기

작성자 : 김시웅
테스트환경 : 이클립스2.1.2, mysql, tomcat4.1.30

본강좌는 jsp에 어느정도 익숙하신걸로 가정하고 진행하겠습니다. 일단 환경부터 구축해야겠죠^^.

먼저 DB에 테이블을 하나 만들겠습니다. Board(번호, 이름, 제목, 내용, 등록일) 테이블을 하나 만들고 디폴트로 몇개의 데이타를 넣겠습니다.(Board.sql, insert.sql) 자, 기본적인 준비는 됐습니다.

이제 이클립스에서 자바프로젝트를 하나 만듭니다. 프로젝트명은 MvcBoard 라고 하겠습니다.

프로젝트에서 www 폴더를 만듭니다. 이제 톰캣플러그인이 필요합니다. 설치하지 않으신분은 자료실에서 다운 받으시면 됩니다.

톰캣플러그인이 설치되셨다면 MvcBoard->특성을 누릅니다. 왼편에 Tomcat을 선택하고 Is a Tomcat Project 를 체크합니다. 다음에 Subdirectory to set as web application root(optional) 부분을 /www 로 변경합니다. 변경한 화면은 다음과 같습니다.


확인을 누르면 톰캣설정이 완료되었습니다. 이제 www폴더에 test.jsp를 만들고 내용은 test 로 합니다.

톰캣을 실행하고 브라우저에서 http://localhost:8080/test.jsp 를 입력합니다. 아래화면처럼 나오면 성공입니다.


지금까지는 db를 구성하고 이클립스에서 프로젝트를 톰캣과 연동하는 과정이었습니다. 앞으로 진행할 웹관련 강좌는 이런형태로
프로젝트를 설정하게됩니다.

자 그럼 모델1방식으로 게시판 리스트를 만들어보도록 하겠습니다. www폴더에 List.jsp 를 만들고 다음의 순서대로 내용을 채우겠습니다.

먼저 import 와 contentType을 설정합니다.
<%@ page language="java" import="java.sql.*,java.io.*" contentType="text/html; charset=euc-kr" %>

그 다음에 db에 접속을 해서 커넥션을 맺습니다. db서버주소, db명, 유저명,암호는 여러분의 db에 맞게 직접 넣으시기 바랍니다.
본강좌에서는 mysql을 사용합니다.

<%
   String url = "jdbc:mysql://db서버주소:3306/db명";
   String username = "유저명";
   String password = "암호";
   Connection con = null;
   try {
      Class.forName("org.gjt.mm.mysql.Driver");
      con = DriverManager.getConnection(url, username, password);
   } catch (ClassNotFoundException e) {
      out.println("드라이버를 찾을수 없습니다.");
   } catch (SQLException ex) {
      out.println("접속실패");
   }
%>

커넥션을 얻었다면 ResultSet을 얻습니다. 테이블은 위에서 만든 Board 입니다. Board.sql을 사용하여 테이블을 만들고 insert.sql 을 사용하여 데이타를 먼저 입력해놓겠습니다.(위의 첨부파일을 참조하세요)
<%   
   PreparedStatement ps = null;
   ResultSet rs = null;      
   String query = "select * from Board";
   try {
      ps = con.prepareStatement(query);
      rs = ps.executeQuery();
%>

이제 ResultSet을 사용하여 화면에 리스트를 구성하도록 하겠습니다.
<html>
   <body>
      <table border="1">
         <tr>
            <td>번호</td>
            <td>제목</td>
            <td>이름</td>
            <td>등록일</td>
         </tr>
<%
      while (rs.next()) {            
         String num = rs.getString("num");
         String subject = rs.getString("subject");
         String name = rs.getString("name");
         String regiDate = rs.getString("regiDate");
%>         
         <tr>
            <td><%=num%></td>
            <td><%=subject%></td>
            <td><%=name%></td>
            <td><%=regiDate%></td>
         </tr>
<%
      } 
%>
      </table>
   </body>
</html>

자, 이제 남은건 커넥션을 닫기만 하면 됩니다.
<%
   } catch (SQLException e) {
      out.println(e);
   } finally {
      try {
         if(rs != null) rs.close();         
         if(ps != null) ps.close();         
         if(con != null) con.close();               
      } catch(SQLException e) {
         out.println(e);      
      }
   }
%>

이제 브라우저에서 http://localhost:8080/List.jsp 를 호출하면 다음화면처럼 나올겁니다.


다음 강좌에서는 MVC기법으로 소스를 변경해보도록 하겠습니다.(물론 화면에 나타나는 결과물은 동일할겁니다)

 

MVC 두번째강좌 - MVC 기법으로 게시판 리스트 만들기(컨트롤러)

작성자 : 김시웅
테스트환경 : 이클립스2.1.2, mysql, tomcat4.1.30

이전강좌에서는 전통적인 방식으로 화면을 만들었습니다. 그동안 다들 이렇게 코딩하셨다구요^^..

상관없습니다. 저도 그렇게 해왔었으니까요.

먼저 MVC로 들어가기전에 페이지가 호출되는 순서에 대해서 살펴보겠습니다. 모델1은 그냥 jsp파일을 직접 호출합니다. 하지만 MVC는 컨트롤러 개념이 들어갑니다. 그래서 먼저 컨트롤러를 호출하고 모델에서 데이타를 구성합니다. 마지막으로 jsp를 호출하죠.

이해가 되시나요? 다시 얘기하자면 컨트롤러 -> 모델 -> 뷰 의 순서로 호출됩니다.

그렇다면 컨트롤러를 가장 먼저 만들어야겠죠. 자 이제부터 MVC에 본격적으로 들어갑니다.

컨트롤러는 쉽게 얘기해서 중개자 역할입니다. 일종의 관문인데 모든 호출은 컨트롤러를 거칩니다. 컨트롤러는 서블릿으로 만들겠습니다. jsp로 만들어도 되지만 서블릿이 좀더 컨트롤러가 하는 역할에 적합하다고 볼수있습니다.

이제 이클립스로 가서 MvcBoard->src 에서 팩키지를 하나 만들겠습니다. 팩키지명은 javaforum.board 로 합니다.

javaforum.board 에서 클래스를 하나 만듭니다. 클래스명은 Controller 로 합니다.

다음에 나오는 순서대로 Controller 클래스에 내용을 채우겠습니다.

먼저 필요한 클래스들을 import합니다.
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import java.io.IOException;

Controller클래스를 HttpServlet으로 상속받도록 변경합니다.
public class Controller extends HttpServlet {

이제 Controller 클래스에 들어갈 함수를 작성합니다.
   public void init(ServletConfig config) throws ServletException {
      super.init(config);            
   }
   
   public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {         
      doProcess(request, response);
   }
   
   public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {         
      doProcess(request, response);      
   }
   
   public void doProcess(HttpServletRequest request, HttpServletResponse response) {
   }

이것으로 서블릿이 하나 완성되었습니다. 물론 하는일은 없습니다^^.. 단, 여기서 살펴볼 부분이 doGet, doPost함수에서 doProcess를 호출하도록 했다는겁니다. get방식이든 post방식이든 doProcess함수에서 처리하겠다는 의미가 되겠죠...

근데 doProcess에 아무것도 없다구요? 이제부터 컨트롤러의 실제 내용이 들어가게 될겁니다.

일단 서블릿이 제대로 작동되는지 테스트를 해봐야되니깐 doProcess에 System.out.println("컨트롤러 호출"); 만 입력하겠습니다.

여기서 한가지 환경설정부분이 필요합니다. src에 있는 파일이 컴파일될때 기본적으로 bin폴더로 들어가게 됩니다. 이 경로를 바꿔야되겠습니다.

먼저 www폴더에서 WEB-INF 폴더를 새로 만듭니다. 그리고 WEB-INF 폴더에 classes 폴더를 만듭니다.

다 만드셨으면 MvcBoard->특성을 누릅니다. 왼편에서 Java 빌드 경로를 선택합니다. 기본출력폴더 에서 /MvcBoard/bin 을 /MvcBoard/www/WEB-INF/classes 로 변경합니다.

이제부터 src에는 파일을 저장시 컴파일됨과 동시에 WEB-INF/classes 폴더로 클래스파일이 들어가게됩니다.

서블릿은 만들었고 남은건 web.xml을 만들고 서블릿을 맵핑하면 됩니다. WEB-INF 폴더에 web.xml 파일을 하나 만드세요.

web.xml에 다음과 같은 내용을 입력하세요. 톰캣이 서블릿을 인식하도록 맵핑해주는 부분이 들어가있습니다..
<?xml version="1.0"?> 
<!DOCTYPE web-app PUBLIC 
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" 
"http://java.sun.com/dtd/web-app_2_3.dtd"> 

<web-app>   
   <servlet>
        <servlet-name>Controller</servlet-name>
        <servlet-class>javaforum.board.Controller</servlet-class>        
    </servlet>
       
    <servlet-mapping>
        <servlet-name>Controller</servlet-name>
        <url-pattern>/servlet/Controller</url-pattern>
    </servlet-mapping>
</web-app>

맵핑하는 방법은 다양하지만 지금은 /servlet/Controller 로 하겠습니다.

자, 톰캣을 재시작합니다. 브라우저에서 http://localhost:8080/servlet/Controller 를 호출해봅니다.
이클립스 콘솔창에 컨트롤러 호출 메시지가 나오면 정상적으로 서블릿이 호출된 상태입니다.


이제 doProcess함수를 다듬어보겠습니다. 컨트롤러에서 파라미터를 하나 받도록 하겠습니다. 파라미터명은 action 으로 합니다.

String action = request.getParameter("action");

action에 대해서 조건문으로 구분합니다. 여기서는 list 일 경우만 넣었습니다.

      if(action.equals("list")) {
      }

여기까지 하고 www 폴더에서 MvcList.jsp 파일을 만듭니다. 내용은 MvcList 라고만 입력합니다.

이제 컨트롤러에서 조건문내에 MvcList.jsp를 호출하는 부분을 넣도록 하겠습니다.

먼저 import를 합니다.
import javax.servlet.ServletContext;
import javax.servlet.RequestDispatcher;

그리고 조건문내에 다음에 나오는 부분을 입력합니다.
         ServletContext sc = getServletContext();   
         RequestDispatcher rd = sc.getRequestDispatcher("/MvcList.jsp");
         try {
            rd.forward(request, response);
         } catch(ServletException se) {
            se.printStackTrace();               
         } catch(IOException ie) {
            ie.printStackTrace();
         }

여기서는 forward를 사용했는데 페이지를 호출하는 방식에는 2가지가 있습니다, forward, sendRedirect 가 있는데 forward는 서버(웹서버)상에서 직접 페이지를 호출합니다. sendRedirect는 서버에서 클라이언트(웹브라우저)에게 해당 페이지를 요청해달라고 요구하면 클라이언트가 다시 페이지를 호출하는 방식입니다. 즉 sendRedirect는 서버와 클라이언트간의 통신을 한번 더 하는 개념입니다.

이제 브라우저에서 http://localhost:8080/servlet/Controller?action=list 로 호출해보세요.


컨트롤러의 개념을 잡기위하여 먼저 뷰를 호출해보았습니다. 순서상으로는 모델호출이 먼저와야 하지만 편의상 뷰를 어떤식으로 호출하는지에 대해서 살펴보았습니다.

이제 데이타를 구성하고 화면에 뿌리는 일만 남았군요. 다음강좌에서 모델부분과 뷰를 완성해보도록 하겠습니다. 그럼 다음강좌에서.....

 

MVC 세번째강좌 - MVC 기법으로 게시판 리스트 만들기(모델, 뷰)

작성자 : 김시웅
테스트환경 : 이클립스2.1.2, mysql, tomcat4.1.30

2장에 이어서 계속 진행하겠습니다. MVC에서 모델의 역할은 데이타를 구성하고 편집하고 결과물을 만드는 역할을 합니다.

일단 아주 간단하게 생각해서 쿼리부분이 들어가는곳이 모델단인데 DB에 접속해서 쿼리후 데이타를 가져오는 부분을 DAO(Data Access Object) 라고 부르겠습니다.

DAO에서 쿼리의 결과물을 어딘가에 담아야하겠죠. 이걸 VO(Value Object) 에 담겠습니다.

그럼 먼저, VO 클래스를 하나 만듭니다. MvcBoard->src->javaforum.board 에서 신규->클래스를 선택합니다. 클래스명은 ListVO 라고 하세요.
ListVO에 4개의 멤버변수를 만듭니다.
   private int num;
   private String subject;
   private String name;
   private String regiDate;

멤버변수하나를 선택한후 마우스 오른쪽버튼을 눌러서 소스->Getter 및 Setter 생성메뉴를 누릅니다. 팝업화면에서 모두선택하고 확인을 누릅니다.

결과물을 담을 객체를 만들었습니다. 이제 DAO에서 쿼리결과를 ListVO에 담으면 됩니다.

이제, DAO클래스를 만들겠습니다. MvcBoard->src->javaforum.board 에서 신규->클래스를 선택합니다. 클래스명은 BoardDAO 라고 하세요.

상단에 import문을 추가합니다.
import java.sql.*;
import java.util.Vector;

커넥션을 얻는 함수를 하나 만들겠습니다.
   public Connection getConnection() {
      String url = "jdbc:mysql://db주소:3306/db명";
      String username = "유저명";
      String password = "암호";
      Connection con = null;
      try {
         Class.forName("org.gjt.mm.mysql.Driver");
         con = DriverManager.getConnection(url, username, password);
      } catch (ClassNotFoundException e) {
         System.out.println("드라이버를 찾을수 없습니다.");
      } catch (SQLException ex) {
         System.out.println("접속실패");
      }
      return con;      
   }

다음에 쿼리한 결과물을 ListVO에 담고 로우수만큼 ListVO를 벡터에 담는 부분입니다.
   public Vector getList() {
      Connection con = this.getConnection();
      PreparedStatement ps = null;
      ResultSet rs = null;      
      String query = "select * from Board";
      try {
         ps = con.prepareStatement(query);
         rs = ps.executeQuery();
         Vector values = new Vector();
         while(rs.next()) {
            ListVO vo = new ListVO();
            vo.setNum(rs.getInt("num"));
            vo.setSubject(rs.getString("subject"));
            vo.setName(rs.getString("name"));
            vo.setRegiDate(rs.getString("regiDate"));
            
            values.addElement(vo);
         }
         return values;
      } catch (SQLException e) {
         e.printStackTrace();
         return null;
      } finally {
         try {
            if(rs != null) rs.close();                                 
            if(ps != null) ps.close();         
            if(con != null) con.close();   
         } catch(SQLException e) {                        
         }
      }      
   }

Board테이블에 5개의 데이타가 들어가있기때문에 ListVO는 5개 만들어지게 됩니다.

이것으로 DAO는 끝났습니다. 그럼 이 벡터를 컨트롤러에서 받아야겠죠. 다시 컨트롤러로 가겠습니다.

import를 하나 추가합니다. import java.util.Vector;

if(action.equals("list")) { 조건문내에 다음부분을 추가하세요.
         BoardDAO dao = new BoardDAO();
         Vector listValues = dao.getList();
         request.setAttribute("listValues", listValues);


dao.getList() 함수를 호출해서 결과를 받았습니다. 그 결과를 request에 저장합니다. setAttribute()의 의미는 서버상의 request메모리영역에 변수를 임시 저장하는 역할을 담당합니다. 물론 나중에 쓸려고 저장하는겁니다.

어디서 쓰냐구요? MvcList.jsp에서 사용해야겠죠. 이제 남은건 MvcList.jsp에서 결과물을 화면으로 구성하면 됩니다.

MvcList.jsp로 다시 이동하겠습니다.

import 와 contentType을 설정합니다.
<%@ page language="java" import="java.util.Vector, javaforum.board.ListVO" contentType="text/html; charset=euc-kr" %>

request에서 getAttribute로 결과값을 다시 꺼냅니다.
<%
   Vector listValues = (Vector) request.getAttribute("listValues");
%>

마지막으로 화면에 뿌려주기만 하면 됩니다.
<html>
   <body>
      <table border="1">
         <tr>
            <td>번호</td>
            <td>제목</td>
            <td>이름</td>
            <td>등록일</td>
         </tr>
<%
      for(int i = 0; i < listValues.size(); i++) {
         ListVO vo = (ListVO) listValues.elementAt(i);
         int num = vo.getNum();
         String subject = vo.getSubject();
         String name = vo.getName();
         String regiDate = vo.getRegiDate();
%>         
         <tr>
            <td><%=num%></td>
            <td><%=subject%></td>
            <td><%=name%></td>
            <td><%=regiDate%></td>
         </tr>
<%
      } 
%>
      </table>
   </body>
</html>

브라우저에서 http://localhost:8080/servlet/Controller?action=list 를 호출합니다.


이상 MVC형태로 게시판 리스트를 만들어보았습니다. 대충 감이 잡히시나요? 다음강좌에서는 둘의 차이점을 비교분석하고 MVC 소스를 약간 변형해보겠습니다.

그럼 다음강좌에서...

 

MVC 네번째강좌 - 모델1과 MVC 소스 비교분석하기, MVC 소스 약간 변경해보기

작성자 : 김시웅
테스트환경 : 이클립스2.1.2, mysql, tomcat4.1.30

이제 모델1과 MVC사이에 어떠한 변화가 일어났는지 살펴볼 시간입니다. 가장 큰 변화는 무엇일까요?

모델1의 List.jsp 에는 커넥션을 맺고 데이타를 가져오는 부분이 있지만 MVC의 MvcList.jsp에는 그 부분이 빠져있습니다.
훨씬 보기가 좋아진것 같나요. 겉으로 보기에도 소스가 간결해진것을 느낄수가 있습니다.

웹프로그래밍이 아닌 전통적인 어플리케이션 개발에서는 모듈화를 해야만 개발이 용이하고 유지보수도 쉽습니다. 하지만 웹으로 넘어오면서 로직이나 화면처리등을 하나의 파일(jsp)에서 처리하는게 익숙해졌고 또 그렇게 해왔습니다. 하지만 이러한 방식은 상당히 소스를 어지럽게 만들기 때문에 유지보수도 어려울뿐더러 코드의 재사용성에도 문제가 됩니다.
물론 모델1기법이 단점만 있는것은 아닙니다. 소규모프로젝트라면 개발기간면에서 mvc보다는 생산성이 높다고 할 수 있습니다.

여하튼 이러한 문제점을 보완하기위해 나온게 MVC인데 요지는 jsp에 있는 소스를 각모듈이 하는 역할에 맞게 분리하자는 겁니다.

1.view : jsp가 됩니다. 단지 화면에 관련된 사항만 처리합니다.
2.controller : jsp에서 넘어오는 파라미터처리후 해당 로직이나 DAO에 연결한 다음 결과값 받아서 jsp에 넘겨주는 역할을 담당합니다.
3.model : 로직이나 DAO는 controller에서 요구한 데이타를 구성해서 결과값을 넘겨주는 역할을 합니다.

자, 그럼 MVC에 좀 더 깊이 들어가보겠습니다. jsp는 화면처리만 담당한다고 했는데 파라미터처리 부분은 어디로 갔을까요? 컨트롤러에서 그부분이 들어갑니다. 바로 String action = request.getParameter("action"); 이 부분이죠.

근데 한가지 짚고 넘어가야할 부분이 있습니다. 서블릿을 호출할때 /servlet/Controller?action=list 이렇게 했습니다. 즉 이것은 MvcList.jsp를 호출하기 위해서죠. 그렇다면 좀더 세련되게 호출할수 없을까라는 의문이 드는군요.

web.xml에서 서블릿을 다르게 맵핑해보겠습니다. url-pattern 에서 /servlet/Controller -> *.action 로 고칩니다.
<url-pattern>*.action</url-pattern>

이제 Controller 로 갑니다. doProcess에서 다음처럼 변경합니다.
      //String action = request.getParameter("action");
      String servletPath = request.getServletPath();
      String actionName = servletPath.substring(servletPath.lastIndexOf("/") + 1);
      if(actionName.equals("MvcList.action")) {


기존의 파라미터는 쓰지 않기때문에 주석처리하고 서블릿경로에서 액션명을 파싱하는 내용입니다. 이렇게해서 컨트롤러를 호출할때 액션명으로 구분하는게 가능하게됩니다.
이제 MvcList.action 으로 호출해야겠죠^^.

그럼 톰캣을 재시작하고 브라우저에서 http://localhost:8080/MvcList.action 이라고 입력합니다.

MvcList.action 을 호출하게 되면 MvcList.jsp를 호출하게 되는것이죠. 컨트롤러를 약간 수정해보았습니다.

이번에는 view로 가볼까요^^.. MvcList.jsp를 에디터에서 여세요. 물론 간결해지기는 했지만 눈에 거슬리는게 한가지 있군요. 태그사이에 스크립틀릿이 들어가서 일관성이 떨어져보입니다.

바로 스크립틀릿을 태그로 바꿀려고 합니다. 아니 태그라니.. 무슨 말인지 이해가 안되신다구요?

커스텀태그를 사용하면 간단하게 해결이 됩니다. 그중에서도 표준인 jstl(jsp standard tag library)을 사용해서 변경해보겠습니다.

변경하기전에 환경부터 갖추도록 하겠습니다. jstl관련 jar파일을 다운받습니다. 자료실에 보면 톰캣4점대, 톰캣5점대용 jstl.jar, standard.jar 가 있습니다.

2개의 파일을 다운받으셨으면 MvcBoard->www->WEB-INF 로 가서 lib 폴더를 만듭니다. jar파일을 lib폴더로 옮겨놓으세요.

MvcList.jsp 로 가서 상단에 다음부분을 추가합니다. jstl core 관련 태그를 사용하겠다는 의미입니다.
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>

jstl 설정은 마쳤습니다. 이제 core 에 들어있는 태그를 사용해서 스크립틀릿 부분을 대체하면 됩니다.
일단 어떻게 변화가 되는지 보여드리겠습니다.
         <c:forEach items="${listValues}" var="data">      
         <tr>
            <td><c:out value="${data.num}"/></td>
            <td><c:out value="${data.subject}"/></td>
            <td><c:out value="${data.name}"/></td>
            <td><c:out value="${data.regiDate}"/></td>
         </tr>
         </c:forEach>


다시 톰캣을 재시작하고 브라우저에서 http://localhost:8080/MvcList.action 을 호출해보세요. 같은결과가 나올겁니다.

변화된 소스를 보면 listValues 를 가져오는 부분이 없습니다. 그리고 for문이 jstl의 forEach 태그로 변했습니다. 마지막으로 출력부분이 c:out 태그를 사용해서 data.num 과 같은 형식으로 변했습니다.

훨씬 보기가 좋군요^^. 어떤가요 소스도 간결해지고 태그화 되어있기때문에 영역구분이 명료해졌습니다.
지금은 core 태그중에 반복문을 표현하는 forEach와 출력문에 사용되는 out태그만을 사용했습니다. jstl에 대한 사용법은 별도의 강좌(커스텀태그와 jstl 강좌)를 통해서 여러분에게 알려드릴 예정입니다.

다음강좌에서는 모델쪽의 DAO클래스에 변화를 줘보도록 하죠. 그럼 다음강좌에서....

MVC 다섯번째강좌 - MVC패턴에서 모델영역에 속하는 DAO클래스 약간 변경하기

작성자 : 김시웅
테스트환경 : 이클립스2.1.2, mysql, tomcat4.1.30

이번 시간에는 DAO클래스에서 DB의 데이타를 가져오는 부분을 변경해보도록 하겠습니다.

getList() 함수를 보면 커넥션을 하나 가져와서 PreparedStatement와 ResultSet을 이용하여 검색된 로우수만큼 컬럼의 값을 가져오는 부분입니다. 하지만 이러한 부분은 중복이 생기는 경우가 많습니다. 그렇기 때문에 이러한 db처리부분을 공통함수화할 필요가 생겼습니다.

그럼 ResultSet과 같은 역할을 하는 MyResultSet을 만들어보죠. MyResultSet에는 로우수만큼 데이타를 가지는 변수가 필요합니다. 그리고 next, getInt, getString 함수를 만들겠습니다.

package javaforum.board;
import java.util.*;
/**
 * @author wwwoong
 */
public class MyResultSet {
   private Vector rowData;
   private int rowPos = -1;
   
   public void setRowData(Vector rowData) {
      this.rowData = rowData;
   }
   
   public int getInt(String columnName) {
      String columnValue = this.getString(columnName);
      try {
         int val = Integer.parseInt(columnValue);
         return val;
      } catch(Exception e) {
         return -1;            
      }
   }
   
   public String getString(String columnName) {
      Hashtable columnData = (Hashtable) this.rowData.elementAt(this.rowPos);
      if(columnData.containsKey(columnName)) {
         String columnValue = (String) columnData.get(columnName);
         return columnValue;
      } else {
         System.out.println("컬럼명이 존재하지 않습니다.");
         return "";   
      }      
   }
   
   public boolean next() {
      if(this.rowPos == this.rowData.size() - 1) {
         return false;
      } else {
         this.rowPos++;
         return true;
      }      
   }
}

MyResultSet은 ResultSet을 흉내낸것이기 때문에 기능이 같습니다. 여러분들이 직접 분석해보시기 바랍니다.

BoardDAO 로 가서 함수 하나를 만들겠습니다. 함수의 내용은 rowData에 쿼리결과를 집어넣고 MyResultSet에 rowData를 넣습니다.
   public MyResultSet selectMultiRow(String query) {         
      Connection con = null;   
      PreparedStatement ps = null;
      ResultSet rs = null;
      ResultSetMetaData rmd = null;
      int columnCount = 0;
      
      MyResultSet myResultSet = new MyResultSet();
      Vector rowData = new Vector();
      try {
         con = getConnection();
         ps = con.prepareStatement(query);
         rs = ps.executeQuery();
         rmd = rs.getMetaData();
         columnCount = rmd.getColumnCount();
         while (rs.next()) {                        
            Hashtable columnData = new Hashtable();
            for(int i = 1; i <= columnCount; i++) {
               String columnName = rmd.getColumnName(i);
               columnData.put(columnName, rs.getString(i));               
            }
            rowData.addElement(columnData);
         } 
         myResultSet.setRowData(rowData);
      } catch (SQLException e) {
         System.out.println("select sql : " + e);
         e.printStackTrace();
      } finally {
         try {
            if(rs != null) rs.close();                                 
            if(ps != null) ps.close();         
            if(con != null) con.close();         
         } catch(SQLException e1) {
            e1.printStackTrace();         
         }
      }
      return myResultSet;
   }

selectMultiRow 는 여러개의 로우결과를 갖기때문에 이렇게 이름지었습니다. 이 함수를 이용해서 getList()를 고쳐보도록 하겠습니다.
   public Vector getList() {
      String query = "select * from Board";
      MyResultSet myResultSet = this.selectMultiRow(query);
      
      Vector values = new Vector();
      while(myResultSet.next()) {          
           ListVO vo = new ListVO(); 
          vo.setNum(myResultSet.getInt("num")); 
          vo.setSubject(myResultSet.getString("subject")); 
          vo.setName(myResultSet.getString("name")); 
          vo.setRegiDate(myResultSet.getString("regiDate")); 
         
          values.addElement(vo); 
      }
      
      return values;
   }

이전의 getList() 함수와 차이가 느껴지나요? 위아래로 반복되는 불필요한 부분을 제거했습니다.

다음강좌에서는 컨트롤러부분을 좀 더 살펴보도록 하죠. 지금까지는 list만으로 예제를 해왔지만 detail, insert, update 부분도 만들어보도록 하겠습니다.

그럼 다음강좌에서...

 

MVC 여섯번째강좌 - MVC기법으로 입력 게시판 만들기

작성자 : 김시웅
테스트환경 : 이클립스2.1.2, mysql, tomcat4.1.30

지금까지는 리스트화면만으로 강좌를 해왔습니다. 이제부터는 나머지화면도 만들어보도록 하겠습니다.

먼저 Controller.java 로 갑니다. doProcess함수에서 jsp로 forward하는 부분을 함수로 만들겠습니다. 함수명은 forward 입니다.
   public void forward(HttpServletRequest request, HttpServletResponse response, String pageName) {
      ServletContext sc = getServletContext();   
      RequestDispatcher rd = sc.getRequestDispatcher(pageName);
      try {
         rd.forward(request, response);
      } catch(ServletException se) {
         se.printStackTrace();               
      } catch(IOException ie) {
         ie.printStackTrace();
      }
   }

그리고 액션명을 얻는 부분도 함수로 만들어보죠. 함수명은 getActionName 입니다.
   public String getActionName(HttpServletRequest request) {
      String servletPath = request.getServletPath();
      String actionName = servletPath.substring(servletPath.lastIndexOf("/") + 1);
      return actionName;
   }

이와같이 2개의 함수를 추가한뒤의 doProcess함수는 다음과 같습니다.
   public void doProcess(HttpServletRequest request, HttpServletResponse response) {
      System.out.println("컨트롤러 호출");
      String actionName = this.getActionName(request);
      if(actionName.equals("MvcList.action")) {
         BoardDAO dao = new BoardDAO();
         Vector listValues = dao.getList();
         request.setAttribute("listValues", listValues);
         
         this.forward(request, response, "/MvcList.jsp");
      }
   }

이제 doProcess함수도 어느정도 정리된 느낌이군요^^. 그럼 insert액션을 추가해보죠. MvcInsert.action 으로 하겠습니다.
      } else if(actionName.equals("MvcInsert.action")) {
      }

조건문내에 DAO를 생성하고 함수를 호출하면 되는데 그전에 한가지 준비해야할게 있습니다. 리스트에서 VO(View Object)를 만들었듯이 인서트에서는 TO(Transact Object)가 필요합니다.
TO는 테이블의 컬럼수와 같다고 보시면 됩니다. DB에 들어갈 오브젝트니까요. InsertTO를 만들겠습니다.
package javaforum.board;

/**
 * @author wwwoong
 */
public class InsertTO {
   private int num;
   private String name;
   private String subject;
   private String content;
   private String regiDate;
}

이와같이 만든후에 getter, setter로 함수를 만드세요.

그리고 DAO에 가서 함수를 하나 만들어야됩니다. insert(InsertTO to) 즉 컨트롤러에서 TO를 만든후 DAO의 insert함수에 건네주는 형태입니다. insert함수를 만들기전에 transact 함수를 먼저 만들겠습니다. 이것 역시 selectMultiRow함수와 마찬가지로 중복을 피하기 위해서 만드는겁니다.
   //insert, update, delete 문 형태
   public boolean transact(String query) {         
      Connection con = null;
      PreparedStatement ps = null;
      try {
         con = getConnection();
         con.setAutoCommit(false);
         ps = con.prepareStatement(query);
         ps.executeUpdate();      
         con.commit();
         return true;    
      } catch (SQLException e) {
         try {
            con.rollback();
         } catch(SQLException re) {
            re.printStackTrace();
         }
         System.out.println("query : " + query);
         System.out.println("transact sql : " + e);
         e.printStackTrace();
         return false;
      } finally {
         try {                              
            if(ps != null) ps.close();         
            if(con != null) con.close();      
         } catch(SQLException e1) {
            e1.printStackTrace();         
         }
      }
   }
   
   //insert, update, delete 문 형태(다중 트랜잭션처리)
   public boolean transact(String querys[]) {         
      Connection con = null;
      PreparedStatement ps = null;
      String query = null;
      try {
         con = getConnection();
         con.setAutoCommit(false);
         for(int i = 0; i < querys.length; i++) {
            query = querys[i];            
            ps = con.prepareStatement(query);
            ps.executeUpdate();
         }                        
         con.commit();
         return true;    
      } catch (SQLException e) {
         try {
            con.rollback();
         } catch(SQLException re) {
            re.printStackTrace();
         }
         System.out.println("query : " + query);
         System.out.println("transact sql : " + e);
         e.printStackTrace();
         return false;
      } finally {
         try {                        
            if(ps != null) ps.close();         
            if(con != null) con.close();      
         } catch(SQLException e1) {
            e1.printStackTrace();         
         }
      }
   }

쿼리가 하나일때와 다수일때에 대한 DB transact함수입니다. 내용은 금방 이해되실겁니다.

마지막으로 Board 테이블의 키인 num의 맥스값을 얻어오는 함수가 필요합니다.
   public int getMaxNum() {
      String query = "select max(num) from Board";      
      String maxStr = this.selectOneCol(query);
      int max = 0;
      if(maxStr != null && !maxStr.equals("")) {
         max = Integer.parseInt(maxStr);
      }               
      max++;
      return max;
   }
   
   //select문 형태(하나의 데이타)
   public String selectOneCol(String query) {
      String resultStr = null;
      Connection con = null;   
      PreparedStatement ps = null;
      ResultSet rs = null;
      ResultSetMetaData rmd = null;
      int columnCount = 0;
      try {
         con = getConnection();
         ps = con.prepareStatement(query);
         rs = ps.executeQuery();
         rmd = rs.getMetaData();
         columnCount = rmd.getColumnCount();
         if (rs.next()) {                        
            resultStr = rs.getString(1);                     
         } 
      } catch (SQLException e) {
         System.out.println("select sql : " + e);
         e.printStackTrace();
      } finally {
         try {
            if(rs != null) rs.close();                                 
            if(ps != null) ps.close();         
            if(con != null) con.close();               
         } catch(SQLException e1) {
            e1.printStackTrace();         
         }
      }
      return resultStr;
   }

getMaxNum 은 맥스값을 얻어서 1증가시킵니다. selectOneCol 은 하나의 데이타만을 얻어오는 함수입니다. 휴 사전공작 힘들군요.
이제 insert함수를 만들수 있습니다^^. 결과값은 boolean으로 넘어옵니다.
   public boolean insert(InsertTO to) {
      String query = 
         "insert into Board values(" +
            to.getNum() + ", " + 
            "'" + to.getName() + "'," +
            "'" + to.getSubject() + "'," +
            "'" + to.getContent() + "'," +
            to.getRegiDate() + ")"; 
      return this.transact(query);
   }

BoardDAO에서 할일은 다 한것같군요. Controller로 가서 redirect 함수를 만들겠습니다.
   public void redirect(HttpServletResponse response, String page) {
      try {
         response.sendRedirect(page);
      }         
      catch(IOException ie) {      
         System.out.println("sendRedirect IOException 에러 : " + ie);
         ie.printStackTrace();
      } catch(Exception e) {
         e.printStackTrace();
      }   
   }

redirect를 쓰게되면 클라이언트로 부터 요청을 받기때문에 이전의 url이 브라우저에 남지 않습니다.
이제 MvcInsert.action 조건문으로 갑니다. 다음을 추가합니다.
         BoardDAO dao = new BoardDAO();
         InsertTO to = new InsertTO();
         boolean isTrue = dao.insert(to);
         if(isTrue) {
            this.redirect(response, "/MvcList.action");
         }          

내용을 살펴보면 InsertTO를 만들고 insert함수를 호출한이후에 결과가 참이면 "/MvcList.action"으로 forward하는군요. 에러가 났다면 현재화면을 보여주면 되니깐 이동할 필요가 없겠죠^^.
아^^. 뭔가 빠진것같다구요? 맞습니다, to에 아무것도 입력하지 않았네요. 다음을 추가해줍니다.
         to.setNum(dao.getMaxNum());
         to.setName(request.getParameter("name"));
         to.setSubject(request.getParameter("subject"));
         to.setContent(request.getParameter("content"));
         to.setRegiDate("now()");

어디에 삽입해야할지는 아실겁니다. 완성된 doProcess함수를 보여드리죠^^.
   public void doProcess(HttpServletRequest request, HttpServletResponse response) {
      System.out.println("컨트롤러 호출");
      String actionName = this.getActionName(request);
      if(actionName.equals("MvcList.action")) {
         BoardDAO dao = new BoardDAO();
         Vector listValues = dao.getList();
         request.setAttribute("listValues", listValues);
         
         this.forward(request, response, "/MvcList.jsp");
      } else if(actionName.equals("MvcInsert.action")) {
         BoardDAO dao = new BoardDAO();
         InsertTO to = new InsertTO();         
         to.setNum(dao.getMaxNum());
         to.setName(request.getParameter("name"));
         to.setSubject(request.getParameter("subject"));
         to.setContent(request.getParameter("content"));
         to.setRegiDate("now()");
         boolean isTrue = dao.insert(to);
         if(isTrue) {
            this.redirect(response, "/MvcList.action");
         }          
      }
   }

근데 한가지 문제가 있군요. 인서트는 초기에 입력화면이 나오는 부분과 submit후에 입력내용을 DB에 넣는 부분이 구별되야합니다. 그래서 MvcInsert.action 을 호출할때 transact 파라미터를 추가하겠습니다. 즉 transact파라미터를 안쓰거나 transact="false" 일때는 초기입력화면이고 transact="true" 일때만 트랜잭션처리를 하도록 변경해야겠습니다.
         String transact = request.getParameter("transact");
         if(transact == null || transact.equals("false")) {
            this.forward(request, response, "/MvcInsert.jsp");
         } else if(transact.equals("true")){
            BoardDAO dao = new BoardDAO();
            InsertTO to = new InsertTO();         
            to.setNum(dao.getMaxNum());
            to.setName(request.getParameter("name"));
            to.setSubject(request.getParameter("subject"));
            to.setContent(request.getParameter("content"));
            to.setRegiDate("now()");
            boolean isTrue = dao.insert(to);
            if(isTrue) {
               this.redirect(response, "/MvcList.action");
            }          
         }

지금까지 insert를 추가하기 위해서 컨트롤러와 DAO의 내용을 변경했습니다. 이제 화면 MvcInsert.jsp만 만들면 됩니다.
<%@ page language="java" contentType="text/html; charset=euc-kr" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
<script language="javascript">
   function insert() {
      form = document.insertForm;   
      form.submit();         
   }
</script>   
<html>
   <body>
      <form name="insertForm" method="post" action="/MvcInsert.action">
      <input type="hidden" name="transact" value="true">
      <table border="1">
         <tr>
            <td>이름</td><td><input type="text" name="name"></td>
         </tr>
         <tr>
            <td>제목</td><td><input type="text" name="subject"></td>
         </tr>
         <tr>
            <td>내용</td><td><input type="textarea" name="content"></td>
         </tr>
         <tr>
            <td align="center"><a href="javascript:insert()">입력</a></td>
         </tr>
      </table>
      </form>
   </body>
</html>

그리고 MvcList.jsp에 <a href="/MvcInsert.action">글쓰기</a>를 추가합니다.

글입력이 잘되는지 테스트해보시기 바랍니다. 이것으로 MVC기초강좌를 마치겠습니다. 나머지 detail, update, delete는 여러분들이 직접해보시면 좀더 MVC에 대한 이해가 빠를거로 생각됩니다.

앞으로 MVC중급강좌, 커스텀태그와 jstl강좌, 아파치 digester강좌 등등을 준비하고 있습니다.
새로운 강좌에서 뵙겠습니다. 그럼 전 이만.....

반응형

'개발도 하냐?' 카테고리의 다른 글

전자세금계산서/세금계산서 업체 정보리스트  (0) 2009.10.29
Anyframe Doc  (0) 2009.09.16
Eclipse + JEUS  (0) 2009.08.19
약도 만들기  (0) 2009.08.14
아키텍쳐에 대한 정의  (0) 2009.08.07
반응형

다운로드는 adobe 사이트에서 가능.

아래의 시리얼넘버를 사용하면 인증가능.

1377-4267-4606-8473-1846-5071
1377-4162-2060-7589-3186-7349
1377-4664-9203-3069-2677-6577
1377-4160-7004-2800-3486-3166
1377-4169-2983-5039-4046-6761
1377-4368-4890-7299-6501-2232
1377-4261-1380-8492-9605-3306
1377-4765-1210-7438-1185-3189

반응형

'삽질로그' 카테고리의 다른 글

HTML 테이블 CSS  (0) 2009.11.04
UI Component  (0) 2009.10.07
DNS 서버  (0) 2009.08.02
태그클라우드 만들기  (3) 2009.07.31
웹에서 제공하는 이메일 이미지 생성과 로고생성을 이용해서 만든 이미지  (0) 2009.07.20
반응형
필수 파일
1. eclipse3.2
-http://www.eclipse.org

2. JMaker 3.2 plug-in
-http://technet.tmax.co.kr

3. JMaker license
-http://technet.tmax.co.kr

4. JEUS5.0

5. 이클립스에서 제우스 서버 구동하기
※ JMaker 3.2 plug-in 삽입
- 압축 풀기 후 eclipse3.2/  폴더 안에
   features 폴더와 plugins 폴더를 덮어쓰기 한다.

※ JMaker license 삽입
   신청하여 받은 license 파일을
   eclipse3.2/  폴더 안에 license 폴더를 생성하여 해당 파일을 추가한다.

※ Local JEUS Server 설정 및 실행
- eclipse를 실행하여 Servers View를 선택하고
   오른쪽 마우스를 클릭하여 New -> Server를 선택한다.

- Server's host name 은 'localhost' 삽입 후 Next

- JRE 와 JEUS Home Directory 확인 후 Next

- Node Name 은 '로컬 PC의 hostname',
  WebHome Directory는  JEUS의 'webhome'까  지 설정,
  유저 이름과 비밀번호를 작성한후 Finish

- JEUS Server를 start하여 jboot 확인한다.

- Ant Build(Alt + Shift + X + Q)를 시켜 jeus 서버로 컴파일한다.


[WebtoB, JEUS and Eclipse]

이번 포스트에서는 TmaxSoft 사의 JEUS와 WebtoB, 그리고 대표적인 자바 개발 툴인 Eclipse와 연동하는 방법에 대해 얘기하기 위해 필요사항을 정리하고, 설치하는 방법까지 알아보도록 하자.

    * 요구사항
          o JEUS 5.0 Fix#14 이상(http://technet.tmax.co.kr/)
          o WebtoB 4.1 이상(http://technet.tmax.co.kr/)
          o Eclipse 3.2(http://www.eclipse.org/)
          o JMaker 3.2 plugin(http://technet.tmax.co.kr/)

    이번 포스트에서는 MyEclipse나 TmaxSoft 사의 JMaker 3.2 SDK를 이용하지 않고, 오리지널 Eclipse과의 연동을 하므로 JMaker 3.2 plugin만 있으면 된다.

    JEUS, WebtoB, JMaker plugin은 TmaxSoft Technet 가입 후, 다운로드를 받아야 한다. 또한, 라이센스가 필요한데, 이 또한, Technet에서 신청 가능하다. 신청 즉시, 이메일로 발송되므로 기다리지 않아도 된다.

    각 제품 별로 데모 기간이 다르므로 라이센스 페이지의 '제품별 발급 라이센스 정보'를 잘 참조하도록 하자. 한가지 설명을 덧붙이자면, 라이센스 신청 시, Host ID 혹은 Host Name을 입력하도록 되어 있는데, 이는 윈도우 콘솔(윈도우키 + R)에서 각각 vol 명령과 hostname 명령으로 확인 가능하다. 단, vol명령의 경우, 해당 제품이 설치되는 디스크 드라이브으로 이동한 뒤, 확인해야 한다.(디스크 드라이브는 각자 고유의 volume이 존재한다.)

    * WebtoB 설치
          o 다운로드 받은 설치 파일을 실행하여 원하는 위치에 설치 하도록 한다.
          o 설치 중간, WebtoB + Servlet 설치 혹은 WebtoB 설치를 물어보는데 Servlet은 필요없으므로 WebtoB만 설치해도 무방하다.
          o 발급받은 라이센스 파일(license.dat)을 license 밑에 복사하여 옮긴다.
          o WebtoB 설정은 WebtoB 기동과 함께 JEUS와의 연동 부분에서 설명하도록 하겠다.
    * JEUS 설치
          o 다운로드 받은 설치 파일을 실행하여 원하는 위치에 설치 하도록 한다.
          o 발급받은 라이센스 파일의 확장자를 제거하고 license 밑에 복사하여 옮긴다.
          o JEUS를 설치하고 나면, Quick Start를 기동할 수 있는데, Quick Start에서 서버를 기동해 볼 수 있다. 정상적으로 서버가 기동되면 설치가 정상적으로 이루어진 것이다.
    * Eclipse 설치
          o Eclipse의 경우, 따로 설치가 필요하지 않고, 압축을 풀어놓기만 하면 된다.
    * JMaker 3.2 plugin 설치
          o JMaker 3.2 plugin은 Eclipse용 plugin이다. 압축 파일을 Eclipse 폴더에 풀기만 하면 설치가 된다.
          o JMaker 3.2 plugin에도 라이센스가 필요하다. Eclipse 폴더에 license 폴더를 새로 만들고 발급된 라이센스 파일을 확장자(dat)를 제거하고 옮겨놓도록 한다.
          o 설치 후, Eclipse를 기동해서, 아무런 경고 메세지가 발생하지 않는다면 정상적으로 설치된 것이다.

반응형

'개발도 하냐?' 카테고리의 다른 글

Anyframe Doc  (0) 2009.09.16
JSP_MVC 형식  (0) 2009.09.16
약도 만들기  (0) 2009.08.14
아키텍쳐에 대한 정의  (0) 2009.08.07
허드슨(Hudson)을 이용한 지속적인 통합(Continuous integration with Hudson)  (0) 2009.07.31
반응형

회사 약도

http://map.creation.net/ 에서 자신만의 지도를 만들어서 사용할 수 있다.



반응형
반응형
점심식사후 현재 학생들과 많은 교류를 하고 있는 송재혁교수님과 함께 이야기해본 최근 패션시장의 동향을 고려해 본 시스템.

유행에 민감한 학생들의 성향을 반영하기 위해서는 스타일리스트의 전문성 가미가 필수이므로, 스타일리스트에 의한 코디정보를 사용자의 모바일기기로 개인화된 코디정보를 전송해 주고, 사용자는 추천 스타일에 맞는 상품을 구매하게 되는 프로세스



비지니스의 성공을 위한 필수요소
1) 명성있는 스타일리스트
2) 최신유행정보
3) 신뢰할수있는 입점업체 상품정보

기술적 요구사항
1) 특화검색엔진(패션,유행)
2) 스타일추천을 위한 데이터마이닝
3) 다양한 그룹핑 옵션(연령,체형,선호스타일 등)
4) 모바일기기 인터페이스제공
5) 사용자의견을 API로 전송(블로그데이터의 전송, 모바일기기에서의 전송)
6) 미려한 Flex, Silverlight 기반의 UI

현재 howtocodi.co.kr / howtocodi.com 도메인은 등록되지 않은 상태이므로, 구체적인 실행단계에 들어가면 도메인 우선등록필요.

반응형

'취미 그리고 생각' 카테고리의 다른 글

하나노케이지  (0) 2010.01.11
abydos openvpn gui client  (0) 2009.12.05
openvpn Windows Client config dir  (0) 2009.08.09
좋은책 고르기  (0) 2009.08.08
시간관리에 대한 생각들  (0) 2009.08.07
반응형
반응형

'오픈소스SW' 카테고리의 다른 글

fckeditor에서 이미지경로를 위한 Tip  (0) 2010.05.13
PHP 게시판  (0) 2010.05.12
CentOs 5.2 vsftpd 설치  (0) 2009.08.10
CentOS 5.2 Final + BIND 9.3.4  (0) 2009.08.02
UML 지원 CASE Tool  (0) 2009.04.29
반응형
설치
yum install vsftpd


블랙리스트 확인
다음의 리스트에 등록되어 있는경우 원격접속이 불가능하다.
리스트를 확인후 수정이 필요

/etc/vsftpd/ftpusers // 다른 ftp의 경우 /etc에 있기도 했다.
/etc/vsftpd/user_list


포트 개방 20번 21번 (TCP만)
vi /etc/sysconfig/iptables

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 20 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 21 -j ACCEPT

service iptables restart

ip_nat_ftp, ip_conntrack_ftp
방화벽을 사용할 경우 다음의 커널 모듈을 로딩해 줘야 된다.
modprobe ip_nat_ftp
modprobe ip_conntrack_ftp

vsftpd 서비스가 실행될때 마다 로딩 하도록
/etc/init.d/vsftpd의 스타트부분에 넣어버렸다. 대략 아래와 같은 느낌으로

start() {
# Start daemons.

if [ -d /etc/vsftpd ] ; then
for i in `ls /etc/vsftpd/*.conf`; do
site=`basename $i .conf`
echo -n $"Starting $prog for $site: "
daemon /usr/sbin/vsftpd $i
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
echo
done

# for ftp connection error
modprobe ip_nat_ftp
modprobe ip_conntrack_ftp

else
RETVAL=1
fi
return $RETVAL
}



부팅시 기동 설정
chkconfig --list | grep ftp
chkconfig --level 2345 vsftpd on
chkconfig --list | grep ftp


실행
service vsftpd start
반응형

'오픈소스SW' 카테고리의 다른 글

PHP 게시판  (0) 2010.05.12
Automating Linux Unix  (0) 2009.08.11
CentOS 5.2 Final + BIND 9.3.4  (0) 2009.08.02
UML 지원 CASE Tool  (0) 2009.04.29
Timeline 소개  (0) 2008.12.26

+ Recent posts