JAVA & Open Framework2013. 1. 30. 14:13

Connecting to a URL

URL 객체를 생성한 다음 openConnection 메소드를 사용하여 URLConnection 객체를 생성할 수 있습니다. 다음은 Yahoo.com URL의 Connection 객체를 만드는 예제 코드입니다.

try {
    URL yahoo = new URL("http://www.yahoo.com/");
    URLConnection yahooConnection = yahoo.openConnection();
    yahooConnection.connect();

} catch (MalformedURLException e) {     // new URL() failed
    . . .
} catch (IOException e) {               // openConnection() failed
    . . .
}

URLConnection.connect 메소드를 사용하여 Connection을 초기화 할 수 있는데 매번 명시적으로 호출하지 않아도 됩니다. getInputStream, getOutputStream 같은 메소드를 호출할 때 암묵적으로 호출하기 때문입니다.

Reading from and Writing to a URLConnection

URLConnection 클래스는 네트워크를 사용하여 URL과 의사소통을 하기 위한 다양한 메소드를 제공합니다. HTTP를 위한 기능들이 많이 있지만, 대부분의 다른 프로토콜을 위한 기능도 제공하고 있습니다.

Reading from a URLConnection

URL에서 직접 읽어오기와 비슷합니다.

import java.net.*;
import java.io.*;

public class URLConnectionReader {
    public static void main(String[] args) throws Exception {
        URL yahoo = new URL("http://www.yahoo.com/");
        URLConnection yc = yahoo.openConnection();
        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                yc.getInputStream()));
        String inputLine;

        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        in.close();
    }
}


Writing to a URLConnection

URLConnection 객체를 사용하여 OutputStream 객체를 얻어서 ObjectOutputStream을 생성한 다음 URL로 원하는 데이터를 posting 한 뒤에 서버에서 처리한 결과를 URLConnection객체의 InputStream을 받아서 BufferedReader로 읽는 프로그램입니다.

import java.io.*;
import java.net.*;

public class Reverse {
public static void main(String[] args) throws Exception {

if (args.length != 2) {
System.err.println("Usage: java Reverse " +
"http://<location of your servlet/script>" +
" string_to_reverse");
System.exit(1);
}

String stringToReverse = URLEncoder.encode(args[1], "UTF-8");

URL url = new URL(args[0]);
URLConnection connection = url.openConnection();
connection.setDoOutput(true);

OutputStreamWriter out = new OutputStreamWriter(
connection.getOutputStream());
out.write("string=" + stringToReverse);
out.close();

BufferedReader in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));

String decodedString;

while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
}
}

 

출처 : http://whiteship.tistory.com/1165

Posted by 아로나
JAVA & Open Framework2013. 1. 23. 10:51

이거는 [최종분석 톰캣]이란 책을 보면서도 공부했던 내용인데...
잊어버리고 있었다.

자바에서 URL을 호출하여서 해당되는 페이지의 정보를 읽어올 수 있다.

어렴풋한 기억으로는 이런 방식으로 톰캣 서버가 구동된다.
추후에 톰캣카테고리에서 자세하게 알아보자.

import java.net.*;
import java.io.*;
public class TestURLConnection {
    public static void main(String[] args) {
        URL url = null;
        URLConnection urlConnection = null;
      
        // URL 주소
        String sUrl = "http://piyoro.tistory.com";

        // 파라미터 이름
        String paramName = "fileName";

        // 파라미터 이름에 대한 값
        String paramValue = "파일경로";


        try {
            // Post방식으로 전송 하기
            url = new URL(sUrl);
            urlConnection = url.openConnection();
            urlConnection.setDoOutput(true);
            printByOutputStream(urlConnection.getOutputStream(), paramName + "=" + paramValue);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
  
    // 웹 서버로 파라미터명과 값의 쌍을 전송하는 메소드
    public static void printByOutputStream(OutputStream os, String msg) {
        try {
            byte[] msgBuf = msg.getBytes("UTF-8");
            os.write(msgBuf, 0, msgBuf.length);
            os.flush();
        } catch(IOException e) {
            e.printStackTrace();
        }finally {
         os.close();
        }
    }
}

출처 : http://piyoro.tistory.com/31

Posted by 아로나
JAVA & Open Framework2013. 1. 21. 15:43

이클립스에서 커밋하는중 발생한 CVS 오류 해결중 찾은 내용


OKJSP 에서 나온 결과

안녕하세요?

프로젝트 전부를 CVS로 커밋할때는 아무 문제가 없었습니다.

그런데 제가 한가지 폴더의 내용만을 수정하고 그 폴더만 커밋했습니다.

그후에 다시 전부를 커밋할려고 하니깐

[project name] : cvs server sticky tag '1.1' for file '문제의 먼저 커밋한 파일' is not a branch

[project name] : cvs [server aborted] : crrect above errors first

라고 나오네여^^

어케 해야하죠?ㅠㅠ

--->에 대한 답변으로..

get Contents sticky 로 가져와 수정된 파일인가봅니다.
그 파일을 replace with Lasted from HEAD 로 교체하고 commit해보세요.

--->라고 되어 있는데 "replace with Lasted from HEAD" 이게 어떻게 하는것인가요?

구글 검색결과

http://cysnim12.tistory.com/entry/sticky-tag를-제거-방법

[project name] : cvs server sticky tag '1.1' for file '문제의 먼저 커밋한 파일' is not a branch
[project name] : cvs [server aborted] : crrect above errors first

에러가 발생하면 아래와 같이 해주세요.

명령어 : cvs update -A

해결방법

이클립스상에서 cvs 콘솔 사용법을 모르는 관계로 뒤에것은 사용 불가
앞의 내용을 사용하기 위해 삽질중 다음 방법으로 해결

Navigator View의 해당 파일에 오른쪽 클릭하고

Team > Switch to Another Branch or Version 을 선택한후

Select the tag from following list   를 선택한후

아래 목록중 HEAD를 클릭하여 선택한후 Finish 시키니까 되더라..

혹시 모르니 지금껏 수정한 파일은 복사하여 백업한후 다시 붙여넣기 하여 commit 시켰음

내 기억이 엉망이라 틀릴수도 있음...
나중에 같은 오류시 참고하려고 그냥 적어넣은 내용임

출처 : http://kngon.hosting.paran.com/tc/37

Posted by 아로나
JAVA & Open Framework2012. 8. 6. 14:40

<%@ page contentType="text/html;charset=euc-kr" %>
<%
    String title = "大韓民國에는 1km마다 맛있는 맛집들이 많이 있습니다!!!";
    title = cutStr(title,17);
    out.println(title);
%>
<%!
    public static String cutStr(String str,int cutByte)
    {
      byte [] strByte = str.getBytes();
      if( strByte.
length < cutByte )
        return str;
      int cnt = 0;
      for( int i = 0; i < cutByte; i++ )
      {
         if( strByte[i] < 0 )
         cnt++;
      }

     String r_str;
     if(cnt%2==0) r_str = new String(strByte, 0, cutByte );
     else r_str = new String(strByte, 0, cutByte + 1 );

     return r_str;
    }
%>

Posted by 아로나
JAVA & Open Framework2012. 7. 31. 13:52

싱글톤 패턴 - 서블릿 클래스당 하나의 오브젝트를 만들어두고, 사용자의 요청을 담당하는 여러 스레드에서 하나의 오브젝트를 공유해 동시에 사용한다.

싱글톤 패턴의 특징 

- 클래스 밖에서 오브젝트를 사용하지 못하도록 생성자를 private으로 만든다.
- 생성된 싱글톤 오브젝트를 저장할 수 있는 자신과 같은 타입의 스태틱 필드를 정의한다.
- 스테틱 팩토리 메소드인 getInstance()를 만들고 이 메소드가 최초로 호출되는 시점에서 한번만 오브젝트가 만들어지게 한다. 생성된 오브젝트는 static field에 저장된다.
- 한번 오브젝트(싱글톤)이 만들어지고 난 후에는 스테틱 필드에 저장해 둔 오브젝트를 넘겨준다.

싱글톤 패턴의 한계
- private 생성자를 갖고 있기 때문에 상속할 수 없다.
- 상속과 다형성 같은 객체지향의 특징이 적용되지 않는 스테틱필드와 메소드를 사용한다.

- 테스트 하기가 힘들다.
  엔터프라이즈 개발의 핵심은 테스트가 핵심인데 에플리케이션 코드를 싱글톤으로 만들면 테스트를 만드는데 지장이 있다.

- 서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.
  여러대의 JVM에 분산돼서 설치가 되는 경우에도 각각 독립적으로 오브젝트가 생기기 때문에 싱글톤으로서의 가치가 떨어진다.

- 싱글톤의 사용은 전역 상태를 만들 수 있기 때문에 바람직하지 못하다.
   아무 객체나 자유롭게 접근하고 수정하고 공유할 수 있는 전역 상태를 갖는 것은 객체지향 프로그래밍에서는 권장되지 않는 프로그래밍 모델이다.

- 싱글톤 레지스트리
   - 스프링은 서번환경에서 싱글톤이 만들어져서 서비스 오브젝트 방식으로 사용되는 것은 적극 지지한다. 스프링은 직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능을 싱글톤 레지스토리로 제공한다.
    - 평범한 자바 클래스를 싱글톤으로 활용하게 해준다.

- 싱글톤과 오브젝트 상태
   - 상태정보를 내부에 갖고 있지 않은 무상태(stateless) 방식으로 만들어져야 한다.

출처 : http://peacekirf.tistory.com/28

Posted by 아로나
JAVA & Open Framework2012. 7. 31. 13:49

@ singleton - 하나씩 일어나는 일[것], 홀로인 것, 독자(獨子), (카드 놀이의) 한 장 패(의 수)


@ 싱글톤 패턴(Singleton Pattern) : 어떤 클래스를 애플리케이션 내에서 제한된 인스턴스 개수, 이름처럼 주로 하나만 존재하도록 강제하는 패턴

@ 싱글톤 패턴의 한계
- private 생성자를 갖고 있기 때문에 상속할 수 없다. 
- 싱글톤은 테스트하기 힘들다. 만들어지는 방식이 제한적이기에 테스트도 힘들다.
- 서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.(ex. 분산환경)
- 싱글톤의 사용은 전역 상태를 만들 수 있기 때문에 바람직하지 못하다.

@ 싱글톤 레지스트리(Singleton Registry)
: 스프링은 직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능을 제공. 평범한 자바 클래스를 싱글톤으로 활용하게 해주므로 싱글톤 패턴이 지니고 있는 한계점들이 문제가 되지 않는다.

 출처 : http://priceless.tistory.com/292

Posted by 아로나
JAVA & Open Framework2012. 7. 30. 14:42

XML 예약문자

<, >, &는 XML tag 표시와 entity를 표시하는 XML 예약문자로, XML 문서에 그대로 사용할 수 없다.

< (less-than sign) &lt;
> (greater-than sign) &gt;
& (ampersand) &amp;


그리스문자

그리스 문자는 풀어서 사용한다.

α alpha
β beta
γ gamma
δ,Δ delta
ε epsilon
ζ zeta
η eta
θ theta
ι iota
κ kappa
λ lambda
μ micron
ν nu
ξ xi
ο omicron
π pi
ρ rho
σ, Σ sigma
τ tau
υ upsilon
φ phi
χ chi
ψ psi
ω, Ω omega


기호 & 부호

&lt; or =
&gt; or =
± +/-
˚ degrees
degrees C
--&gt;
㎍, μG microgram
㎕, μL microliter
㎛, μM micrometer
® (R)
(TM)
χ2 chi─square


화학기호

화학기호는 윗첨자나 아랫첨자를 지정하지 않고 그대로 입력한다.

K+ K+
Cl- Cl-
Mg2+ Mg2+
CO2 CO2
H2O H2O


수학기호

수학기호는 윗첨자나 아랫첨자를 괄호 "( )" 안에 넣어서 입력한다.

102 10(2)
10-2 10(-2)
height2.239 height(2.239)

 

출처 : http://www.kamje.or.kr/special.html

Posted by 아로나
JAVA & Open Framework2012. 7. 26. 18:54

주어진 문자열이 숫자로 이루어져 있는지, 즉 숫자로 변환할 수 있는 문자열인지, 알아내야 할 때가 있습니다.

"124" 또는 "5425.8878" 또는 "0.0f" 이런 문자열은 숫자가 될 수 있고
"XYZ000" 이런 것은 당연히 숫자가 될 수가 없습니다.

다음의 isStringDouble(String s) 이라는 메소드로, 이런 판단을 쉽게 할 수 있습니다.

문자열이, 숫자(10진수 실수/정수)인지 아닌지 판단 예제


파일명: Foo.java

public class Foo {
  public static void main(String[] args) {

    String str = "123";
    if (isStringDouble(str))
      System.out.println("숫자입니다.");
    else
      System.out.println("숫자가 아닙니다.");

  }




  public static boolean isStringDouble(String s) {
    try {
        Double.parseDouble(s);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
  }


}



isStringDouble() 메소드는, 파라미터(인수)로 받은 문자열이, 실수로 변환될 수 있는지 여부를 확인하는 것입니다. 정수도 실수에 포함되기에, 정수인지도 판단할 수 있습니다.

우선 Double.parseDouble() 로 문자열을 실수로 변환해서, 에러가 나면 숫자로 아닌 것으로 판단하여 false(거짓)를 반환하는 식입니다.

그런데
0xFF
이런 16진수는 숫자라는 것을 알지 못하는 한계가 있습니다. 따라서 위의 방법은 10진수 숫자 여부만을 판단할 수 있습니다.


위의 예제, 컴파일 및 실행 결과:

D:\Z>javac Foo.java && java Foo
숫자입니다.

D:\Z>

 

출처 : http://mwultong.blogspot.com/2006/12/java-isnum-isdouble.html 

 

- 방법2

 

public boolean NumberChk(String str){
    char c = '';

    if(str.equals("")) return false;
    
    for(int i = 0 ; i < str.length() ; i++){
        c = str.charAt(i);
        if(c < 48 || c > 59){
            return false;
        }
    }
    return true;
}

 

 


Posted by 아로나
JAVA & Open Framework2012. 2. 26. 21:58

 

Duncan Mills 지음

Oracle9i JDeveloper가 Model-View-Controller 디자인 패턴 기반 J2EE 애플리케이션의 구축을 돕는 방법

필자는 여러분들이 내년 이후에는 MVC (Model-View-Controller) 패턴이라 불리는 디자인 패턴에 대하여 훨씬 더 많이 접하게 될 것이라고 확신합니다. 이번 기고는 그런 의미에서 MVC의 정확한 정의와 언제, 어디서 그리고 어떻게 Oracle9i JDeveloper를 사용하여 MVC 애플리케이션을 구축할 수 있는 지에 대하여 설명할 수 있는 좋은 기회라고 생각합니다.


이번 기고에서는 우선 디자인 패턴부터 소개를 하고, 그 후에 MVC에 대하여 자세하게 살펴보도록 하겠습니다.

필수 용어

J2EE 애플리케이션 디자인을 다룰 때 극복해야 할 첫번째 과제는 새로운 용어들과 특정 소프트웨어 형식 관련 전문 용어들입니다. 그래서 이번 기고에서는 자주 다루게 될 J2EE 관련 중요 개념들을 먼저 살펴본 후 본 내용을 다루도록 하겠습니다

디자인 패턴

"디자인 패턴"이라는 용어가 요즘 매우 많이 사용되고 있지만 여기에서 다루고자 하는 것은 프로그래밍 문제 해결을 위한 증명된 시도 방법에 대해서 입니다. 불행하게도 그 용어는 그 동안 남용되어 오면서, 그 자신이 목적이 되곤 했습니다. 소프트웨어는 디자인 패턴에 기반을 둘 수 있고, 그러한 경우에는 소프트웨어의 개발이 더 용이해질 수도 있지만, 소프트웨어를 구입하거나 디자인하는 경우에 기능보다 디자인 패턴을 더 중요하게 여긴다면 역효과를 낼 수도 있습니다.

"이것이 과연 디자인 패턴을 통해 나를 도울 수 있습니까?"라고 질문하면서 개발 환경을 지켜보는 것은 그리 생산적인 행동은 아닙니다. 디자인 패턴이라는 것은 목적에 대한 수단이 되어야지 결코 그 자체가 목적이 되어서는 안되기 때문입니다. 개발 툴을 평가할 때 할 수 있는 의미 있는 질문은 아마도 "애플리케이션 구축을 위해 이 환경이 얼마나 많은 것을 제공할 수 있습니까?" 정도가 될 것입니다.

다음은 고려해야 할 중요한 사항들입니다:

  • 디자인 패턴은 비즈니스 문제들을 해결하기 보다는 특정 프로그래밍 과제들을 해결합니다.
  • 디자인 패턴은 실제 구현보다도 가이드라인을 제공합니다.
  • 디자인 패턴은 재사용이 가능합니다
  • 디자인 패턴은 입증된 트랙 기록을 갖고 있습니다.
현재 웹 상에는 디자인 패턴과 관련된 다양한 정보들이 존재하고 있는데 그 중에서도 Sun Java Blueprints site 사이트는 반드시 확인해 보시기 바랍니다.

MVC

MVC는 디자인 패턴 중의 하나로 프로그래밍 세계에서는 전혀 새로울 것이 없습니다. Smalltalk 등과 같은 객체형 프로그래밍의 초기 시대 부터 Java Swing 컴포넌트 집합의 기초를 제공하는 최근까지 디자인 패턴으로서의 MVC 사용과 관련된 많은 레퍼런스들이 존재하고 있습니다. 그런데 MVC가 다시 주목을 받게 된 이유는 그것의 패턴이 웹 기반 애플리케이션 구축 시 발생하는 기본 문제들 중의 대다수를 해결하는데 적합하다는 것을 깨달았기 때문입니다.


일반적인 데이타베이스-중심 애플리케이션들과 특정한 웹 기반의 씬-클라이언트 애플리케이션들을 살펴보면 애플리케이션이 여러 가지 구분되는 작업들을 수행해야 한다는 것을 발견할 수 있습니다:

  • 데이타 액세스
  • 비즈니스 로직 구현
  • 사용자 인터페이스 표시 (데이타 프리젠테이션)
  • 사용자 상호 작용
  • 애플리케이션 (페이지) 플로우
MVC 아키텍처 또는 패턴은 사용자가 사용자 인터페이스를 재작성하지 않고 다른 데이타 소스에서 애플리케이션으로 용이하게 플러그할 수 있도록 데이타 프리젠테이션 등과 같은 작업들을 데이타 액세스로부터 분리시켜야만 한다는 전제 조건을 갖고 이러한 작업들의 구분 방식을 제공하고 있습니다.

지금은 MVC를 여기까지만 살펴보고 나중에 다시 자세하게 살펴보도록 하겠습니다.

JSP Model 1과 Model 2

진행을 하기에 앞서 JSP Model 1와 Model 2 아키텍처에 대해 잠시 살펴보도록 하겠습니다. 현재 많은 씬-클라이언트 웹 애플리케이션들은 사용자 인터페이스의 디스플레이 처리 방법으로 JSP (JavaServer Page) 를 사용하고 있습니다. 특히 복잡한 애플리케이션에서 여러 페이지를 함께 연결할 때 사용자는 하나 이상의 "루트"를 갖는 페이지들 사이에서 플로우를 어떻게 제어해야 할지 결정을 해야 합니다. 이러한 문제의 경우 JSP는 두 개의 시도 방법을 갖고 있습니다: Model 1 아키텍처와 Model 2 아키텍처

Model 1 아키텍처 ( 그림 1) 는 페이지들 사이의 라우팅을 JSP 자체에게 맡깁니다. 그래서 JSP는 하드코딩된 링크를 갖고 있거나 또는 페이지 내에 내장된 이동 (navigation) 로직을 갖고 있어야 합니다. 그러나 이 전략은 하나의 문제를 해결함과 동시에 또 다른 문제를 야기시키는데, 그것은 프리젠테이션과 이동 로직이 섞여있어서 페이지를 쉽게 재사용할 수 없기 때문입니다. 심지어 JSP Model 1를 사용하는 간단한 페이지 플로우들도 쉽게 복잡해질 수 있기 때문에 각각의 페이지는 그것이 링크된 다른 페이지들을 모두 알고 있어야만 합니다.

 
사용자 삽입 이미지

JSP Model 2 (그림 2) 는 이 문제에 대한 해결 방법입니다. Model 2 아키텍처의 경우에 페이지 플로우는 JSP에 의해 처리되지 않습니다. 오히려 아키텍처는 페이지와 함께 제출된 정보를 기반으로 하여 분리된 서블릿이 라우팅을 결정하도록 해주어서 페이지들은 논리적으로 링크된 다른 페이지들을 인식할 필요가 없습니다. 이 서블릿은 Controller라고 호칭되는데, 이것은 이번 기고의 원래 주제인 MVC 패턴과 밀접한 관계를 맺고 있습니다.

 
사용자 삽입 이미지

MVC의 상세 내용

MVC는 애플리케이션을 Model, View 그리고 Controller라고 호칭 되는 세 가지 레이어 또는 기능 영역으로 논리적 방법을 통해 분리한 것입니다.


MVC와 같은 디자인 패턴은 각기 다른 레벨로 적용될 수 있는데, MVC는 애플리케이션 구축 방법으로서 뿐만 아니라 컴포넌트 레벨에서도 유용한 전략으로 활용될 수 있습니다. 잠시 JSP와 웹으로부터 벗어나서 Java Swing 리스트 박스 (이것은 단순한 컴포넌트이지만 훨씬 더 지역화된 범위에서 세 가지의 MVC 요소들을 모두 보유하고 있습니다) 와 같은 것을 고려해 보는 것도 좋습니다.


그럼 이제부터 세 가지 레벨을 한번 살펴보도록 하겠습니다:

The Model

Model은 애플리케이션 데이타 및 비즈니스 로직의 저장소 (repository) 입니다. 그러나 Model이 데이타베이스를 표시한 것이라고 말하는 것은 너무나 극단적인 표현입니다. 일반적으로 Model 기능의 일부는 데이타베이스 기반 애플리케이션을 통해 데이타를 데이타베이스로부터 읽어 들이거나 또는 데이타를 데이타베이스에 지속시키는 것입니다. View의 데이타 액세스는 데이타를 드러내거나 또는 View를 통해 입력된 데이타를 입증 및 소모하기 위해 비즈니스 로직 레이어를 구현하는 작업도 필요로 하고 있습니다.


애플리케이션 레벨에서 Model은 표시하는 사용자 인터페이스와 표시되는 비즈니스 데이타 사이의 입증 및 추상화 레이어 처럼 동작을 합니다. 데이타베이스 서버 자체는 단순히 Model을 위한 퍼시스턴스 (persistence) 레이어 입니다.

The View

View는 Model 데이타를 렌더링하는 것과 관련이 있습니다. 이제부터는 View를 렌더링하는데 사용되는 다른 기술들에 대하여 살펴볼 예정인데, 보통은 JSP 페이지를 사용하고 있습니다. 여기에서 주목해야 할 것은 View 코드는 사용자 역할에 따라 조건부 데이타 표시와 같은 작업들의 수행 로직을 포함할 수는 있지만 View 코드 자체가 애플리케이션이나 이동 로직을 하드코딩하지는 않는다는 것입니다. 최종 사용자가 View로부터 렌더링 되는 HTML 페이지 내의 동작을 수행할 때에는 이벤트가 Controller에게 제출이 되고 그 다음에 무엇을 할 것인지는 전적으로 Controller에게 달려 있습니다.

The Controller

Controller는 이름이 나타내는 것과 같이 전체 패턴의 연결 고리 입니다. View에서 수행된 모든 사용자 동작은 브라우저의 요청 컨텐트에 기반을 두고 프로그래밍 또는 메타데이타에 결합되어 다음에 무엇을 할지를 결정하는 Controller를 통해 제출됩니다.


Controller들은 여러 가지 다른 방식으로 운영될 수 있습니다. 어떤 것들은 요청들을 정확한 코드로 라우팅하기 위해 URL 인수들을 사용할 것이고 다른 것들은 요청이 제출되어 지는 페이지를 참작할 것입니다. 또한 그 외의 것들은 페이지 제출 시에 무엇을 할지를 알아내기 위해 숨겨진 필드들을 사용할 수도 있습니다. 그런데 MVC 디자인 패턴 자체는 Controller가 어떻게 동작하는지 그리고 단순히 그것의 기능이 무엇인지에 대해 규정을 하고 있지는 않습니다.


Controller는 여러 가지 구분되는 프로세스들 또는 서블릿들로 만들어져서 전체 Controller 기능의 다른 측면들을 처리할 수 있습니다. 예를 들면, 사용자는 하나의 서블릿이 제어하는 페이지 플로우 컨트롤과 또 다른 서블릿이 제어하는 사용자 인터페이스 이벤트 컨트롤 등과 함께 정확한 하위 Controller에게 디스패치하는 마스터 Controller를 가질 수 있습니다. 이 개념 자체는 다른 디자인 패턴의 주제이기도 합니다: Front-Controller 패턴

웹 애플리케이션에서의 작동 방식

MVC 패턴은 요약이 가능하여 그림3 에서와 같이 다이어그램을 사용하는 전통적인 씬-클라이언트 웹 애플리케이션에 적용 시킬 수 있습니다.

사용자 삽입 이미지

이와 같은 웹 애플리케이션에 있어서 명심해야 할 것은 모든 것들은 페이지를 제출하는 사용자에 대한 응답을 통해 발생한다는 것입니다. "다음 10 개의 레코드를 표시하십시오" 등과 같은 간단한 UI 작업은 Controller에 대한 클라이언트 브라우저의 요청에 의해 구현되어 더 많은 데이타가 필요하다는 것을 Model에게 가르쳐 준 후 원래 페이지를 다시 표시할 것입니다. 그런 후에 View가 Model로부터 데이타를 요청할 때에는 다음 10 개의 행들이 표시 가능하게 될 것입니다.

지금까지는 모든 것이 매우 간단하게 보였고, 언급된 세 개의 부분 모두 명확하게 설명되었습니다:

  1. View를 이루는 개별 페이지들은 다른 페이지들에 대한 관계를 알지 못합니다. 그것들은 단지 "이벤트"를 발생시키고 Controller는 정확한 일이 발생하였다는 것을 보증해 줍니다.
  2. View와 Controller는 기본이 되는 데이타 구조 또는 비즈니스 규칙에 대해서 알지도 못 하고 구현도 하지 않습니다. 그것들은 단순히 Model의 공용 API들을 사용 (consume) 할 뿐입니다

  3. Model은 View나 Controller Model에 대해서 아무 것도 알지 못 합니다.
MVC 패턴의 본질은 장소에 구애 받음이 없이 애플리케이션의 View와 Model 부분의 재사용을 간편하게 만드는 것이고, 애플리케이션 자체는 본래 데이타 소스와 UI를 의미있는 방식으로 결합하는 Controller 부분에 의해 표현이 됩니다.

마찬가지로, 이러한 논리적 분리는 사용자가 나머지 애플리케이션을 다시 작성하지 않고 선택하는 기술을 특정 레이어를 위해 변경할 수 있게 해줍니다. 예를 들면, View의 구현을 위해 JSP를 사용하여 애플리케이션을 프로토타입할 수 있지만, XML 메타데이타-방식 서블릿을 통해 이후에 View를 바꾸어 놓는 것도 가능합니다. 이 작업은 Model을 변경함이 없이 Controller을 최소한만 변경하여 이행할 수 있습니다. (Controller에 있어서 이러한 경향은 나중에 다시 한번 자세히 살펴보겠지만 Jakarta Struts와 같은 메타데이타-방식 Controller 프레임워크를 사용하기 위함입니다. 그러므로 View를 교환할 때는 Controller 로직 자체가 아니라 그 메타데이타만 변경하면 됩니다.)

한번 MVC-기반 애플리케이션의 구현을 시작하게 되면 모든 것들이 보다 복잡해 지고, 프로그래머들은 레이어들 사이에서 논리적인 분리를 계속 유지하기 위해서는 교육을 받아야 합니다. 예를 들어 링크를 하드코딩해서 네비게이션 로직을 JSP로 코딩하는 것이 좋게 보일 수는 있지만, 만약 이것이 구현되면 페이지는 더 이상 사용할 수 없게 될 것입니다.

레이어들 사이의 라인들이 뚜렷하지 않다는 것도 반드시 인식하고 있어야 합니다. 예를 들면 데이타가 페이지로부터 제출될 때 Struts와 같은 Controller 프레임워크는 JavaBean을 데이타로 채우고 계속 진행하기 위해 빈을 Controller로 전달할 수도 있습니다. 그러면 지금의 그 빈은 View의 일부입니까 아니면 Controller의 일부입니까? 솔직히 말씀드리면 어느 버킷 (bucket) 을 선택해서 그것을 위치시키는가 하는 문제는 그리 중요한 것이 아닙니다. 중요 컴포넌트들 사이에서는 항상 인터페이스 레이어들이 존재할 것입니다. 여기에서 중요하게 여겨야 할 것은 올바른 장소에 정확한 종류의 로직을 유지해야 하는 것입니다.

실제 상황에서의 MVC

앞에서는 MVC의 이론을 살펴보았고, 지금부터는 J2EE가 포함하고 있는 기술들과 MVC 기반 애플리케이션 구축 과정을 도울 수 있는 Oracle9i JDeveloper에 대하여 살펴보도록 하겠습니다.
MVC의 각 부분에 대하여 역할 완수를 위해 사용자가 채택할 수 있는 선택 가능한 구현 방법들이 있는데, 당연히 앞으로 언급할 옵션들은 소모적인 것이 아니라 가능성의 일부를 설명해 주는 것들입니다. 뿐만 아니라 일부 솔루션들은 하나 이상의 MVC 부분도 포함할 것입니다.

실제 상황에서의 Model

Model의 역할은 애플리케이션 기능과 관련된 애플리케이션 데이타와 비즈니스 로직을 처리하는 것이라고 알려져 있는데, Model은 단지 여러 레이어로 이루어져서 다음과 같은 작업을 처리하는 것이라고 생각하면 됩니다:

  • 비즈니스 객체 지속
  • 데이타 액세스
  • 비즈니스 서비스 제공
Enterprise JavaBeans (EJB), JDBC, Web Services, 그리고 Oracle9iAS TopLink 등과 같은 기술들은 모두 Oracle9i JDeveloper Business Components for Java (BC4J)와 같은 완벽한 Model 프레임워크를 통해 가장 생산적인 솔루션을 제공하면서 이러한 작업들의 전부 또는 일부를 이행할 수 있는데, 이 프레임워크는 Model 레이어들의 생산을 위해 선언적인 메타데이타-방식의 시도 방법을 제공하면서 프로그래머들이 로우-레벨 보다는 그들의 코드를 통해 비즈니스 요구 사항들의 해결에 집중할 수 있도록 해줍니다. 그리고 BC4J는 지속성을 위해 EJB를 사용하는 것과 같이 다양한 Model 레이어 작업들을 위해 각각 다른 구현 방법을 사용할 수 있는 유연성을 프로그래머에게 제공하고 있습니다. BC4J와 같은 프레임워크를 사용하게 되면 Model의 사용자들은 (View 개발자들) 데이타 액세스 및 비즈니스 로직 구현에 대한 세부 사항들을 정확하게 알 수가 없고 그들은 단지 추상적 레이어만을 제공 받게 됩니다.

이번 기고에서는 Model 레이어 구현의 다양한 시도 방법에 대한 상대적 장점에 대해서 많은 부분을 할애하지는 않을 것입니다. 그런데 여기에서 알아야 할 것은 JDeveloper는 Model 내에서 사용자들이 비즈니스 프로세스 프로그래밍 로직에 집중할 수 있게 해주면서 이러한 Model 레이어들을 사용하는 기본 작업을 보다 쉽게 만들 수 있는 툴들을 제공한다는 것입니다.

예를 들어 사용자는 JDeveloper를 통해 데이타베이스를 찾고 Model의 기본으로 사용할 데이타베이스 테이블들을 선택한 다음 그 테이블들을 직접 UML 클래스 다이어그램으로 끌어놓을 수 있습니다.

JDeveloper는 사용자가 기본 위저드와 등록 정보 편집기 등을 통해 Model 레이어를 생성할 수 있게 해줍니다. 그리고 동일한 방식으로 기본적인 EJB와 BC4J 클래스들, 메타데이타 그리고 전개 기술자 (deployment descriptor) 등의 정의 작업을 수행할 수도 있습니다. BC4J의 경우에는 사용자가 등록 정보 편집기를 통해 검증과 재사용 가능한 비즈니스 규칙들을 그들 자신의 모델로 적용할 수 있는 능력을 얻게 됩니다.

실제 상황에서의 View

일반적으로 사용자 인터페이스를 생성할 때 어떠한 기술을 선택해야할 지 무척 당황해 할 수 있습니다. 다음은 선택 가능한 세 가지 시도 방법입니다:

  • HTML 페이지 생성 Java 코드를 작성하는 Java 서블릿
  • 기본적으로는 HTML 페이지를 생성하지만 Model로부터 데이타를 가져오는 것과 같은 기능들을 수행할 때에는 특별한 태그 또는 스크립틀릿 (scriptlet) 들을 내장하는 JSP
  • 메타데이타-방식 또는 템플릿-방식 프레임워크
Java 서블릿 방식은 Java 프로그래머들이 많이 선호하는 방식으로서 View-구축에 필요한 요구 사항들을 해결합니다. 모든 것은 프로그램 문자열 내에 내장된 HTML 요소들을 통해 코드 내에서 즉시 처리되어야만 하는데, 이와 같은 방식은 복잡하고 오류가 많이 발생합니다.

현재 View 생성에 있어서 가장 유명한 기술은 JSP 방식인데, 이것은 페이지를 위한 기본적인 사용자 인터페이스 디자인 툴인 Macromedia Dreamweaver 등과 같은 표준 HTML 편집 툴들의 사용 능력과 그 페이지의 작업 방식과 데이타 바인딩을 처리하기 위한 Java 코드의 내장 능력을 함께 결합한 것입니다. JSP가 최초로 실행이 될 때에는 서블릿으로 컴파일이 되는데, HTML 내에 Java 스니핏 (snippet) 들을 내장하는 방식은 Java 내에 HTML을 내장하는 반대 프로세스보다 훨씬 더 생산적이라고 판명되었습니다

JSP들은 그것들 내부로 직접 내장되는 Java 코드의 세그먼트들을 갖거나 또는 커스텀JSP 태그들을 사용할 수 있습니다. 태그들은 컴파일 시에 즉시 배치되는 Java 코드를 위한 위치 표시자 (placeholder) 인데 그것들의 재사용이 가능하도록 해주는 API와 함께 디자인되어 사용되고 있습니다. 그래서 프로그래머는 기본적 구현에 대한 지식을 보유하지 않고도 애플리케이션 내에서 태그 라이브러리를 재사용이 가능한 컴포넌트들의 라이브러리처럼 사용할 수 있습니다.

JSP와 JSP 태그 라이브러리들을 결합하는 것은 View 개발자들에게 막대한 능력을 제공함과 동시에 많은 문제점을 발생시킬 수도 있습니다. 그러한 태그 라이브러리들은 BC4J-기반 모델에 대한 간편한 액세스 기능을 제공하는 Oracle BC4J 태그 등과 같은 특별 라이브러리들부터 Struts 태그 라이브러리와 Java Standard Tag Library (JSTL) 등과 같은 보다 일반적인 "개방형 소스" 라이브러리들 까지 존재합니다.

프로젝트를 위해 정확한 태그 라이브러리를 선택하는 것은 어려운 일이지만 사용을 위해 선택한 다른 기술들이 그 선택 과정을 이끄는 경우도 가끔 발생할 것입니다. 예를 들어, Model 프레임워크로 BC4J를 사용하고 Controller로 Struts를 사용하기로 결정한 경우 JDeveloper는 사용자에게 이러한 조합을 위해 맞추어진 표준 태그 라이브러리들의 집합을 제공할 것입니다

View 개발의 마지막 방식은 템플릿-방식 또는 메타데이타-방식 프레임워크를 사용하는 것입니다. 이것의 관련 예는 XML을 선언적으로 사용하여 페이지 정의 방식을 제공하는 JDeveloper 내의 UIX 프레임워크입니다.

Jakarta Velocity 프로젝트는 또 다른 템플릿-기반 방식을 제공하는데 Velocity는 XML-방식 보다는 Velocity가 대신하는 템플릿 HTML 페이지 내의 특별 마크업을 사용하여 오히려 JSP 페이지처럼 동작합니다.

이와 같은 메타데이타-방식의 시도 방법은 서블릿 또는 JSP를 사용하는 것보다 많은 이점을 제공할 수 있습니다. 우선, 프레임워크는 UI가 무슨 일을 하고 그것이 어떻게 보이는지를 정의하지만 그것이 어떻게 구현되는지는 정의하지 않기 때문에 다른 장비로부터 출력을 얻어낼 때 동일한 메타데이타 정의를 사용할 수 있습니다 (예를 들면 브라우저 클라이언트로부터 HTML 출력을 얻어내거나 또는 전화로부터 WML 출력을 얻어낼 때). 두 번째는 메타데이타의 선언적 성격이 그것 자신에게 정의 뿐만 아니라 시각 편집기의 사용도 추가해 주고 있습니다. 사용자 인터페이스의 포인트-앤드-클릭 편집은 J2EE 개발자의 생산성을 증가시키기 위한 필수 사항 중 하나입니다.

실제 상황에서의 Controller

웹 기반 애플리케이션에 적용되었을 때 Controller 기술이 모든 MVC 컴포넌트들 사이에서 가장 완성된 것은 아닙니다. 이것은 Controller와 View가 혼합된 JSP Model 1 방식이 지금까지 광범위하게 사용되어 왔기 때문입니다. Controller들이 계속 사용되어 온 경우 Controller들은 자체 내에서 성장하면서 Jakarta Struts Controller 프레임워크에 기반을 두는 경향도 갖고 있습니다.

Struts Controller는 매우 유명한 JSP 애플리케이션 구축용 Controller 프레임워크로서 핵심 Controller 기능을 포함하면서 View 레이어를 위해 많은 태그들을 제공하고 있습니다. Struts는 개별 페이지들을 위해 위치 추상화 (abstraction) 를 정의하는 XML 메타데이타와 페이지들 사이의 실제 흐름을 제어하기 위한 프로그래밍 코드의 혼합된 형태를 사용하고 있습니다. 보다 자세한 정보는 Apache 웹 사이트에서 확인해 보시기 바랍니다.

JDeveloper는 Struts 구성 파일 편집기 그리고 단순 Struts 또는 Struts, BC4J, JSP UIX 등의 조합을 사용하는 애플리케이션들의 구축을 보다 간편하게 만들어 주는 위저드와 JSP 태그들의 집합을 제공하여 Controller로서의 Struts 사용을 완벽하게 지원하고 있습니다.

MVC의 미래

이번 기고의 시작 부분에서 잠시 언급했던 것처럼, MVC는 점차 발전하면서 J2EE 애플리케이션들을 위해 선택 가능한 개발 방법론이 되어가고 있습니다. 우리는 현재 매우 흥미로운 개발들이 (특히 View 및 Controller 분야에서) 진행 중인 것을 보고 있습니다.


Controller 측면에서 Struts 버전 1.1은 베타 상태에 있는데, 이 새로운 버전은 Struts 1.0 보다 훨씬 더 유연하고 또한 많은 일을 처리할 수 있습니다. 또한 페이지 플로우 정의 작업을 더욱 선언적으로 만들면서 단순 페이지 플로우 이상으로 Controller의 범위를 확대하는 Controller를 통해 보다 많은 일이 수행되고 있습니다.


페이지 플로우의 시각 모델링이 첫번째 단계인데, 많은 벤더들은 현재 이 기술의 작업을 계속 진행하고 있습니다. 그러나 개발자들이 웹 배치를 위해 보다 복잡한 시스템을 구축하기 시작하면서 단순 페이지 플로우 보다는 전체 프로세스들을 모델링하는 능력에 대한 요구가 점차 증가하고 있습니다. 이와 같은 프로세스들 중에서 페이지를 최종 사용자에게 보여주는 것은 플로우를 위해 가능한 여러 작업들 중의 하나일 뿐입니다. Oracle은 매우 가까운 미래에 이와 같은 종류의 Controller 기술을 통해 흥미로운 개발들을 제공할 예정입니다!

View 측면에서 커다란 변화는 JavaServer Faces (JSF) 입니다. 이것의 목적은 HTML을 위해 J2EE를 사용하여 그래픽 인터페이스의 새로운 표준을 개발하는 것이고, 개념은 표준 UI 요소들과 이벤트 핸들링을 통해 Swing GUI Toolkit과 같은 것을 HTML을 위해 제공하는 것입니다.

Oracle은 Java Community Process (JSR 127) 의 일부로 정의되고 있는 이 과제의 정의 프로세스에 참여하고 있고, 표준 작업이 종료되자 마자 JSF를 구현할 예정입니다. JSF에 대한 보다 자세한 사항은 http://www.jcp.org/en/jsr/detail?id=127을 확인해 보시기 바랍니다.

JavaServer Faces는 MVC의 Model에 영향을 미치고 있습니다. 표준화된 GUI 툴킷이라는 것은 View와 Model 사이의 상호 작용이 Model 데이타를 특정 필드 또는 컨트롤로 바인딩을 해서 표준화가 될 수 있다는 것을 의미합니다. 그래서 필자는 J2EE 개발을 위한 패턴으로서 MVC를 사용하는 흥미로운 단계에 접어들었다고 믿고 있습니다. 이 기술은 이제 막 성숙한 단계에 접어들었고 또한 표준화 작업도 함께 이루어지고 있습니다.


비즈니스 프로그래머들의 작업을 간편하게 해줄 수 있는 시각적 모델러와 UI 편집기를 통해 코드-중심의 애플리케이션 구축으로부터 선언적 컴포넌트 어셈블리로 현재 이동하고 있고, 보다 많은 프레임워크들은 J2EE-관련 표준 및 디자인 패턴의 구현을 위해 통합되어서, 프로그래머들은 코드 작성보다는 비즈니스 문제 해결에 좀 더 집중할 수 있게 되었습니다.

Duncan Mills는 Oracle Application Development Tools 그룹의 제품 관리자로서 Oracle9i JDeveloper와 Oracle9i Forms의 전문가인데 1988년 이후로 DBA 또는 개발자로서 Oracle 제품을 담당해 왔습니다.


이 기사는 원래 ODTUG Technical Journal의 2003년 6월 호에 발표되었던 것입니다.

출처 : http://syseng.tistory.com/tag/MVC%ED%8C%A8%ED%84%B4

Posted by 아로나
JAVA & Open Framework2012. 2. 26. 21:46

JSP Model 2 Architecture

JavaWorld에 기고한 Govind Seshadri의 아티클
'Understanding JavaServer Pages Model 2 architecture'(12/29/99)
에 보면 JSP 초창기 스펙에 Model 1과 Model 2에 대해 다음과 같이 설명하고 있다.

This model(Model 2) can also be seen as a server-side implementation of the popular Model-View-Controller (MVC) design pattern.
The early JSP specifications advocated two philosophical approaches for building applications using JSP technology

그래서, 도대체 초창기 JSP 스펙에서 어떻게 언급되었는지가 궁금해서 스펙을 찾아보기로 결정했다.
강의할때는 그냥 '초창기 JSP 스펙에서 언급되었었다'라는 간단한 언급만 하고 넘어가던 차에 이제서야 할일을 한 느낌이다. ;; 하지만, 스펙을 생각만큼 빨리 찾지는 못했다. SUN 사이트에서는 1.0 이후 스펙들만 확인이 가능했기 때문에..

JavaServerTM PagesTM - Specification 0.92, October 7, 1998

다음은 번역내용이다.

JavaServer Pages Access Model

JSP를 다음 두가지 방식으로 사용할 수 있습니다.

Model 1: A request sent to a JavaServer Pages file
    - 클라이언트 웹 브라우저를 사용하는 사용자가 직접 JavaServer Pages(.jsp)에 요청을 날린다.
    - 클라이언트의 요청을 받은 후, JSP는 JavaBean에 정보를 요청한다.
    - JSP는 JavaBean의 내용을 조회하거나 뿌려줄 수 있다.


Model 2: A request sent to a Java Servlet
    : JSP를 사용하는 다른 방법은 Servlet에 request를 보내는 것이다.(JSP가 보내는게 아님)
    - 예제에서 클라이언트는 Servlet에 request를 보낸다.
    - Servlet이 동적 컨텐츠를 생성한다.
    - 예제에서 Servlet은 DB와 통신하기 위해 JDBC를 사용했다.
    - Servlet은 동적 컨텐츠를 Bean에 담는다.
    - JSP는 Bean으로부터 동적 컨텐츠에 접근하고, 클라이언트 웹 브라우저에 컨텐츠를 뿌려준다.



Common to both access models

    - Model 1, Model 2 둘 다 JSP파일은 .jsp 확장자로 구분이 된다.(이는 서버에 특별한 처리가 필요하다는 것)
    - 브라우저로부터의 직접요청이든, Servlet으로 부터의 요청이든 JSP에 요청이 들어오면, .jsp 파일은 오브젝트로 컴파일된다. (이 이유로, 최초 JSP요청에 대해 응답지연이 발생)
    - 오브젝트로부터의 결과는 브라우저에서 해석하고 뿌려줄 수 있는 표준 HTML이다.


내용을 정리해 보자면, 딱히 특별할게 없다. MVC에 대한 언급도 없다.
Model 2 아키텍처 자체는 
    JSP와 Servlet중에 무엇이 클라이언트의 요청을 받는가와 JSP의 역할에 따른 차이를 구분한 것일뿐이었다.
다시 생각해보면, Model 2는 JSP 스펙에서 Access Model을 규정하면서 나온것들이다.
다분히, JSP입장에서 생각해야 한다.

다시 Govind Seshadri의 아티클로 돌아가자.
사실 난 여기에서 강한 의문을 갖게 되었다. 과연, JSP 스팩에서 Model 2를 구분할때 MVC 디자인 패턴을 염두에 두고 구분을 했을까라는 점이다.
MVC 디자인 패턴이야 1970년대 Smalltalk에서 나온 개념이니, JSP가 생기기 훨씬 이전부터 존재하던 개념이었으니 말이다. 구글링을 통해 일단 단서를 찾았다.

   Model 1 Model 2 MVC

Model-View-Controller 패턴은 Trygve Reenskaug에 의해서 발명된 GUI 코드에서 Separate Of Concern을 위한 일반 기술이었다. 이는 곧 동등한 레벨의 분리를 위해 Java EE 어플리케이션에도 적용될 수 있다는점이 분명해지게 되었다. 그렇게 함으로써, Model 영역은 JavaBeans나 POJO로 작성하고, Controller로써 Servlet을, 모든 작업이 끝나고 결과를 포맷하거나 마크업하기 위해 JSP로 포워딩하게 되었다. MVC 패턴을 사용하여 작성된 Servlet/JSP 어플리케이션이 Model 2 JSP Programming으로 알려지게 되었다.
이 패턴은 Servlet/JSP 어플리케이션에서 사용되기 이전부터 다른 형식으로 존재해왔기 때문에, "MVC2"로 언급되기도 하였으나 MVC1이 존재하는 것 같은 혼란을 야기하므로, MVC로만으로도 충분하다.

주목할 부분은 MVC 패턴을 사용하여 작성된 Servlet/JSP 어플리케이션이 Model 2로 알려지게 되었다라는 부분이다. Model 2가 MVC를 염두에 두고 나온 아키텍처인가에 대한 물음은 위키페디아를 통해서도 확인할 수 있었다.

    Model-view-controller

MVC는 일반적으로 썬용어로는 Model 2 아키텍처로 구현되었다.

Model 2로 위키페디아를 검색해보니 더 명확해졌다.

Model 2는 컨텐츠로부터 프리젠테이션을 분리하기 위해 Model-View-Controller(MVC) 디자인 패텬을 사용한다.
MVC에 대한 Brian McCallister의 블로깅에서도 다음 내용이 나온다.

Then the Web happens and Sun starts talking about Model2 in terms of MVC.

출처 : http://ericlove.tistory.com/12
Posted by 아로나