레이블이 Java인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Java인 게시물을 표시합니다. 모든 게시물 표시

2010년 8월 19일 목요일

블로그 이전 했습니다.

텍스트 큐브에서 티스토리로 이전했습니다.

 

주소는

 

http://rooya85.tistory.com/

 

입니다.!

 

많은 관심 가져주세요~

2010년 8월 16일 월요일

@PathVariable 어노테이션을 이용한 URI 템플릿

RESTful 서비스가 유행하면서 URI를 다음과 같이 REST 방식으로 구성하는 경우가 있다.

 

 

기존에는 http://somehost/users/userinfo?id=madvirus 와 같이 파라미터를 이용해서 아이디나 이름을 전달받았다면, 이제는 URI에 아이디나 이름 등이 포함되도록 URL을 구성하고 있다.

 

스프링 3 버전에 추가된 기능 중 필자가 가장 반기는 기능 중의 하나가 URI 템플릿이며, 이 URI 템플릿을 이용하면 REST 방식의 URL 매칭을 쉽게 처리할 수 있다. URI 템플릿을 사용하는 방법은 매우 간단하며, 다음과 같이 두가지만 추가로 작업해주면 된다.

 

1. dispatcherServlet.xml 가장 밑에 다음을 추가한다.

 

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  <property name="alwaysUseFullPath" value="true"/>
 </bean>
 
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  <property name="alwaysUseFullPath" value="true"/>
 </bean>

 

2. web.xml 에 다음을 추가한다.

 

  <servlet-mapping>
   <servlet-name>dispatcher</servlet-name>
   <url-pattern>*.nar</url-pattern> // 적절한 이름을 사용한다.
   <url-pattern>/board/*</url-pattern>  // 적절한 이름을 사용한다. 

  </servlet-mapping>

 

3. 해당 Controller에 다음과 같은 변수를 사용한다.

 

@RequestMapping 어노테이션의 값으로 {템플릿 변수}를 사용한다.

@PathVariable 어노테이션을 이용해서 {템플릿 변수}와 동일한 이름을 갖는 파라미터를 추가한다.

 

실제 URI 템플릿이 적용된 코드는 다음과 같다. (수정 중)

 

스프링3.0의 세가지 Layer

Presentation Layer(Spring MVC, DispatcherServlet)

 

Business Layer - Service, Spring Container(Service Bean, DAO Bean 등의 DI 관계)

 

Data Layer

 

PL <-- Controller --> BL <-- DAO --> DL

 

 

2010년 7월 30일 금요일

Spring에서 파일을 포함한 Form 을 전송하고 업로드 하기


1. 먼저 form 태그에 다음의 프로퍼티를 추가한다.

 

enctype="multipart/form-data"

인코딩 타입이 Multipart 인 경우 파라미터나 업로드한 파일을 구할려면 전송 데이터를 알맞게 처리해 주어야 한다. 스프링은 Multipart 지원 기능을 제공하고 있기 때문에, 이 기능을 이용하면 추가적인 처리 없이 Multipart 형식으로 전송된 파라미터와 파일 정보를 쉽게 구할 수 있다.

 

2. MultipartResolver 설정

 

<bean id="multipartResolver"

 class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

</bean>

Multipart 지원 기능을 사용하려면 먼저 MultipartResolver를 스프링 설정파일에 등록해 주어야 한다. MultipartResolever 는 Multipart 형식으로 데이터가 전송된 경우, 해당 데이터를 스프링 MVC 에서 사용할 수 있도록 변환해준다.

 

라이브러리에 다음을 추가한다.

 

commons-fileupload / commons-fileupload

commons-io            / commons-io            <- 1.4 version

 

2.1. MultipartResolver의 Property

 Property  Type  Descript
 maxUploadSize  long  최대 업로드 가능한 바이트 크기. -1 은 체한이 없음을 의미한다, Default 는 -1
 maxInMemorySize  int  디스크에 임시 파일을 생성하기 전에 메모리에 보관할 수 있는 최대 바이트 크기, 기본값은 10240 바이트이다.
 defaultEncoding  String  요청을 파싱할 때 사용할 캐릭터 인코딩. 지정하지 않을 경우 HttpServletRequest.setCharacterEncoding() 메서드로 지정한 캐릭터 셋이 사용된다. 아무 값도 없을 경우 ISO-8859-1을 사용한다.

 

 

3. Controller 에서 데이터 받아오기.

 

컨트롤러의 파라미터에 값을 받아 넣을 때 다음의 소스를 입력한다.

@RequestParam("[inputName]") MultipartFile [paramName]

 

다음은 MultipartFile 인터페이스가 제공하는 주요 메서드 이다.

 

 Method  Descript
 String    getName()  파라미터의 이름을 구한다.
 String    getOriginalFilename()  업로드 한 파일의 이름을 구한다.
 boolean isEmpty()  업로드 한 파일이 존재하지 않는 경우 true를 리턴한다.
 long      getSize()  업로드 한 파일의 크기를 구한다.
 byte[]   getBytes() throws IOException  업로드 한 파일의 데이터를 구한다.
 InputStream getInputStream() throws IOException

 업로드 한 파일 데이터를 읽어오는 InputStream을 구한다,

 InputStream의 사용이 끝나면 알맞게 종료해 주어야 한다.

 void      transferTo(File dest) throws IOException  업로드 한 파일 데이터를 지정한 파일에 저장한다.

 

if (multipartFile.isEmpty)) {

//업로드 한 파일데이터를 구하는 가장 단순한 방법은 MultipartFile.getBytes() 메서드를 이용하는 것이다. 바이트 배열을 구한 뒤에 파일이나 DB 등에 저장하면 된다.

   byte[] fileData = multipartFile.getByte();

   ...

}

 

if (multipartFile.isEmpty)) {

//업로드 한 파일 데이터를 특정 파일로 저장하고 싶다면 MultipartFile.transferTo() 메서드를 사용하는 것이 편리하다.

   File file = new File(fileName);

   multipartFile.transferto(file);

   ...

}

 

 

 

Validation Check

Validation Check 는 Data의 검증을 뜻한다.

 

Validation Check의 방법에는 크게 3가지 가 있는데

 

    1. Client-Side VC : UI에서 JS를 이용해 체크한다.
    2. Server-Side VC : Java 에서 체크한다.
    3. Database Constraint VC : Key, check, Default 등으로 체크 한다.

위 세가지중 하나라도 배제한다면 잘못된 프로그래밍 습관을 가진것이다.

2010년 7월 29일 목요일

Integer 타입에서 자주 쓰는 API

1. 숫자를 문자로 변환하기.

입력되거나 변수에서 초기화 또는 대입된 숫자를 문자로 바꿀 수 있다.

  1. 문자변수 = Integer.toString(숫자 또는 숫자변수) // 숫자 또는 숫자변수를 문자변수에 형을 변환해서 저장한다.

Spring 타입에서 자주 쓰는 API

1. String 을 숫자로 변환하기.

int num = Integer.parseInt(문자);

 

숫자를 문자로 변환하거나, nextLine() 으로 입력받은 문자를 숫자로 변환하고자 할때 사용된다.

즉, 문자 부분에 들어갈 수 있는 것은 두가지가 있다.

순수한 문자열 또는 Scanner 가 있다.

 

2. 문자열 비교하기.

Scanner 로 입력받은 문자열은 단순한 문자열로는 비교할 수 없다.

하여 Scanner 로 입력받은  문자열은 String 타입의 특정 메서드를 사용하는데

종류는 크게 3가지가 있다.

  1. String.compareTo(문자)  // 문자와 문자사이에 존재하는 문자의 개수를 리턴한다. 즉, 반환값이 0이라면 같은 문자열이다.

  2. String.equals(문자) // 문자와 문자를 순수히 비교한다. 같다면 true, 틀리면 false 를 반환한다.

  3. String.equalsIgnoreCase(문자) // 문자와 문자를 비교하는데 대소문자 구분을 하지 않는다. 다시말하면 equals 는 대소문자를 구분한다.

 

3. 문자 추출하기

문자열은 앞의 문자와 뒤의 문자를 비교할 수 있다. 또한, 시작 위치를 지정하고 추출할 길이를 추출하면 해당 길이만큼의 문자를 추출해낼 수 있다.

  1. String.startsWith(문자) // String 이 문자로 시작하는지 판단한다. 참이라면 true, 거짓이면 false 를 반환한다.

  2. String.endsWidth(문자) // String 이 문자로 끝나는지 판단한다. 참이라면 true, 거짓이면 false 를 반환한다.

  3. String.subString(시작위치, 마지막위치) // String 에서 시작위치부터 마지막 위치까지의 문자열을 반환한다.

  3. 예제 abcdefg.subString(0, 3) =>> abc

페이징 로직

//페이지 처리

pageNum = Integer.parseInt(request.getParameter("pageNum")); //현재 페이지

totalRecord = 총 레코드 갯수;

paging = 페이지 당 보여질 게시물 수;

pageingCount = Math.ceil(totalRecord / paging); // 총 페이지 수

start = paging * pageNum; // 페이지의 시작위치

 

//페이지 그룹 처리

pageGroup = 페이지 그룹에 포함될 페이지의 수;

pageGroupNum = Math.ceil((pageNum+1) / pageGroup); // 현재의 페이지 그룹

pageStart = (pageGroupNum - 1) * pageGroup + 1; //페이지 그릅의 첫페이지

pageEnd = pageStart + pageGroup -  1; // 페이지 그룹의 마지막 페이지

 

// 이전 그룹 처리

prevGroup = pageGroupNum - 1; // 이전 그룹

prevStart = (prevGroup - 1) * pageGroup; // 이전 페이지 그룹의 첫페이지

if(pageGroupNum != 1) {

      ?pageNum=prevStart;

}

 

// 페이지 출력

int j = 0;

for(int i = pageStart; i < pageEnd; i++) {

    if(i > pageingCount) break;   

    j = i - 1;

    ?pageNum=j 

}

 

//다음 그룹 처리

nextGroup = pageGroupNum + 1; // 다음 그룹

nextStart = (nextGroup -1) * pageGroup; // 다음페이지 그룹의 첫페이지

if(pageingCount > (nextGroup+1)) {

     ?pageNum=nextStart

}

커넥션 풀을 이용한 DataSource 설정

스프링이 직접적으로 커넥션 풀 구현 클래스를 제공하진 않지만, DBCP API와 같은 커넥션 풀 라이브러리를 이용해서 커넥션 풀 기반의 DataSource를 설정할 수 있다. 아래 코드는 DBCP가 제공하는 BasicDataSource 클래스를 이용해서 DaeaSource를 설정하는 예제이다.

 

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

  <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />

  <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE" />

  <property name="username" value="[username]" />

  <property name="password" value="[password]" />

  <property name="initialSize" value="5" />

</bean>

위 설정내용은 commonContext.xml 로 저장하고

web.xml 에서 로드한다.

 

그 뒤 Dao 가 쓰이는 곳에 bean property로 등록하면 완료!

Bean 파일을 분리하는 방법

web.xml 에 아래의 내용을 추가한다.

 

<context-param>

  <param-name>contextConfigLocation</param-name>

  <param-value>

    WEB-INF/config/xml 파일 이름

    ...

  </param-value>

</context-param>

 

<listener>

  <listener-class>

    org.springframework.web.context.ContextLoaderListener

  </listener-class>

</listener>

이렇게 하면 WEB-INF 의 config 밑에 있는 xml 파일중 등록된 xml 파일을 로딩하게 된다.

JUnit Test Framework 사용하기

JUnit 은 TDD 개발방식을 구현(?) 할 수 있게 하는 Framework 이다.

 

사용법 :

프로젝트를 Maven 으로 만든 후

Springframework Defenndency 를 추가한 후

Junut : Junit Defendency 를 추가 한 뒤

Maven Package 를 실행한 뒤에

Target의 라이브러리를 Webapp 의 라이브러리로 복사해 넣는다.

 

그 뒤에 src/main/java 와 src/test/java 쪽에 도메인/패키지 명을 동일하게 만든 뒤

Test 패키지 쪽에 테스트클래스명+Test 형식의 클래스 파일을 만든다.

 

코딩 중 다른 클래스를 만들게 되면 src/main/java에 만들도록 한다.

 

그 뒤에

테스트하고자 하는 메소드를 코딩 한 뒤에 Run As -> JUnit Test 를 실행하면 되는데,

이때 메소드 명 위에 마다 @Test 어노테이션이 존재하여야 JUnit Framework가 인식 할 수 있다.

 

실행하고 나면 이클립스 창 아래에 JUnit 이라는 탭이 생기는데

이 탭의 오른쪽 상단에 빨간색과, 녹색의 줄 중 하나의 줄이 생긴다.

 

빨간색 줄은 소스에 오류가 있어 테스트를 통과하지 못했다는 것이고

녹색 줄은 테스트를 통과했다는 것이다.

2010년 7월 28일 수요일

Java Map(HashMap, TreeMap, Hashtable)

1. Collection
  • Map은 key와 value를 가진 집합이며, 중복을 허용하지 않는다.
  • 즉, 한개의 key에 한개의 value가 매칭된다.
  • java.util 패키지에 여러 집합들을 사용하기 위한 여러 interface와 class 들이 정의되어 있다.
2. HashMap
  • HashMap은 Map interface를 implements 한 클래스로서 중복을 허용하지 않는다.
  • Map의 특징인 key와 value의 쌍으로 이루어지며, key 또는 value 값으로써 null을 허용한다.
  • 아래의 예는 HashMap을 사용한 간단한 예제이다.

    import java.util.*;

    public class HashMapTest
    {
        public static void main(String argv[])
        {
            HashMap hm = new HashMap();
            System.out.println(hm.put("aaa", "111"));
            System.out.println(hm.put("bbb", "222"));
            System.out.println(hm.put("aaa", "444"));
            System.out.println(hm.put("ccc", "333"));   
            System.out.println(hm.put("ccc", null));      
           
            System.out.println("HashMap size : " + hm.size());
           
            Set set = hm.keySet();
            Object []hmKeys = set.toArray();
            for(int i = 0; i < hmKeys.length; i++)
            {
                String key = (String)hmKeys[i];  
                System.out.print(key);
                System.out.print(" - ");
                System.out.println((String)hm.get(key));
            }
        }
    }


    /**
    실행:java HashMapTest
    결과:
    null
    null
    111
    null
    333
    HashMap size : 3
    ccc - null
    bbb - 222
    aaa - 444
    */

3. TreeMap
  • TreeMap역시 중복을 허용하지 않으며, key와 value의 쌍으로 이루어져 있다.
  • HashMap과 다른 점은 SortedMap을 implements 하였으므로, key 값들에 대한 정렬이 이루어진다는 점이다.
  • 아래의 예는 TreeMap을 사용하여 각 요소가 몇몇 이나 나왔는지 알아보는 간단한 예제이다.

    import java.util.*;

    public class Freq
    {
        private static final Integer ONE = new Integer(1);

        public static void main(String args[])

        {
            Map m = new TreeMap();

            // Initialize frequency table from command line
            for (int i=0; i < args.length; i++)

            {
                Integer freq = (Integer) m.get(args[i]);
                m.put(args[i], (freq==null ? ONE :
                                new Integer(freq.intValue() + 1)));
            }

            System.out.println(m.size()+" distinct words detected:");
            System.out.println(m);
        }
    }


    /**
    실행:java Freq if it is to be it is up to me to delegate
    결과:
    8 distinct words detected:
    {be=1, delegate=1, if=1, is=2, it=2, me=1, to=3, up=1}
    */

4. Hashtable
  • Hashtable Map interface를 implements 한 클래스로서 중복을 허용하지 않는다.
  • Map의 특징인 key와 value의 쌍으로 이루어지며, key 또는 value 값으로써 null을 허용하지 않는다.(HashMap과의 차이점)
  • 아래의 예는 HashTable을 사용한 간단한 예제이다.

    import java.util.*;

    public class HashtableTest
    {

        public static void main(String argv[])
        {
            Hashtable ht = new Hashtable();
            System.out.println(ht.put("aaa", "111"));
            System.out.println(ht.put("bbb", "222"));
            System.out.println(ht.put("aaa", "444"));
            System.out.println(ht.put("ccc", "333"));   
           
            System.out.println("Hashtable size : " + ht.size());
           
            System.out.println("aaa value : " + (String)ht.get("aaa");
           
        }
    }


    /**
    실행:java HashMapTest
    결과:
    null
    null
    111
    null
    Hashtable size : 3
    aaa value : 444
    */

    출처 : http://pelican7.egloos.com/881589

Spring MVC를 이용한 웹 요청 처리

스프링 MVC를 이용한 웹 요청 처리



구성요소

DispatcherServlet : 클라이언트의 요청을 전달받음. 컨트롤러에게 클라이언트의 요청을 전달하고 컨트롤러가 리턴한 결과 값을 view에 전달하여 알맞은 응답을 생성하도록 한다.

HandlerMapping : 클라이언트의 요청 URL을 어떤 컨트롤러가 처리할 지를 결정

Controller : 클라이언트의 요청을 처리한 뒤, 그 결과를 DispatcherServlet에 알려줌.

ModelAndView : 컨트롤러가 처리한 결과 정보 및 뷰 선택에 필요한 정보를 담는다.

ViewResolver : 컨트롤러의 처리 결과를 생성할 뷰를 결정

View : 컨트롤러의 처리 결과 화면을 생성


캐릭터 인코딩 처리를 위한 필터 설정

요청 파라미터의 캐릭터 인코딩이 ISO-8859-1이 아닌경우, request.setCharacterEncoding() 메소드를 사용해서 요청 파라미터의 캐릭터 인코딩을 설정해 줘야 하는데 모든 Controller에서 이 코드를 실행할 수 있지만 그것보다는 서블릿 필터를 이용해서 원하는 요청에 코드를 적용하는것이 더 편리.


web.xml에 추가
 <filter>
  <filter-name>encodingFilter</filter-name>
  <filter-class>
   org.springframework.web.filter.CharacterEncodingFilter
  </filter-class>
  <init-param>
   <param-name>encoding</param-name>
   <param-value>UTF-8</param-value>
  </init-param>
 </filter>

 <filter-mapping>
  <filter-name>encodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>



웹 요청과 컨트롤러 매핑 : HandlerMapping의 구현 클래스

- SimpleUrlHandlerMapping
- BeanNameUrlHandlerMapping
- ControllerClassNameHandlerMapping
- DefaultAnnotationHandlerMapping

컨트롤러 종류

- Controller
- AbstractController
- AbstractCommandController
- SimpleFormController
- AbstractWizardFormController
- ParameterizableViewController
- UrlFilenameViewController
- MultiActionController


Annotatiln을 이용한 Controller의 구현

더 자세히


예외처리

interface Controller의 handleRequest() 메소드는 Exception을 발생할 수 있도록 정의

Controller는 서블릿과 관련된 ServletException뿐만 아니라 NullPointerException과 같은 RuntimeException등 다양한 예외를 발생시킬 수 있다.

보통은 서블릿 엔진이 제공하는 에러 화면이 웹 브라우저에 출력되는데 만약 예외에 따라 알맞은 에러 화면을 출력하고 싶다면 HandlerExceptionResolver를 사용하면 된다.
DispatcherServlet은 HandlerExceptionResolver가 등록되어 있을 경우, 예외 처리를 HandlerExceptionResolver에 맡긴다.

SimpleMappingExceptionResolver 클래스는 HandlerExceptionResolver 인터페이스를 구현하고 있으며, 스프링에서는 현재 SimpleMappingExceptionResolver 클래스만을 제공하고 있다.

 

출처 : http://flyburi.com/301

2010년 7월 27일 화요일

Spring MVC의 주요 구성요소 및 처리 흐름

 구성 요소 설 명
 DispatcherServlet  클라이언트의 요청을 전달받는다. 컨트롤러에게 클라이언트의 요청을 전달하고, 컨트롤러가 리턴한 결과값을 View에 전달하여 알맞은 응답을 생성하도록 한다.
 HandlerMapping  클라이언트의 요청 URL을 어떤 컨트롤러가 처리할지를 결정한다.
 Controller  클라이언트의 요청을 처리한 뒤, 그 결과를 DispatcherServlet에 알려준다, 스트럿츠의 Action과 동일한 역할을 수행한다.
 ModelAndView  컨트롤러가 처리한 결과 정보 및 뷰 선택에 필요한 정보를 담는다.
 ViewResolver  컨트롤러의 처리 결과를 생성할 뷰를 결정한다.
 View  컨트롤러의 처리 결과 화면을 생성한다. JSP나 Velocity 템플릿 파일 등을 뷰로 사용한다.


이들 각 구성 요소의 메시지 흐름은 다음과 같다.

1. 클라이언트의 요청이 DispatcherServlet에 전달된다.

2. DispatcherServlet은 HandlerMapping을 사용하여 클라이언트의 요청을 처리할 컨트롤러의 객체를 구한다.

3. DispatcherServlet은 컨트롤러 객체를 이용해서 클라이언트의 요청을 처리한다.

4. 컨트롤러는 클라이언트의 요청 처리 결과 정보를 담은 ModelAndView 객체를 리턴한다.

5. DispatcherServlet은 ViewResolver로부터 응답 결과를 생성할 뷰 객체를 구한다.

6. 뷰는 클라이언트에 전송할 응답을 생성한다.

 

이 과정에서 개발자가 직접 개발해야 할 부분은 클라이언트의 요청을 처리할 컨트롤러와 클라이언트에 응답 결과 화면을 전송할 JSP나 Velocity 템플릿 등의 뷰 코드이다. 나머지 DispatcherServlet이나 HandlerMapping, ViewResolver 등은 스프링이 기본적으로 제공하는 구현 클래스를 사용하게 된다.

MVC 패턴

Model -> 서비스

View  -> UI

Controller -> 서비스 + UI

 

MVC 패턴은 계산하는 로직과 화면을 구성하는 로직을 분리 하자는 목적의 패턴이 Model2 방식이 된다.

 

1. 요청을 처리해서 응답을 해주는 컨트롤이 필요. -> DispatcherServler

2. 비즈니스 로직 처리 -> Controller(서비스)

3. 화면을 구성. -> JSP

 

JSP의 기능이 단축된다. : 화면만 구성한다. 로직이 들어가지 않는다. 스크립트릿은 필요없다.

 

요청/응답 컨트롤

 요청과 응답만을 전담으로 처리한다.

 DispatcherServlet 이 처리한다. 즉, Model2 방식에서의 모든 요청은 DispatcherServlet 이 한다.

 DispatcherServlet 은 보안에서도 유리하다. Post, get 이 노출이 되지 않는다.

 

2010년 7월 25일 일요일

Maven WTP Project 생성하기

1. CMD를 실행.

2. 워크스페이스로 이동한다.

3. 워크스페이스 폴더에서 다음과 같이 입력한다.

 

mvn archetype:generate -DgroupId=package.name -DartifactId=ProjectName

-DarchetypeArtifactId=maven-archetype-webapp

위와 같이 입력하면 워크스페이스에 ProjectName 이라는 폴더가 생기면서 프로젝트 폴더의 구색을 갖추게 된다.

 

Maven 기반 웹 프로젝트의 기본 디렉토리는 src/main/webapp이다. webapp 디렉토리는 자바 기반 웹 애플리케이션의 기본 웹 디렉토리 구조를 따른다. Maven Archetype에 의하여 기본으로 생성되는 war 프로젝트는 자바 소스 코드를 관리하기 위한 src/main/java, src/test/java 디렉토리를 생성하지 않는다. 따라서 웹 자원과 자바 소스 코드를 같이 관리하려면 src/main/java, src/test/java 디렉토리를 추가해야한다.

 

그 다음으로 할일은 maven 프로젝트의 pom.xml 을 수정해야 한다.

 

pom.xml 파일은 maven 프로젝트의 설정을 관리한다.

 

여튼,

 

메이븐으로 만들어진 기본 pom.xml 파일의 내용은 다음과 같다.

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>net.narsha</groupId>
  <artifactId>Address</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Address Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

 

위의 설정에서 몇가지를 추가해야하는데 그 내용으로는, 이클립스에서 사용가능하도록 컴파일러 플러그인과, 메이븐 이클립스 플러그인, 그리고 인코딩 설정을 담고 있다.

 

여튼 추가해보도록 하자.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>net.narsha</groupId>
  <artifactId>Address</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Address Maven Webapp</name>
  <url>http://maven.apache.org</url>
 <properties>
   <webapp.context>/</webapp.context>
   <maven.compiler.source>1.5</maven.compiler.source>
   <maven.compiler.target>1.5</maven.compiler.target>
   <maven.compiler.encoding>utf-8</maven.compiler.encoding>   
  </properties> 
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
   <finalName>Address</finalName>
   <plugins>
    <plugin>
     <artifactId>maven-compiler-plugin</artifactId>
     <configuration>
      <source>${maven.compiler.source}</source>
      <target>${maven.compiler.target}</target>
      <encoding>${maven.compiler.encoding}</encoding>
     </configuration>
    </plugin>
    <plugin>
        <artifactId>maven-eclipse-plugin</artifactId>
      <version>2.4</version>
      <configuration>
       <wtpContextName>${webapp.context}</wtpContextName>
       <downloadSources>true</downloadSources>
       <downloadJavadocs>true</downloadJavadocs>
       <wtpversion>1.5</wtpversion>
      </configuration>     
     </plugin>
    </plugins>
   </build>
</project>

 

위와같이 설정을 추가했으면 다시 cmd 로 돌아가 방금 생성한 프로젝트폴더로 이동한 다음

다음과 같이 입력한다.

 

mvn eclipse:clean eclipse:eclipse

 

이 명령은 Maven 기반의 프로젝트를 이클립스에서 실행할 수 있도록 만들어 준다.

입력 후 실행을 하고 BUILD SUCCESS 가 출력된다면, 빌드에 성공한것이다.

 

그 다음, 할일은 이클립스에서 Import 를 해주는데 General - Existing Projects into Workspace 로 들어간 뒤

Select root directory 에서 메이븐 프로젝트를 선택 한 후 Finish 를 누르면 메이븐 프로젝트 -> 이클립스 프로젝트로 완성이 된다.

 

 

2010년 7월 23일 금요일

Trac, Apache, SVN 연동하기

프로젝트의 운영관리에서 이슈관리, 버전관리, 배포관리를 위한 관리 툴 SVN 과 Trac의 연동을 해보자.

SVNTrac은 설치에서 사용 및 응용이 쉽다. 때문에 빠르게 전파되어 지금은 많은 개발자들이 사용하는 관리 툴이 아닌가 한다. 간단하게 설명하고 바로 설치 및 연동을 해보기로 한다.


Python으로 작성된 오픈소스로 웹기반의 프로젝트 관리 및 버그 추적 툴.
Trac은 버전관리 프로그램(SVN)의 웹 인터페이스
개선점 및 버그와 같은 각종 이슈의 트래킹
위키 커뮤니티를 통한 문서의 관리 기능을 제공.





서버-클라이언트 모델로 서버와 클라이언트는 http, https, svn, svn+ssh의 규약으로 통신한다.
단위 등록이 가능하므로, 다른 사용자의 등록과 엉키지 않는다.
이름을 변경, 복사, 삭제시에도 리버전 기록을 유지한다.
파일의 저장 후 변경될 경우 차이점만 저장하기 때문에 저장소의 효율이 높다.
디렉토리도 버전관리 할 수 있다.
디렉토리 전체를 빠르게 이동, 복사 가능하며, 리버전 기록도 그대로 유지한다.
저장소의 크기에 상관 없이 일정 시간안에 branching, tagging 할 수 있다.
저장소의 접근이 최적화 되어 있어, 네트워크 트래픽을 줄일 수 있다.




 
Apache + SVN + Trac 연동
3가지의 소프트웨어를 연동하게 되면 보다 쉽게 프로그램의 컨트롤이 가능하다.
Apache와 SVN을 연동하여 http통신 규약으로 SVN 컨트롤이 가능하다.
SVN과 Trac을 연동하여 Trac을 통한 SVN저장소의 조회/관리가 가능하다.
또한 Trac을 통하여 SVN으로 관리되고 있는 소프트웨어 및 소스코드를 배포 할 수 있다.
이제 순서에 따라 프로그램의 설치 및 연동설정을 해보자.



Download Program:다운로드 프로그램
  1. SVN: Setup-Subversion-1.6.5.msi
    (Apache 2.2 버전과 연동하기 위해 Apache 2.2 버전용 파일을 다운로드 받는다.)

    2009년 10월 27일 Setup-Subversion-1.6.5.msi(Apache 2.2.x)다운로드 URL
  2. SVN Client Gui Tool: TortoiseSVN-1.6.6.17493-win32-svn-1.6.6.msi
    (일명 거북이(TortoiseSVN)를 다운로드 받는다.)

    2009년 10월 27일 다운로드 URL
  3. Apache(아파치): apache_2.2.9-win32-x86-no_ssl-r2.msi
    (Apache 2.2.x 버전을 다운로드 받는다. ssl을 사용할 경우 openssl 포함 버전을 받는다.)

    2009년 10월 27일 2.2.14 no ssl 버전 다운로드 URL
    2009년 10월 27일 2.2.14 openssl 버전 다운로드 URL
  4. Python(파이슨): python-2.5.msi
    (Python 2.5 버전을 다운로드 받는다. 현재 2.6 버전까지 나와있지만 현재 Trac 및 SVN을 Apache와 연동하기 위한 연동 모듈이 2.5 버전으로 작성되어 있으므로 2.6버전을 설치하면 연동이 불가능 하다.)

    2009년 10월 27일 다운로드 URL
  5. Apache 와 SVN 연동 모듈: svn-python-1.6.5.win32-py2.5.exe
    (Apache 와 SVN의 연동 모듈로 파악.
    버전이 맞지 않을때 증상: SVN 설치, Apache 연동, Trac 생성까지는 문제가 없다. 이후 Trac 사이트를 열게되면 사이트가 열리지 않고 브라우저 에러가 발생후 페이지 표시할 수 없음을 볼 수 있다.)

    2009년 10월 27일 다운로드 URL
  6. Genshi: Genshi-0.5.1.win32-py2.5.exe

    2009년 10월 27일 다운로드 URL
  7. setuptools: ez_setup.py
  8. mod_python: mod_python-3.3.1.win32-py2.5-Apache2.2.exe
    (설치된 Apache 버전을 확인하여 사용 가능한 모듈을 다운로드 받는다.)

    modpython 사이트 : http://www.modpython.org/
    2009년 10월 27일 다운로드 URL
  9. pysqlite: pysqlite-2.5.5.win32-py2.5.exe
    2009년 10월 27일 다운로드 URL
  10. enscript: enscript-1.6.3-9-bin.exe
    2009년 10월 27일 다운로드 URL
  11. trac: easy_install http://svn.edgewall.org/repos/trac/tags/trac-0.11
    (현재 사이트에 등록되어있는 0.11.5 버전을 설치하게 되면 에러가 발생한다. easy install을 사용하여 설치하면 이상없이 사용 가능하다.)



다운로드 해야할 파일이 생각 이상으로 많았다.
그리고 각각의 프로그램이 버전별로 다양하여 버전을 맞추는 것도 중요한 포인트 이다.
각각의 프로그램 및 모듈에 대한 보다 자세한 정보를 알고 싶을때에는 하단에 참고도서를 구매하여 읽어보면 많은 도움이 될것이라 생각한다.



Install & Setting:설치에서 연동까지

 ※주의 : 본 내용은 SVN, 아파치, Trac에대한 설치 위주의 설명이다 때문에 사용법등은 자세하게 기록하고 있지 않다. 사용법에 대한 설명이 필요하신 분은 댓글로 문의 부탁드립니다. 

1. SVN, SVN Client Tool 설치
위자드 형식의 설치를 지원하며 특별한 처리 없이 Next를 눌러 설치 한다.
(하단의 처리 내용은 기본설치 디렉토리 기준으로 설명을 합니다. 즉 C:\Program Files\Subversion 에 설치가 되어 있다는 가정을 합니다.)

2. SVN 저장소 만들기
명령 프롬프트를 실행한다.
c:>mkdir c:\repos
c:>cd c:\repos
c:\repos>svnadmin create sample

svnadmin 명령어를 사용하여 저장소를 생성할때에는 원하는 위치의 디렉토리로 이동 후에 생성할 저장소 명을 입력합니다.

C 드라이브의 repos 디렉토리에 sample 저장소를 생성 했다.
이 후 권한/계정/비밀번호 설정을 한다.
(SVN 사용법에 대한 검색을 하시면 쉽게 찾아볼 수 있습니다. 따로 설명하지 않습니다.)

3. SVN 저장소 실행
SVN 저장소가 정상적으로 생성 및 작동하는지 확인 하기 위하여 server를 실행한다.

명령 프롬프트를 실행한다.
svnserve.exe -d -r c:\repos
일반모드 실행(기본포트:3690) : 포트는 따로 설정하지 않고 기본포트를 사용한다.
SVN Client Tool을 사용하여 CheckOut 테스트를 하여 서버의 이상 유무를 확인 한다.

4. Apache 설치
2.2.x 버전을 설치한다.

5. Apache에 SVN 모듈 설치
httpd.conf 파일을 열어 다음설정을 추가
LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module "C:\Program Files\Subversion\bin\mod_dav_svn.so"
LoadModule authz_svn_module "C:\Program Files\Subversion\bin\mod_authz_svn.so"

※ httpd.conf 파일은 아파치 설치 디렉토리의 bin 디렉토리에서 찾을 수 있습니다.
대략 60라인에서 LoadModule라는 단어를 찾을 수 있습니다.
위 내용의 모듈을 추가합니다.


6. SVN + Apache 연동

연동 모듈을 conf 파일에 명시한 후 Apache에서 사용할 계정/비밀번호를 설정한다.

비밀번호 설정 파일 생성
명령 프롬프트를 실행한다.
c:>cd c:\repos
c:>"C:\Program Files\Apache Software Foundation\Apache2.2\bin\htpasswd.exe" -c htpasswd admin
권한 설정 파일 생성
authz 파일을 저장소 Root (c:\repos)에 생성.
파일을 메모장 등의 편집기를 통하여 다음과 같이 작성한다.
[sample:/]
admin = rw
* =


정상적으로 진행하였다면 C 디렉토리에는 다음의 디렉토리 및 파일을 찾을 수 있다.


httpd.conf 파일에 다음설정을 추가
NameVirtualHost *:80
<VirtualHost *:80>
 <Location /svn>
  DAV svn
  SVNParentPath "C:\repos"

  AuthzSVNAccessFile "C:\repos\authz"

  AuthType Basic
  AuthName "Well Come !! Drake World"
  AuthUserFile "C:\repos\htpasswd"
  Require valid-user
 </Location>
</VirtualHost>

conf 파일을 수정한 이후 Apache를 Stop 시킨 후 Start 하여 http://localhost/svn/sample를 입력하여 저장소에 접근이 가능한지 확인 한다.
또한 SVN Client Tool을 사용하여 http 통신 규약으로 저장소의 접근 및 관리가 가능한지 확인 한다.

※ 지금까지 순서에 맞게 진행하였다면 Apache 와 SVN의 설치에서 연동까지 확인이 가능할 것이다. 이제 Apache 와 SVN의 설치 및 연동을 완료하였다. 아직 갈 길이 멀다. 담배 한가치 태우면서 휴식을 취하자.







충분히 휴식을 취하였는가? 그럼 상당히 애먹을 수 있을 작업을 시작해보자.
위의 다운로드에서 가볍게 언급하고 지나갔지만 연동을 위해서 필수적으로 체크해야 하는 부분은 각각의 주요 프로그램들의 버전 정보의 확인 및 일치 작업이다.

확인 및 일치 시켜야 할 버전 정보
Apache 2.2.x
SVN 1.6.x
Python 2.5
Trac 0.11

다운로드 파일 목록의 버전 정보를 확인 후에 다운로드 파일의 버전이 일치 하지 않는다면 다시 맞는 버전을 다운로드 받는다. 설치 중 설치가 되지 않거나, 설치가 되어도 정상 작동을 하지 않는다.

7. Trac 설치
※ 주의:python, svn, apache, trac 등의 버전을 확인하여 모두 일치할 수 있도록 한다.

a. python 설치 : python-2.5.msi 실행
b. svn-python 설치 : svn-python-1.6.5.win32-py2.5.exe 실행
svn 과 python의 버전을 확인하여 설치된 버전에 맞는 프로그램을 설치

c. Genshi 설치 : Genshi-0.5.1.win32-py2.5.exe 실행
d. setuptools 설치  : ez_setup.py 실행
e. mod_python 설치
mod_python-3.3.1.win32-py2.5-Apache2.2.exe 실행
apache 버전을 확인하여 설치된 버전에 맞는 프로그램을 설치
httpd.conf 파일에 다음설정을 추가

LoadModule python_module modules/mod_python.so

f. pysqlite 설치 : pysqlite-2.5.5.win32-py2.5.exe 실행
g. enscript 설치 : enscript-1.6.3-9-bin.exe 실행
h. trac 설치
※ 참고한 서적에 나와있는 설치 버전과 지금 현재의 최신 버전은 버전의 차이가 있다. 또한 지금까지 설치한 다른 모듈 및 프로그램과의 버전 문제가 있어서 쉽게 설치 되지 않았다.

현재까지 필자가 제시한 모듈 및 프로그램을 그대로 다운로드 하여 설치한다면 Trac을 다음과 같이 설치해보자.
easy install을 사용하여 설치하는 방법으로 Python을 2.5로 설치 하였다면 C:\python25\script 디렉토리에서 easy_install 또는 easy_install.exe 파일을 발견할 수 있다.

명령 프롬프트를 실행한다.

c:>cd c:\python25\script
c:\python25\script>easy_install http://svn.edgewall.org/repos/trac/tags/trac-0.11

easy install을 실행하여 0.11 버전의 trac을 설치 한다.

8. Trac 생성
지금까지 설치가 정상적으로 되었다면 다음 명령어를 통하여 Trac을 생성 할 수 있다.

Trac의 Root 디렉토리로 사용할 디렉토리(C:\trac)를 생성한다.
명령 프롬프트를 실행한다.

c:\Python25\Scripts>trac-admin.exe c:\trac\sample initenv

※ 명령어 설명
 - trac-admin.exe : trac 프로젝트를 생성하는 명령어
 - c:\trac\sample : trac root 디렉토리 c:\trac에 sample 라는 trac을 생성
 - initenv : 생성 명령어

Trac이 정상적으로 설치 되어 있다면 다음과 같은 화면을 보게된다.



[My Project] 에는 프로젝트 명으로 sample 를 입력.
[sqlite:db/trac.db] 엔터를 입력하면 기본 설정된다.
[svn] 저장소의 저장 형태를 입력하는 부분으로 엔터를 입력하면 기본 설정된다.
[/path/to/repos] 저장소의 path를 입력한다.

마지막 엔터를 입력한 순간 Trac이 생성된다. 모듈이 모두 정상적으로 설치되어 있다면 Congratulations! 라는 메시지를 보게되면 그렇지 않다면 오류가 나는 부분의 에러를 확인 할 수 있다.
대부분의 에러는 버전이 일치하지 않아 발생한다.

9. svn + apache + trac 연동설정
마지막으로 apache 와 trac를 연동하여 웹 브라우저를 통하여 확인해 보자.

httpd.conf 파일의 <VirtualHost> 태그의 자식 노드로 다음 내용을 추가한다.
위에서 SVN과 Apache를 연동하기 위하여 Location 설정을 해보았다.
기본 입력 Host에 Trac의 입력 Location을 추가하는 과정이다.
NameVirtualHost *:80
<VirtualHost *:80>
 <Location /svn>
  DAV svn
  SVNParentPath "C:\repos"

  AuthzSVNAccessFile "C:\repos\authz"

  AuthType Basic
  AuthName "Subversion repository"
  AuthUserFile "C:\repos\htpasswd"
  Require valid-user
 </Location>

 <Location /trac>
  SetHandler mod_python
  PythonHandler trac.web.modpython_frontend
  PythonOption TracEnvParentDir "C:\trac"
  PythonOption TracUriRoot "/trac"
 </Location>

 <LocationMatch "/trac/[^/]+/login">
  AuthType Basic
  AuthName "Trac"
  AuthUserFile "C:\repos\htpasswd"
  Require valid-user
 </LocationMatch>

</VirtualHost>

주의를 기울여 보면 알겠지만 C:\repos에 위치하는 htpasswd 파일을 같이 사용하여 관리한다.

10. SVN + Apache + Trac 연동확인
모든 작성이 완료되면 Apache 서버를 정지 후 다시 실행 시킨다. Restart를 하면 설정정보를 다시 읽어오지 않기 때문에 Stop 후 Start 하여 실행한다.

인터넷 브라우저를 열고 http://localhost/trac를 입력하여 정상작동을 확인한다.
생성한 sample 프로젝트의 링크를 클릭하여 정상작동을 확인한다.

이후의 설정 및 다양한 추가 설정은 스스로 확인 해보자.
아래 추천하는 서적을 읽어보면 필요하다 싶은 내용은 다 나와있다.


참고 자료
위에 설명된 내용은 기존에 알고 있던 몇가지 사항 외에는 많은 부분을 책에서 도움받았다.

윈도우 프로젝트 필수 유틸리티 - 10점
이재홍 지음/한빛미디어


프로젝트의 운영관리를 위한 개발환경의 구성과 필요한 유틸리티들이 잘 소개되어 있다.
본문의 내용중에 나온 SVN 과 Trac의 보다 많은 사용법과 특징, 개념 등에 대한 설명이 잘 되어있는 편이다. 그리고 쉽고 필요 요소만이 설명되어 있기 때문에 부담없이 볼수 있는 책이다.

책에대한 자세한 내용은 다음에 독후감의 형식을 빌려 소개하기로 하자.

프로그램 파일의 대부분은 Google 검색을 통하여 찾았다.
아직은 원하는 내용의 프로그램들을 한번에 다운로드 하여 통합 설치하는 형식의 것들은 나와있지 않다.
그리고 버전에 맞는 프로그램을 다운로드 하는 것 또한 만만한 일이 아니였다.


출처 : http://codepedia.tistory.com/80

2010년 7월 22일 목요일

TRAC

Dynamic Share Object : DSO 아파치를 구성하는 일종의 플러그인

LoadModule xxxxxxxxxxxxx.so 로 모듈을 로딩한다.

 

TRAC은 오픈소스로 작성되었기 때문에 언제든지 사용자가 소스를 수정하여 사용할 수 있다. 물론 소스 자체를 수정하지 않더라도 TRAC 가체에서 제공되는 다양한 플러그인으로 기능을 확장할 수도 있다.

 

둘째, TRAC은 문서, SVN, WBS등 모든것을 웹 기반으로 관리할 수 있다. 웹 브라우저로 프로젝트 정보에 언제 어디서든 접근할 수 있으며, 누구라도 수정할 수 있다. 또한, 프로젝트 정보에 대한 이력(log)까지 관리할 수 있으므로 변경사랑을 추적하거나 최종 완료 문서를 확인하기 쉽다.

셋째, SVN, Git, 머큐리얼 등의 여러 버전 관리 시스템과 연동할 수 있다. 상용 소프트웨어와는 달리는 오픈 소스로 작성되어 있어 필요에 따라서는 사용자가 원하는 시스템과 연동할 수 있게 소스를 직접 수정할 수 있다. 또한, TRAC의 사용자와 버전 관리 시스템의 사용자를 같게 유지할 수 있다.

 

TRAC은 Apache HTTP Demon의 80Port를 통해 서비스가 된다.

 

TRAC은 Apache의 VirtualHost 를 통해 서비스가 된다. 즉 http://localhost/hostName 으로 접속이 가능하다.

 

2010년 7월 21일 수요일

프로그래밍의 발전 방향

과거의 프로그래밍 방법은 개발자가 모든것을 처리해야 했다.

이때는 개발자의 능력에 따라 구현의 결과가 달라지곤 했었다.

그만큼 개발자의 능력이 중요시 되었다.

 

하지만 현재는 수많은 라이브러리들의 설정파일에 의존하며 개발하고 있다.

개발자의 능력은 예전만큼 큰 요소가 되지 못하고 있고, 라이브러리의 설정파일 덕분에

설정파일의 홍수에 살고있다.

작은 규모의 프로젝트는 그렇지 않겠지만, 대규모의 프로젝트는 실로 그렇다.

그러다 보니 코딩의 어려움 보다는 설정의 어려움, 설정하는 시간이 더 오래 걸리는 경우가 많다.

 

이런 문제점때문에 단체는 설정파일을 줄이자는 운동을 하곤 한다.

 

설정파일을 줄이면 다시 개발자가 모든것을 처리하는 방식이 될까?

 

그렇지 않다.

주석을 이용해 설정파일을 작성한다.

 

방법은 다음과 같다.

   Annotation 기반 프로그래밍 으로 전환(주석을 읽어와서 처리)

 

@xxxxxxx

Design Pattern

Design Pattern은 Java소스를 설계하는 패턴을 말한다.

다시말하면 권장되는 프로그래밍 습관을 말하는데

 

그것은 다음과 같다.

구현(Implementation)과 속성(Interface)를 분리하라.
 

분리 대상

      Service, DAO class를 분리한다.