노무현 대통령 배너

Make A Wish!!

SERAPHMATe's LifeLog


참조사이트 : https://www.digitalocean.com/community/articles/how-to-install-and-run-a-node-js-app-on-centos-6-4-64bit


예전부터 관심이 있었던 node.js를 실전에 써볼까해서 회사 개발서버에 설치하였다.
구글링을 해서 참조 사이트를 찾고 설치를 진행했다.
지식이 허술한지라 다음에 또 참조하기 위해 기록을 남겨둔다.


1. node.js를 설치하기 위한 의존 패키지를 설치한다. 참조 사이트에서는 개발도구 전체를 설치하는 것으로 되어 있다.

yum install gcc gcc-c++
yum install openssl-devel
yum install make


2. screen 명령어를 설치한다. screen 명령어가 뭔지 몰라 찾아봤다. screen 명령어에 대한 설명은 다음과 같다. "원격에서 작업하다 보면 여러창을 보고 싶을때가 많지만, 따로 로그인 하기도 귀찮고, 여러창 왔다갔다 할때도 어느 터미널이 어느 기계인지 많아지면 관리가 안되는 경우가 많다. 이럴때 사용하면 편리한 것이 screen이다. screen은 한 터미널 화면에서 여러 쉘과 프로그램을 띄울수 있으며, 또한 세션 관리 기능도 지원해서 터미널을 종료해도 나중에 다시 그 세션으로 복귀할수 있다."라고 한다. 더 자세한 내용은 여기를 참조하도록 하자. 설치하고 보니 이 기능은 딱히 나한테는 필요하지 않은 듯.

yum -y install screen


3. /usr/src 디렉토리로 이동한 후 node.js 소스 파일을 다운로드 받는다. 설치 계정을 어떤 걸로 해야할지 몰라서  우선은 root로 설치했다.

cd /usr/src
wget http://nodejs.org/dist/v0.10.22/node-v0.10.22.tar.gz


4. 압축을 풀고 디렉토리로 이동한다.

tar zxvf node-v0.10.22.tar.gz
cd node-v0.10.22


5. configure 후, make && make install을 실행하여 설치한다.

./configure
make && make install

- configure : makefile을 생성해주는 스크립트이다.
- make : 소스코드를 컴파일 해주는 명령어, configure를 통해 생성된 makefile에 설정된 내용을 바탕으로 바이너리 파일을 생성해준다. 여기까지의 컴파일 과정은 패키지로 배포된 소스파일을 사용자가 실행 가능한 파일 형태로 만들어주는 것을 의미한다.
- make install : 실제 설치를 하는 명령어로 make 명령어를 통해 생성된 설치파일을 실행하는 과정이다.


6. NPM을 통해 Express를 설치한다. 참조 사이트에는 visudo 명령으로 설치 계정에 sudo 권한을 주고 있는데 나는 root로 설치했으니 별 상관 없는 것 같다. -g 옵션은 해당 패키지를 시스템 내에서 GLOBAL하게 사용할 수 있게 설치한다는 옵션이다.

npm -g install express supervisor


7. node.js 어플리케이션을 실행하는데 사용할 사용자 계정을 생성한다. 보안상의 이유로 sudo 권한이 없는 일반 계정을 생성한 후 node.js 어플리케이션을 실행하도록 한다.

useradd nodejs
passwd ****


8. express를 통해 샘플 어플리케이션을 생성해본다.

express hello


9. 생성된 node.js 어플리케이션 디렉토리로 이동 후 express 관련 라이브러리를 설치한다.

cd hello && npm install


10. node.js 어플리케이션을 실행해본다.

supervisor app


Leave a comment

Comet이란 무엇인가?


그러게 뭘까나.. 공부를 해보자.

Comet

View more documents from knight1128


Leave a comment

출처 : http://www.aptana.com/node/224


Callbacks


Jaxer에서 페이지의 lifecycle은 두 파트로 구성된다. : Jaxer는 그들이 브라우저에 서비스를 하기 전에 페이지를 처리한다. 그리고 Jaxer는 브라우저에서 서버측의 기능으로 돌아오는 호출을 처리한다. 두 번째 파트를 보자 : 어떻게 Jaxer는 브라우저가 서버측 기능을 호출하기 쉽게 만들어주는지.


자, 간단한 예제를 보자. 만약 우리가 순수한 브라우저 측 어플리케이션을 작성한다면, 우리는 이렇게 작성할 수 있다. :

<script>
        function getData() {
                return 42; 
        }

</
script>
<
input type="button" value="get it" onclick="alert(getData())">

브라우저에서 이 페이지를 볼때, 이 페이지는 하나의 버튼을 가지고, 당신이 그것을 클릭하면, "42"를 출력하는 alert를 보게 된다. 이것 대신에 서버로부터 데이터를 얻고 싶다면, 당신은 단순히 script 태그에 값을 "server-proxy"를 가진 "runat" 이라는 Attribute만 추가하면 된다.("server"는 코드를 서버에서 실행하기 위해, "proxy"는 브라우저가 호출할 수 있게 하기 위해 사용한다.)

<script runat="server-proxy">
        function getData() {
                return 42; // or do something more interesting, like a database query
        }
</script>
<input type="button" value="get it" onclick="alert(getData())">

이것이 어떻게 동작을 할까? Jaxer가 클라이언트로 페이지를 전송하기 전 그것을 처음 처리할 때, Jaxer는 서버에서 동작하도록 구성된 어떠한 Javascript코드를 실행한다. : 특히, "server", "both", 또는 변수들 중 하나의 값을 가진 runat Attribute를 가진 script 블록이 있는. 당신은 callback이 가능하도록 처리하는 동안 정의된 몇몇의 기능을 디자인 할 수 있다. 이러한 기능은 오로지 해당 페이지로부터의 callback에게만 가능하다.

브라우저가 호출할 수 있도록 디자인 된 함수란 어떤것인가? script블록 내에 runat="server-proxy" attribute를 가지고 있거나, true 값을 가진 "proxy" 프로퍼티가 있거나, 페이지에 Jaxer.proxies 배열을 가진 것이다. 만약 이것들 중 하나가 있다면, 그 함수는 페이지 처리 과정 마지막에 서버에 캐시(저장)된다. 그리고 그 안에서 같은 이름을 가진 proxy 함수가 브라우저 영역의 페이지에 삽입된다. proxy 함수가 호출될 때, Jaxer로 돌려주는 XMLHttpRequest가 브라우저에서 생성된다.; Jaxer는 원래 함수를 찾아서 그것을 실행한다.; 그러면, proxy 함수가 처리한 것 처럼 결과 값이 브라우저로 리턴된다.


사실은, 모든 호출가능한 서버측 함수마다 두개의 proxy함수가 브라우저 영역의 페이지에 삽입된다.: 하나는 서버측 함수와 동일한 이름을, 나머지는 그것의 이름에 "Async"가 첨부된 것이다. 두번째 것은 비동기 호출을 생성하는데 사용되고, 나머지 하나는 요청이 서버에서 생성되고, 처리되고, 돌아올 때까지 브라우저가 멈춰있지 않도록 한다. 비동기 버전은 추가적인 첫 인자를 취한다. : 서버가 응답을 받았을 때, 호출되는 함수. 그 함수는 그 자신의 서버측 함수의 반환된 결과를 취한다.


예를 들어보자 :
<script runat="server-proxy">
        function getLastName(firstName) {
                var lastName = Jaxer.DB.execute(
                "SELECT lastName FROM names WHERE firstName = ?", firstName).singleResult;
                return lastName;
        }
</script>
<script>
        function showFullNameNow() {
                var firstName = document.getElementById("first").value;
                var lastName = getLastName(firstName);
                show(firstName, lastName);
        }

        function showFullNameSoon() {
                var firstName = document.getElementById("first").value;
                getLastNameAsync(

                        function(lastName) { show(firstName, lastName); },
                        
// this is called when getLastName() returns
                        firstName);
        }

        function show(firstName, lastName) {
                alert(firstName + " " + lastName);
        }
</script>
<input type="button" value="Show Now" onclick="showFullNameNow()">
<input type="button" value="Show Soon" onclick="showFullNameSoon()">

getLastName() 함수를 서버에서 호출하는 것은 브라우저에서 호출하는 것 만큼 쉽다는 걸 기억하자. - 왜냐하면, 사실은 브라우저에 서버의 진짜 getLastName() 함수를 위한 proxy기능을 하는 getLastName() 함수가 있기 때문이다. getLastNameAsync()를 사용하기 위해, 비동기 흐름을 허용하는 약간의 소스코드의 재구성이 필요하지만, 이것은 사용자 편의성의 향상을 종종 의미하곤 한다.


많은 경우에, Callback하는 동안 서버에 있는 다른 함수들이 필요하게 된다. 예를 들어, getLastName()은 어떠한 접근권한을 필요로 한다고 하자. 그 권한은 getCurrentUser() 함수를 호출하는데 필요하고, isAuthorized()에서 호출된다. 그러나 getCurrentUser()와 isAuthorized()는 보안 문제 등으로 인해 브라우저에서 바로 호출되어서는 안된다. 이것을 해결하기 위해서, Jaxer는 페이지 처리 마지막 시점에 자동으로 다른 함수들을 캐시한다.(명시적으로 runat="server-nocache"또는 runat="both-nocache"라고 작성되지 않았다면.), 그리고, 그 함수들을 Callback 중에 다른 함수가 사용 가능하도록 한다. - 하지만 브라우저에서는 사용이 불가능하다. (우리는 단순화를 위해 비동기 버전을 생략했다.) :
<script runat="server">
        function getCurrentUser() {
                return Jaxer.session.get("user");
                // this will be available to other functions during a callback
        }

        function isAuthorized(user) {
                // this will be available to other functions during a callback
                return user.authorizationLevel > 4; // substitute some logic here
        }

        function getLastName(firstName) {
                var user = getCurrentUser();
                if( !isAuthorized(user)) throw "You are not authorized";
                var lastName = Jaxer.DB.execute(
                "SELECT lastName FROM names WHERE firstName = ?", firstName).singleResult;
                return lastName;
        }
        getLastName.proxy = true;
</script>
First name : <input type="text" id="first">
<input type="button" onclick="showFullName()">

모든 서버측 함수 getCurrentUser(), isAuthorized(), 그리고 getLastName()은 페이지 처리 후 저장되고, callback중에 사용이 가능하다.; 그러나 단 하나, getLastName()은 브라우저에서 직접 호출이 가능하도록 허용되어 있다. 그리고 필요에 따라 다른 함수를 호출할 수 있다. 브라우저를 통해 사용자와 상호작용하는 흐름에 실질적으로 필요한 단 하나의 proxied 함수를 한정짓는 방법에 대한 좋은 예제이다.


callback에 대해 좀 더 상세히 이해하고 싶다면 페이지의 lifecycle을 고려해라. Jaxer는 페이지를 읽고, 그것을 HTML으로부터 DOM으로 생성하는 처리를 하고, 몇몇의 함수를 생성하고, DOM을 조작하는 서버측 Javascript로 구동한다. 페이지의 끝 부분에는 HTML DOM이 HTML로 변환되고, 브라우저로 전송된다. 그러면서 Jaxer는 Callback 하는 동안 필요한 함수를 캐시하고, 서버 측의 global "window" Javascript 컨텍스트를 제거하고, 그 컨텍스트 내의 모든 Javascript 함수와 데이터 역시 DOM으로 변경한다. 그리고 그것에 대한 다음 요청을 준비한다. 캐시된 함수들은 데이터베이스에 저장되지만, 메모리에도 bytecode로 동시에 저장되기 때문에 효율적이다.(Jaxer 인스턴스의 메모리). 그러면 매번 callback때 마다 빈 DOM을 가진 빈 "window" 오브젝트가 가용하게 되고, 해당 페이지를 위해 캐시된 함수들이 그 "window"에 재구성된다.(필요하다면, database로부터 가져온 후, 메모리 내의 bytecode를 이용한다.) 마지막으로, Callback에서 한정된 특별한 함수가 실행된다. (우리는 함수의 versioning, 브라우저로, 브라우저에서의 데이터 패키징, 예외처리 등에 관해 상세한 언급은 하지 않겠다.)


이러한 흐름에 따라, 당신은 Callback하는 동안 가용한 환경이, 최초 페이지의 그것과 동일하지 않다는 것을 볼 수 있었을 것이다. 기본적으로, 단지 캐시된 함수만 가용하다. 대부분의 경우에, 동작이 원활하고, 매우 효율적이다.: 함수를 호출하기 위해서 기존 페이지 전체를 재 구성할 필요가 없고, callback 도중에 브라우저에서 변경될 가능성이 있는 DOM에 대해 어떻게든 그 DOM과 동기화 시키기 위한 복잡함도 없다. 그리고 그 페이지에서 사용자 별로 한정된 데이터가 다른 사용자에게 개방되는 위험성 등에 대한 문제도 없다. 그러다 가끔 당신이 좀 더 컨트롤 해야할 필요가 있을 때가 있는데, 예를 들면, 서버 측 라이브러리를 가용하게 만들때가 그러하다. 만약 서버 측 라이브러리가 순수하게 함수로만 구성되어 있다면, 아마도 페이지가 초기에 처리 되는 동안 로드될 때 자동으로 캐시가 되며, 모든 것이 정상 동작하게 된다. 그러나 만약 비-함수적인 객체가 존재할 필요성이 있을 경우, 당신은 Callback되는 동안 그러한 것들을 스스로 재구성 할 필요가 있다. 어떻게 그것을 할 수 있을까? 만약 그 라이브러리가 외부 Javascript 파일을 포함할 경우, 가장 쉬운 방법은, "<script src="myLibrary.js" runat="server" autorun="true"></script>"를 통해 로드하는 것이다. autorun attribute는 Jaxer가 이 페이지에 대한 모든 요청 뿐 아니라 이 페이지에 대한 모든 callback에도 해당 라이브러리를 실행하도록 한다.; 효율성을 위해, 라이브러리는 bytecode로 컴파일 되고, 메모리에 저장된다.(Jaxer 인스턴스의 메모리). 다른 방법으로, 당신은 oncallback 이라고 불리는 특별한 함수를 정의할 수 있다.이 특별한 함수는 당신이 callback을 수행하도록 한 함수 전에, 이 페이지에 대한 모든 callback에서 실행된다. 당신의 oncallback() 함수는 환경이 세팅되어 잇는지, 그렇지 않으면 어떤것을 할 수 있는지 등을 체크할 수 있다. 좀 더 상세한 내용을 보고 싶다면, "the FAQ entry on oncallback()"을 보라.
Leave a comment

   5. 당신이 브라우저로 서버측 자바스크립트 함수를 호출했을 때, Jaxer는 함수의 이름과 인자들을 JSON 스트링으로 감싸고, 그것들을 XMLHttpRequest를 통해 정보를 추출해내는 Jaxer로 전송하고 당신이 호출한 서버측 함수를 호출한다. 그리고 그에 대한 결과는 JSON을 사용하여 돌려받고 마치 서버측 함수를 즉시 실행한 것처럼 브라우저로 돌려준다.


전통적인 웹 Stack과 비교해 볼 때, Jaxer는 클라이언트와 서버 사이에 보다 가까운 관계를 허용한다. 왜냐하면, Jaxer는 단일하고, 통합되며 친숙한 개발 패러다임을 제공하기 때문이다. 당신은 지속적으로 컨텍스트를 교체하거나, 다수의 hat을 입거나(wear multiple hats, ?), 데이터와 함수 호출을 싸고 추출할 필요가 없다. 쉽게 말하면, "모든 것은 Ajax로 통한다". 당신은 Jaxer를 (아래 그림처럼) 전체 어플리케이션에 적용하거나, 프레젠테이션 레이어에서 서버와 클라이언트, 통합할 Back-end - API가 방화벽 뒤에 안전히 보존된 - 의 기존 시스템들의 모든 프레젠테이션 로직을 Jaxer에 의존하여 통합하는데 적용할 수 있다.



보다 상세한 내용

Jaxer는 Apache 2.x 웹 서버에 플러그인 형태로 설정되어 있고, 또한 Java 기반의 Jetty 웹 서버도 지원한다. 추후 버전은 IIS와 같은 다른 웹 서버도 지원할 것이다. 세계적인 수준의, Javascript와 DOM 표준을 준수하는 서버의 기능을 제공하기 위하여, Jaxer는 대중적인 Firefox 브라우저의 Mozilla 엔진을 탑
재하고 있다. Jaxer는 PHP 또는 Ruby와 같은 다른 언어들에 의해 생성된 동적 페이지를 수정하기 위해 Apache에 입, 출력 필터로 Layered 되어있다.



Jaxer Core vs. Framework

Jaxer는 C/C++로 된"Core" 코드와 서버 사이드 Javascript인 "FrameWork"로 구성되어 있다. Core는 Javascript 파서와 런타임, HTML 파서와 DOM 엔진, 서버에서 문서가 처리될 때프레임 워크를 호출하는 이벤트 아키텍처를 제공한다. 프레임워크는 Jaxer Logic을 제공한다. 예를 들면 해당 코드가 서버에서 수행될 것인지 클라이언트에서 수행될 것인지를 결정하거나, 클라이언트에서 호출가능한 서버 사이드 함수를 위해 Proxy를 생성하거나, 직렬화 및 직렬화 해제 등의 로직이 있다.


프레임워크가 Javascript로 구성되어 있기 때문에, Ajax 개발자들에 의해 쉽게 확장될 수 있다. Jaxer는 오픈 소스이며, 무료이고, end-to-end의 Ajax 개발 및 풍족한 프레젠테이션 레이어의 최상단에 존재하는 back-end / 확장가능한 플랫폼이다.



Jaxer page lifecycle

Jaxer를 이용하여 구성된 통상적인 웹 페이지의 LifeCycle을 보자 :

   1. 디스크로부터 읽히는 정적인 HTML도 PHP나 Ruby, Java등으로 생성되는 동적인 페이지 등 모든 HTML 문서는 서버에서 life를 시작한다. Jaxer는 DOM을 생성하고 배치하며, 서버에서 동작하도록 디자인 된 Javascript 코드를 전체 문서가 소비될 때까지 실행한다.
   2. 결과는 프레임워크와 개발자를 통해 수정된 DOM 형태이다. : 특히, proxy들은 자동적으로 클라이언트가 호출할 수 있는 서버 측 함수(server-side client-callable functions)를 대체해준다. Callback과 지속적인 Session-type의 데이터로 디자인 된 Javascript 함수를 저장하는 작업을 포함한 몇몇의 중요한 부작용이 있다.
   3. 새로운 DOM은 HTML 문서로 직렬화 되고 보통의 통신방법처럼 클라이언트에게로 전송된다.
   4. 클라이언트는 HTML 문서를 수신하고 처리를 계속하여 DOM으로 부터 HTML을 재생성하고, 이 시간에 페이지에는 클라이언트 쪽 Javascript만 남겨두는 작업을 수행한다.
   5. 클라이언트 측의 Proxy 함수중 하나가 호출될 때, 그것의 파라미터는 자동적으로 JSON(JavaScript Object Notation)형태로 직렬화 되고, XMLHttpRequest는 이 파라미터들을 이용하여 실제 함수를 호출하기 위하여 서버로 전송된다.
   6. 서버가 이러한 특별한 요청을 받았을 때, 파라미터들은 직렬화에서 해제되고, 호출되어야 하는 함수는 파라미터들을 넘겨받아서 호출된다. 그리고 결과(또는 예외)는 다시 JSON 형태로 직렬화 된다.
   7. 반환되는 데이터는 클라이언트에서 직렬화가 해제 되고 proxy에 결과값으로 넘겨진다.(또는 클라이언트 측 예외로 나타난다.)


서버 쪽에서 개발자들이 작성한 Javascript 환경은 데이터 베이스(SQLite, MySQL 등), 파일 시스템, 네트워크(저레벨의 소켓부터 고레벨의 웹 서비스까지), HTTPRequest 및 Response 데이터, 그리고 추후에는 Java, PHP, Ruby와 같은 외부 서버 사이드 플랫폼과 직접 통합될 Jaxer 프레임워크에 의해 향상된다.


Jaxer Page Flow (Non-Callback)


Jaxer Callback Flow



Leave a comment

출처 : http://www.aptana.com/jaxer/book - Aptana Jaxer Documentation

Rich 웹 어플리케이션들과 그것을 기반으로 한 사이트는 훌륭한 가치를 지니는 반면, 개발, 배포, 유지가 어렵다. 어플리케이션 또는 사이트의 클라이언트는 복잡한 DHTML, Javascript, CSS의 섬세한 조합을 필요로 한다. Aptana Studio IDE는 클라이언트 쪽의 불편을 덜어주기 위해 구성되었다.


그러나 Ajax-Style(Web 2.0)의 어플리케이션에는 또 하나의 어려운 면이 있다. 바로 서버쪽. 개발자들은 브라우저 쪽의 다양한 기술 및 라이브러리 뿐만 아니라 서버쪽의 완전히 다른 패러다임들 역시 알고 있어야 한다. : HTML을 문자열로 보내기 위한 템플릿화 된 프레임워크, Java, PHP 또는 Ruby와 같은 다른 언어들, 웹 클라이언트와 서버 사이에 통신하기 위한 다양한 방법들에 대해서. 그리고 이러한 클라이언트-, 서버 중심적인 기술들은 서로 고르고, 유연하고, 유지보수 가능한 제품으로 엮여야만 한다. 만약 이것이 바르지 않으면, 낮은 성능, 과도한 네트워크 부하, 사용량을 측정하고 모니터링하는데 어려움을 겪고, 지속적인 두통이 생길 것이다.


Aptana의 Ajax 서버인 Jaxer는 이러한 어려움들을 직접적으로 처리해준다. Jaxer는 개발자들이 어떠한 서버측 기술을 필요로하지 않더라도 그들이 이미 잘 알고 있는 클라이언트 쪽 패러다임 - Javascript, HTML DOM, CSS - 을 서버측에서도 지속적으로 사용할 수 있도록 통일된 개발 모델을 제공한다.


어플리케이션 또는 사이트의 서버와 클라이언트 측은 습득해야되는 별도의 기술없이, 쉽고 직관력 있게 통신할 수 있다. 클라이언트의 자바스크립트 함수는 데이터베이스의 정보를 가져오는 자바스크립트 함수를 쉽게 호출할 수 있고, 필요에 따라서 Back-end의 자바 비즈니스 객체와 네트워크 리소스에 접근할 수 있다.


DOM은 페이지를 전달할 때, 클라이언트가 사용하게 될 동일한 Ajax 라이브러리를 서버에서 사용할 수 있도록 준비되어 있다. 웹 개발자들이 값을 전달하는 데 Ajax 기술에 초점을 맞출 수 있도록 개발과정이 보다 더 간단하고 효율적이게 된다.


사실, 전체 Rich 웹 어플리케이션은 단일한 HTML 문서로 쓰여지게 된다. Jaxer는 완전히 웹 표준을 기반으로 구성되었기 때문에, 독점적인 마크업 또는 프로토콜에 대해 독립적이다. 어플리케이션과 사이트는 이제 순수하게 end-to-end로 Ajax 기술을 이용하여 구성될 수 있다. 또는 Jaxer는 Java나 PHP처럼 비즈니스 로직 레이어의 최상단인 Presentation 레이어(클라이언트 / 서버 양쪽에서)에서 사용될 수 있다.


Jaxer는 대부분의 IT 네트워크 구성에 쉽게 맞출 수 있다. : Jaxer는 Apache에 포함되어 완전한 웹 어플리케이션 / 페이지 서버의 기능을 수행하고, 기존의 웹 서버 집합에 통합되거나 outbound HTML 스트림의 post-processing을 위한 최대의 유연성을 발휘하는 Proxy로 배포될 수 있다.


Post-processor로서, Jaxer는 성능과 사용률과 작동에 대한 모니터링을 위해 outbound HTML을 지능적으로 사용한다.
; 어플리케이션의 최적화(ex. 네트워크 지연을 최소화 하기 위한 Javascript와 CSS 파일 간소화)
; 보안과 유연성의 필요성을 강제
; 기존의 어플리케이션에 설계되지 않은 새로운 특성/기능을 추가하고자 할때
이것은 가능성을 만들어 준다. 왜냐하면 Jaxer는 DOM, Javascript, CSS를 브라우저처럼 기본적으로 알고 있기 때문이다.


Jaxer는 Firefox 브라우저와 같은 Mozilla 엔진의 최상부에 탑재된다. Jaxer는 확장 가능한, 대시보드, optimizer, IT에서 사용되는 compliance Filter를 구축하고, 조직이 다수의 기존 웹 어플리케이션을 마케팅하기에 미래에도 경쟁력 있는 플랫폼이 될 것이다. 수집된 지식은 새로운 웹 어플리케이션과 사이트에 조합될 수 있다. - Jaxer로 보다 효율적으로 개발한.
Leave a comment

기보에서 포틀릿을 생성할때 각 시스템(일단은 그룹웨어)으로부터 받는 정보는 XML을 이용하여 받기로 하였다.

아무 생각 없이 XML을 가져오는 URL을 포틀릿 소스에 반영했으나, Javascript 에러가 발생했다.

"엑세스가 거부되었습니다."라고.

예전에 장고단에서 액세스 관련 에러가 떴을 때, document.domain, 즉, 도메인이 달라서 그랬던 경우가 있었기 때문에 document.domain='kibo.or.kr'로 변경해서 처리했었던 기억이 있어서 해당 소스를 추가시켜주었으나 여전히 에러 메시지가 발생했다.

혼자 한참을 삽질하다 박수석님께 여쭤보니, 그런 문제는 신뢰할 수 있는 사이트로 등록해두면 해결할 수 있다고 하여 해결 -_-;

도메인 문제도 있고 여러 가지 문제 점이 있어 회사 내부에서 쓰는 시스템간에는 신뢰할 수 있는 사이트로 미리 등록해둔다고 함.

어렵다. Web.
Leave a comment

IBM 문서 http://www.ibm.com/developerworks/xml/library/j-jtp03225.html의 자체번역입니다. 이상하더라도 이해하시길..=_=)


자바 이론과 실습 : XQuery를 이용한 Screen-Scraping
 - XQuery는 HTML 추출과 변환을 쉽게 할 수 있게 합니다.

XQuery 는 XML 문서들로부터 정보를 추출해내기 위한 W3C 표준으로 현재까지 14번째 초안으로 확장되었다. XQuery의 주된 관심사가 반-구조화된 문서 데이터들 기반의 쿼리에 대한 것인 반면에, XQuery는 몇몇의 실용적인 면에서 놀라울 정도로 매우 효과적일 수 있다. 이번 달의 '자바 이론과 실습'은 컬럼니스트 Brian Goetz가 어떻게 XQuery가 HTML Screen-Scraping 엔진으로써 효과적으로 사용될 수 있는지 보여줄 것이다.

지난 달, Java Technology의 전문가 Sam Pullara는 자바 사용가능한 최신형 핸드폰, Nokia 6630을 보여주었다. 그것은 모든 기술 -- Embedded JVM, GPRS, Bluetooth -- 이 담겨있었지만, 그것은 모든 스마트폰이 앓고 있는 동일한 전염병 -- 한정된 화면 크기 -- 을 앓고 있었다.  몇몇의 웹 사이트들은  CellPhone기반의 브라우저를 지원하고 있고, 내장 브라우저들도 작은 화면 내에서 페이지를 효과적으로 나타내기 위해 노력하고 있지만, 폰 화면에서 일반적인 웹 페이지를 보기 위해서는 코끼리를 당신의 자동차 뒷 좌석에 밀어넣는 것(당신과, 당신의 자동차와, 코끼리 모두에게 불만을 주는)만큼의 많은 노력이 필요하다. Sam은 그가 좋아하는 웹 사이트에서 데이터를 Screen-Scraping하고, 작은 화면을 위해 그 데이터들을 Reformatting하는 단순하고, 멋진 솔루션을 만들어 두었다.


새로운 접근

당신은 HTML문서로부터 데이터를 추출하기 위한 많은 접근 방법을 사용할 수 있다. 나는 Sam이 가져온 접근법, Screen-Scraping 툴을 이용한 것(페이지로부터 적절한 데이터를 추출)이든, Stylesheet 툴(데이터를 재포맷하여 스크롤링 없이 페이지를 잘 맞출 수 있게)을 이용한 것이든, XQuery를 이용한 접근법을 정말로 좋아한다. 적은 양의 기반조직과 몇몇의 꽤 단순한 XQuery 표현으로, 다량의 데이터 소스와 관련된 데이터 -- 교통정보, 날씨, 재정적인 시세 등 -- 를 폰에서 멋지게 보여지도록 추출할 수 있게 된다.

나는 종종 HTML 페이지를 Screen-Scraping하는 상황을 겪는데, 이 페이지들은 특정한 문제에 대하여 매우 민감한 솔루션으로 보인다.(?) 그러나 Screen-Scraping을 위한 자바기반의 툴킷은 매우 적다. 많은 HTML 파싱 툴들이 사용 가능하지만, 그것들은 보통 충분한 추상적인 성능이 부족하고, HTML을 따르며 범용으로 사용하기엔 한계가 있고, 오랜 시간동안 구조가 변화되고 동적으로 생성되는 페이지들을 다루기에는 부족하다.

저품질의 HTML과 훌륭한 XML-처리 세트간의 차이를 연결하기 위해, 당신은 머저 HTML을 XML로 컨버트 할 필요가 있다. 다수의 툴이 당신이 이러한 일을 하는 것을 도와준다. ; JTidy 툴킷은 그 일을 멋지고 쉽게 해준다. JTidy는 HTML을 일반적인 품질(다시 말하면, 나쁜)로 읽어들일 수 있도록 설계되어 있고, 명확한 어떤 것을 출력하며, 또한, XML 파서에 제공될 수 있는 HTML 문서를 탐색하기 위한 DOM 인터페이스를 제공한다. Listing 1에 있는 코드는 HTML 문서를 InputStream으로부터 읽어들이고, 문서에 대한 DOM표현을 생성할 것이다.



이 러한 간단한 변환으로, 당신은 거의 모든 웹페이지들을 XML 문서로 처리할 수 있고, 당신이 데이터를 추출하기 위하여 -- SAX, XSL, XPath -- 선호하는 XML 툴을 적용하고, 지정할 수 있다. XSL은 XML로부터 정보를 추출하고, 그것의 표현을 변환해 주기 위한 설계라는 명확한 목적이 있는 선택이 있는 반면에, 만약 이미 당신이 그것을 알지 못한다면, XSL은 명백한 배움 단계가 있다. 그리고 극도로 단순한 XSL 변환일지라도 매우 귀찮게 복잡하다. XPath는 추출이라는 부분 -- XSL과 XQuery 모두 컨텐트 선택에 사용됨 -- 에서 매우 훌륭한 후보이고, 당신이 XPath를 당신이 필요로하는 데이터를 꺼내고, 스스로 HTML 포맷팅하기 위해 쉽게 사용되지만, XQuery는 그것을 훨씬 쉽게 해결해준다.



XQuery : (터무니없이) 짧은 투어

XQuery 는 잠재적으로 매우 큰 XML 데이터셋으로부터 데이터를 추출하기 위해 설계되었다. 입력 데이터 셋은 XML 문서일 필요는 없지만 XML 문서일 수도 있다. 그러나 또한, 입력 데이터 셋은 XML 데이터베이스 내에 인덱스 되어 저장된 문서들의 집합일 수도 있고, 또는 관계형 데이터베이스 내의 테이블의 집합일 수도 있다. SQL처럼 XQuery는 추출, 종합, 모음, 여러 다수의 데이터셋으로부터 데이터를 조합하는 기능을 포함한다.

단지 JSP, ASP, Velocity등의 템플릿 언어들의 표현처럼 XQuery는 두개의 도메인 -- Presentation Domain과 Computational Domain -- 으로부터 단일한 조합 문법으로 요소들을 조합한다.그 결과는 이미 스스로를 평가하기 위해 유효한 XQuery 표현으로 된 XML 문서이다.이 문서는 또한 "for"나 "let"처럼 XML 요소들을 혼합할수 있는 언어 구문을 가지고 있다.

Listing 2는 책들의 출판 목록을 보여주는 샘플 XML 문서, bib.xml을 보여준다. 나는 당신에게 XQuery가 하는 일에 대해 맛을 보여주고, 그리고 Screen-Scraping 예제로 넘어가기 위해, 몇 줄의 간단한 XQuery 표현을 보여줄 것이다. XQuery 문법과 Use-Case를 커버하기 위해서는 수 백페이지가 소요된다. -- 좀더 자세한 참조 자료와 예제는 Resource 섹션을 참조하라.



Listing 3은 1991년 이후 Addison-Wesley에서 출간된 모든 책들을 선택하고, 그 책들의 제목을 추출하고, 제목들을 bulleted list(<ul>)로 포매팅하기 위한 XQuery를 보여준다. "Presentation mode"(<ul> 또는 <li> 등의 태그같이 출력으로 직접 통과될 데이터)에서 "Code mode"까지의 모드 전환은 중괄호로 표시된다. ; "Code mode"에서 "Presentation mode"로의 묵시적인 전환은 return 절 이후에 즉시 발생한다.



"for" 문으로 시작되고, "Flower Expression"이라고 종종 불리는 (약어 'FLWOR' - for-let-where-order-return 로부터) 쿼리 문법은 이 예제에서 bib.xml 문서 내의 <book>노드의 집합은 XPath의 표현이 사용되었고,나아가 특정한 쿼리 조건(the publisher is Addison-Wesley, and the publication year is after 1991)에 부합하는 노드들을 걸러내는 것 처럼 문서로부터 XML 노드들의 순서를 선택한다. 이 각각의 노드들을 위해 이 문법은 마크업(<li> 태그)과 code(각각의 <book>노드에서 <title> 요소의 컨텐츠를 추출)의 혼합된 표현을 처리해준다.

이 단순한 XQuery 예제는 XQuery의 여러 형태를 보여준다. -- 하나의 문서 내에서의 Presentation과 Code의 혼합, XPath의 사용, 대체의 사용($b 참조), 평범하지 않은 Query 표현, XQuery 함수(data()), 그리고 출력되는 문서의 구조는 입력되는 문서의 구조와 일치하지 않아도 된다는 사실.

Listing 4는 출판 목록내의 단일한 <count> 요소에서 각각의 출판사 수를 출력하기 위한 좀 더 간단한 XQuery 표현을 보여준다. 이전의 예제처럼 노드들의 세트를 선택하기 위해서 XPath 표현을 사용하고, 노드의 개수를 세고, 개별적인 값을 선택하기 위한 XQuery 기능을 적용했다. bib.xml 문서내의 개별적인 출판사의 수를 숫자로 평가한다.



이러한 예제들은 XQuery에 의해 수행되는 쿼리들의 형태의 표면을 겨우 가져온다. -- 그것들은 단순히 당신이 이 예제들로 할 수 있는 것들의 종류에 대해 맛보기만 줄 뿐이다. 그리고 당신이 선택한 포맷으로 XML 문서들을 변환하기 위해 XQuery를 어떻게 사용해야 하는지를 제안한다. XQuery가 가진 능력이 다량의 문서 기반의 쿼리나 데이터 소스를 목표로 하고 있는 반면에 당신은 XQuery의 아주 단순한 부분을 사용하여 다양한 어플리케이션에서 HTML 문서들로부터 당신이 원하는 부분을 핸드폰 같이 화면 크기가 한정된 장치에서 관련 데이터를 표시할 수 있도록, 또는, 다수의 사이트에서 데이터를 모아서 표시하여 당신만의 포탈을 만들 수 있도록, Screen-Scrap할 수 있다.



XQuery로 Screen-Scraping 하기

웹 페이지를 Screen-Scraping을 위한 하나의 (또는 많은) 노력은 보통 스스로 증명할 수 없는 구조, 사이트 내에서 편집되는 컨텐츠의 구조가 변경되는 것, 또는 심지어 페이지 내에서 각각 다른 요청에 의해 추가, 삽입되는 각각 다른 동적인 컨텐츠다. 결과적으로, 당신은 응답되는 페이지의 어떤 부분이 당신이 추출하기를 원하는 데이터인지를 줄곧 생각해야만 한다.


StockPrices

Yahoo! Finance 페이지(http://finance.yahoo.com/q?s=IBM)로 부터 IBM 주식의 현재 가격을 추출해보도록 하자. 이 페이지에는 많은 정보들이 있다 -- 뉴스 헤드라인, 광고, 재정 데이터 -- 그러나 나는 "Last Trade"를 포함하는 셀 다음에 있는 주식 가격 데이터를 가지고 싶다. Listing 5의 쿼리는 "Last Trade"라는 텍스트를 포함한 모든 <td> 노드를 선택하고, 각각을 (나는 단 하나만 기대한다.) 위해, <td> 노드 이후에 나오는 컨텐츠를 포함하는 테이블 열을 출력한다. 컨텐츠들은 data() 함수에 의해 return절 내에 추출된다. 반면에, 나는 <td>노드 내의 텍스트 외에 모든 마크업을 또한 더 얻고 싶다. (이 쿼리의 교묘한 부분은 단지 text() [1] 부분이다. ; 여기서 진행되는 것은 text() 함수가 <td> 요소 내의 모든 텍스트를 매치시킨다. -- 이 경우 단지 하나 뿐이지만, XQuery는 그것을 알 수 없다. -- 그래서 나는 더욱 더 노드에 대해 텍스트 매칭을 하기 전에 먼저 첫 텍스트 노드를 선택하라고 말해야 한다.) 페이지가 페이지 내의 "Last Trade"라는 텍스트를 가진 테이블 셀을 포함하고 그 다음 셀이 주가를 포함하는 한, 페이지의 구조는 쿼리의 실패 없이 임의로 변경될 수 있다.



Weather

다른 페이지를 한번 시도해 보자. Yahoo! Weather 페이지는 많은 수의 포틀릿 패널들로 구성되어 있고 나는 리스트 된 도시들의 이름과 온도, 아이콘을 추출하고 싶다.(Yahoo! Weather 페이지(http://weather.yahoo.com)는 당신이 Yahoo!에 로그인 되어 있을경우 당신이 My Yahoo!에서 선택한 도시들의 날씨를 보여줄 것이고, 그렇지 않을 경우에는 샘플로 선택된 주요 도시들의 날씨를 보여줄 것이다.) Listing 6은 "New York, NY" 텍스트를 포함한 서브패널을 보여주고, 둘러싸인 테이블을 탐색하고, 모든 열을 선택하는 Query를 보여준다.



그러면, 각 열에 대해서, 쿼리는 관련된 세가지 데이터 행을 추출하고 -- 도시명, 온도, 아이콘 -- 이 정보들에 대해서만 간단한 테이블을 포함한 출력으로 나타낸다. 결과는 당신이 관심을 가진 도시들의 날씨 정보를 작은 화면에 맞게 간략하게 표현한다. 결과는 다음과 같다.



이 쿼리는 Listing 5의 쿼리만큼 확실하진 않다. "New York, NY"라는 텍스트는 small 요소 내부에 있다.(Yahoo!에서 다음 번에 쉽게 바뀔 수 있는 종류의 그들 페이지에서 재구성 할 마크업이다.) 또한 "New York, NY"은 날씨를 다룬 페이지에서는 한번 이상 쉽게 나타날 수 있다. 그러나, 이러한 위험 요소들은 보다 더 나은 쿼리를 개발해서 덜어낼 수 있다.; 많은 개발 옵션과 함께, 쿼리의 복잡성과, 안정성 사이의 조건이 있다.

Listing 5, Listing 6에서 보여진 쿼리들은 사용할 수 있는 쿼리들의 유일한 방법이 아니다. 좀 더 복잡한 XPath 문법을 사용하여, Listing 6에서 두개의 for절을 하나의 XPath 표현으로 넣고, Listing 5의 전부를 FLWOR 문법대신 XPath 표현처럼 사용한다. 만약 당신이 XPath 전문가라면, 당신은 아마도 XPath 지향적인 접근법을 쉽게 사용할 수 있을 것이지만, SQL에 관한 경험은 FLOWR 문법에 더욱 끌리게 할 것이다.

Tools

두드러지게 적은 양의 코드들이 HTML 페이지에 의지하여 XQuery를 실행시키는데 필요하다. JTidy 라이브러리는 HTML 문서를 깨끗하게 해주고, 그것을 DOM 오브젝트(Listing 1 참조) 형태로 표시한다. Saxon XQuery 엔진은 문서의 DOM 오브젝트에 의지하여 쿼리를 컴파일하고 실행한다. XQuery 구문을 문서의 DOM 표현에 의지하여 컴파일하고 실행하는데 Listing 7에서 보이는 것처럼 단지 6줄만 필요할 뿐이다.



쿼리 실행의 결과는 DOM 요소들의 리스트이다. 그리고 당신은 당신이 선호하는 DOM 조작 기술(당신이 가장 싫어하는 DOM 조작 기술도 괜찮다.)을 쿼리의 결과를 문서로 전환하는데 사용할 수 있다.

몇몇은 무료, 다른 몇몇은 상업적인 XQuery로 된 많은 구현 사례들이 가용하다. -- Resource를 참조하라.



종합

XQuery는 대량의 문서 기반의 쿼리로 설계되어 있는 반면에, 단순한 문서들의 변형에도 또한 좋은 툴이다. 작은 화면을 위해 복잡한 페이지를 단순화 시키거나, 집에서 만든 포탈에 많은 페이지들로 부터 요소를 추출하여 그것을 결집시키거나, 단순히 데이터를 얻기위한 프로그램적인 방법이 없기 때문에 데이터를 추출할 때, XQuery는 당신이 필요로하는 데이터들을 HTML 페이지에서 가져오는 비교적 쉬운 방법을 제공한다.

Resources
  • Participate in the discussion forum.

  • Howard Katz's An introduction to XQuery (developerWorks, June 2001) covers the basics and history of the XQuery standardization effort.

  • The tutorial, Process XML using XML Query (developerWorks, September 2002), by Nicholas Chase dives deeper into the uses and syntax ofXQuery.

  • You can read about Sam Pullara's cell phone in his blog.

  • Download JTidy from its home on SourceForge.

  • Check out the Saxon XQuery and XSL implementation.

  • You can try out the free community edition of the Mark Logic server, a content database which lets you search large document bases with XQuery.

  • The official specifications for XQuery can be downloaded from the W3C site; this page also hosts a list of XQuery implementations.

  • This set of slides from an XQuery tutorial offers a lot of good examples of what XQuery is good for and how to use it.

  • To learn more about Java technology, visit the developerWorks Java zone. You'll find technical documentation, how-to articles, education, downloads, product information, and more.

  • To learn more about XML, visit the developerWorks XML zone. As with the Java zone, you'll find technical  documentation, how-to articles, education, downloads, product information, and more.

  • Visit the New to Java technology site for the latest resources to help you get started with Java programming.

  • Get involved in the developerWorks community by participating in developerWorks blogs.

  • Browse for books on these and other technical topics.

About the author

Brian Goetz has been a professional software developer for over 18 years. He is a Principal Consultant at Quiotix, a software development and consulting firm located in Los Altos, California, and he serves on several JCP Expert Groups. See Brian's published and upcoming articles in popular industry publications.



Powered by ScribeFire.

Leave a comment