dw 기사를 보다가 JSDT(JavaScript Development Toolkit)를 알게 되었습니다. JavaScript 자동완성에 실시간 문법체크를 해줍니다. 어~ 좋은데, 그런데 어떻게 설치하지 찾아봤습니다만 WTP3.0 (Ganymede JEE 버전과 동일합니다.)에 기본적으로 포함되어 있더군요.

다음 이미지를 보시면 알 수 있듯이 다른 js 파일에서 선언된 변수도 가져다 쓸 수 있습니다.

위키를 보니 JSDT는 ATF(Ajax Toolkit Framework) 프로젝트의 서브 프로젝트로 진행중이네요.

JSDT에 대해 잘 요약된 DW기사도 일독을 권합니다.

간단한 객체 지향 자바스크립트 simple object oriented javascript 에 이어집니다.

지난 번 함수에 파라미터는 어떻게 전달할까요. onclick="issue.view('kenu')" 이렇게 말이죠.
<script type="text/javascript">
  var issue = {
    view : function(name) {
      alert(name + "! Let's see.");
    }
  };
</script>
<input type="button" value="check it out" onclick="issue.view('kenu')">

name 이라는 파라미터 전달 방식입니다. 설명하기 애매하지만 그냥 () 괄호 안에 쓰면 됩니다.

issue.open() 이라는 것을 만들어 볼까요.
<input type="button" value="open it" onclick="issue.open('kenu')">
이라고 추가할 수 있겠죠. 코드는 다음과 같아 집니다.

<script type="text/javascript">
  var issue = {
    view : function(name) {
      alert(name + "! Let's see.");
    },
    open : function(name) {
      alert(name + "! Open it, please.");
    }

  };
</script>
<input type="button" value="check it out" onclick="issue.view('kenu')">
<input type="button" value="open it" onclick="issue.open('kenu')">

view : function {} 다음에 오는 콤마(,) 이후에 view와 같은 형식의 open function을 만들면 됩니다. 두 개 만드는 법을 알았으니 3, 4, 5 계속 추가할 수 있겠죠.

 
자바스크립트 이야기입니다. 웹2.0이 뜨고나서, 특히 Ajax라고 불리면서 현란하게 브라우저를 수놓는 시대에 와서 가장 진보적인 위치를 차지하고 있는 것이 자바스크립트입니다. 자바에다가 스크립트를 붙이면 정말 다른 언어가 됩니다. 물론 베이직 언어와 달리 대소문자를 칼같이 지켜야 되는 점은 자바와 같지만, 컴파일이나 실행방식, 문법 구조 같은 언어적 특성이 자바와 많이, 아주 많이 다릅니다.

웹2.0을 전후로 자바스크립트 내에서도 큰 변화가 생겼습니다. 그 전에는 베껴쓰는 자바라 하여 컴퓨터 랭귀지 취급도 받지 못했습니다. "그거 아무나 하는거야 그냥 검색해서 찾아서 베껴쓰면 되잖아"라는 인식이 팽배했습니다. 물론 접근하기 쉽다는 인식도 있지만, 자바스크립트 언어의 진면목을 세상이 몰라 주었던 것이죠.

구글맵으로 세상이 들썩거리고 자바스크립트의 객체지향성을 일깨워 준 프레임워크가 나왔습니다. 미운 오리 새끼가 백조가 될 수 있는 가능성을 보여준 것이죠. 바로 prototype.js 입니다. 이것을 바탕으로 해서 많은 자바스크립트 프레임워크와 라이브러리들이 쏟아지기 시작했습니다.
기존에는 거의 팁으로만 취급받던 것들이 소프트웨어 제품으로 인정을 받기 시작했죠. 초창기에 script.aculo.us, rico, dojo 등이 선보였고, YUI(Yahoo UI) 같이 큰 포털에서 내어놓은 것도 있었습니다. 자바스크립트의 르네상스라고 해도 될지요. DHTML로 살짝 떴다가 내려갔는데, 이 때는 정말 부흥이 맞습니다. 아직도 지속되고 있구요.


허무할지 모르지만 그 유치했던 자바스크립트에서 이런 표현이 가능합니다.

<script type="text/javascript">
  var issue = {
    view : function() {
      alert("Let's see.");
    }
  };
</script>
<input type="button" value="check it out" onclick="issue.view()">

어떤 의미인지 설명하지 않아도 되겠죠. 하나 유념할 것은 issue에 종속된 view()라는 것입니다 그냥 view() 호출하면 안됩니다. 이렇게 scope를 주는 것이 의미가 있게 됩니다.

gmail에서 gtalk로 친구신청된 모습입니다. 오페라 9.2 브라우저에서는 "예"를 클릭해도 처리되지 않습니다.
사용자 삽입 이미지

파이어폭스2.0입니다. 여기는 "예"버튼에 관한 처리가 자연스럽게 됩니다.
사용자 삽입 이미지

오페라 브라우저는 빠른 서핑을 가능하게하는 장치들이 많이 있습니다. 반대급부로 자바스크립트의 해석이 저주받은 것 같습니다. 특히나 자바스크립트로 html을 생성해서 표시하거나 레이아웃에 영향을 주는 경우 아예 동작을 안 하거나, 이 정도면 크게 불만 없습니다만, CPU 100%를 치면서 메모리 증가하면서, 제 맥북프로의 팬을 돌려버립니다. 강제 종료만 있을 따름이죠.

여튼 점점 더 오페라로 서핑하기 힘들어집니다. 한 발 한 발 새로운 영역으로 다가설 때마다 프로세스 킬을 각오하고 다녀야 하니까요.
사용자 삽입 이미지
우측의 shop gallery 위젯이 페이지를 새로 고칠 때마다 바뀌는 것을 볼 수 있을 것입니다.
티스토리의 스킨 바꾸기에서 다음 스크립트만 삽입하면 됩니다.

<script src="http://www.okjsp.pe.kr/mashup/shopg.jsp">
</script>

확장자는 jsp 입니다만 브라우저에 저 주소를 호출해보면 자바스크립트만 나오는 것을 알 수 있습니다.

서버 쪽의 소스는 따로 설명해드리겠습니다. shopg.jsp 의 소스를 공개하면 다음과 같습니다.

<%@ page pageEncoding="utf-8"
    import="java.util.*, service1.*"%><%
        String q = "macbook";
        Map item = GetSearchResults.getItemByRandom(q);
%>
function showShopGallery() {
  var shopg_link = 'http://itempage.auction.co.kr/detailview.aspx?itemno=<%= item.get("itemId") %>';
  var shopg_image = 'http://image.auction.co.kr/itemimage<%= item.get("image") %>';
  var shopg_name = '<%= item.get("name") %>';
  var shopg_price = '<%= item.get("buyItNowPrice") %>';
  var htmlCode =
'<link rel="stylesheet" type="text/css" href="http://www.okjsp.pe.kr/mashup/style.css" />\
\
<table class="shopg"><tr>\
<td rowspan="2"><a \
href="'+shopg_link+'"><img \
src="'+shopg_image+'"></a></td>\
<td><div class="shopg_name">'+shopg_name+'</div></td>\
</tr>\
<tr>\
<td>'+shopg_price+'</td>\
</tr></table>\
';

  document.write(htmlCode);
}

showShopGallery();

키워드는 "macbook"입니다. 이것을 자바스크립트 호출시 부르도록 바꿀 수도 있습니다. 그건 따로 설명하겠습니다. 아주 기본적인 프로그램이기 때문에 예외적인 데이터 처리는 빠져있습니다. 보안, 캐싱, 문자열 처리 등의 안전장치들이 앞으로도 추가되어야 합니다.

서버쪽에서 어떤 변화가 있었는지 궁금하신 분들은 프로젝트 홈페이지의 소스들을 받아보세요. 커밋해 놓았습니다. http://code.google.com/p/shopgallery

블로그에서 자바스크립트를 호출하는 도메인이 다른데도 "Access Violation" 에러가 나오지 않고 정상적으로 동작하는 것을 보면 현재 도메인의 함수와 원격 도메인의 자바스크립트가 서로 상관하는 것이 없어서인듯 생각되는군요.

일단 화면단에서 가장 기본적으로 처리해야하는 것은 일단락 지겠습니다.
자바스크립트의 특징 중 하나는 위에서 아래로 해석되면서 실행되는 것입니다. 때문에 위에서 선언되지 않은 함수를 호출하면 undefined 라고 에러를 발생하게 됩니다. 그 함수가 바로 아래 빤히 보여도 말이죠. 때문에 함수의 선언은 상단에서 이뤄져야 합니다. 함수의 호출은 아래쪽에 위치해야 합니다.

동적으로 바꾼 자바스크립트 부분을 함수로 바꿔보겠습니다.

<script type="text/javascript">
function showShopGallery() {
  var shopg_link = 'http://itempage.auction.co.kr/detailview.aspx?itemno=A099090503';
  var shopg_image = 'http://image.auction.co.kr/itemimage/016/85/02/0168502107.gif';
  var shopg_name = '1+1고객행복상품07가을/에니팅그래픽티셔츠시즌2/R13552/남여공용/착불';
  var shopg_price = '8,900원';
  var htmlCode =
'<link rel="stylesheet" type="text/css" href="style.css" />\
\
<table class="shopg"><tr>\
<td rowspan="2"><a \
href="'+shopg_link+'"><img \
src="'+shopg_image+'"></a></td>\
<td><div class="shopg_name">'+shopg_name+'</div></td>\
</tr>\
<tr>\
<td>'+shopg_price+'</td>\
</tr></table>\
';

  document.write(htmlCode);
}
showShopGallery(); // 함수 호출
</script>


함수로 만드는 것은 아주 간단하게 끝났습니다.


관련글: http://okjsp.tistory.com/tag/openapi

[shopgallery] 개발 구조에서 일단 화면에 보이는 것을 만들었습니다. 이렇게 만들어진 화면에 컨텐츠를 자유롭게 바꾸기 위해서는 동적으로 html 태그가 만들어져야 합니다.

데이터가 들어가는 부분 외의 style영역은 따로 파일을 만들어도 좋을 듯 합니다.
다음과 같이 코드가 분리됩니다.

style.css

.shopg {
  border: 1px solid #88F;
  background-color: #FEE;
  padding : 1px;
}
.shopg img {
  border: 1px solid #88F;
  width : 65px;
}
.shopg td {
  font-size : 11px;
  width: 65px;
}
.shopg_name {
  height: 39px;
  overflow: hidden;
}

simple.html

<link rel="stylesheet" type="text/css" href="style.css" />

<table class="shopg"><tr>
<td rowspan="2"><a
href="http://itempage.auction.co.kr/detailview.aspx?itemno=A099090503"><img
src="http://image.auction.co.kr/itemimage/016/85/02/0168502107.gif"></a></td>
<td><div class="shopg_name">1+1고객행복상품07가을/에니팅그래픽티셔츠시즌2/R13552/남여공용/착불</div></td>
</tr>
<tr>
<td>8,900원</td>
</tr></table>


이제 simple.html 을 javascript를 이용해서 출력하도록 바꿔보겠습니다.
html에서는 모두 큰따옴표를 썼기 때문에 자바스크립트에서 문자열은 작은따옴표를 이용해서 둘러싸도록 하겠습니다.

자바스크립트 문자열의 특징은 자바와 다르게 줄 끝에 \ 를 붙여서 이어쓰기 할 수 있습니다. 때문에 이렇게 문자열을 만들 수 있습니다.
simple.html

<script type="text/javascript">
  var htmlCode =
'
<link rel="stylesheet" type="text/css" href="style.css" />\
\
<table class="shopg"><tr>\
<td rowspan="2"><a \
href="http://itempage.auction.co.kr/detailview.aspx?itemno=A099090503"><img \
src="/'>http://image.auction.co.kr/itemimage/016/85/02/0168502107.gif"></a></td>\
<td><div class="shopg_name">1+1고객행복상품07가을/에니팅그래픽티셔츠시즌2/R13552/남여공용/착불</div></td>\
</tr>\
<tr>\
<td>8,900원</td>\
</tr></table>\
';

  document.write(htmlCode);
</script>

일단 프로그램화 시키는 것은 성공했습니다. 이제 변수를 뽑아야죠.
'... href="http://itempage.auction.co.kr/detailview.aspx?itemno=A099090503"> ...'
위 코드가 다음과 같이 나눠집니다.
'... href="'+'http://itempage.auction.co.kr/detailview.aspx?itemno=A099090503'+'"> ...'
동적으로 변하는 부분의 양쪽을 문자열 덧셈표시로 바꾼 것이죠. ' 로 막고 + 붙이고 ' 로 다시 문자열 시작을 합니다. 이것을 변수처리해주면 됩니다.
var shopg_link = 'http://itempage.auction.co.kr/detailview.aspx?itemno=A099090503';
...
'... href="'+shopg_link+'"> ...'

코드를 바꾸면 다음과 같습니다.
simple.html

<script type="text/javascript">
  var shopg_link = 'http://itempage.auction.co.kr/detailview.aspx?itemno=A099090503';
  var shopg_image = 'http://image.auction.co.kr/itemimage/016/85/02/0168502107.gif';
  var shopg_name = '1+1고객행복상품07가을/에니팅그래픽티셔츠시즌2/R13552/남여공용/착불';
  var shopg_price = '8,900원';
  var htmlCode =
'<link rel="stylesheet" type="text/css" href="style.css" />\
\
<table class="shopg"><tr>\
<td rowspan="2"><a \
href="'+shopg_link+'"><img \
src="'+shopg_image+'"></a></td>\
<td><div class="shopg_name">'+shopg_name+'</div></td>\
</tr>\
<tr>\
<td>'+shopg_price+'</td>\
</tr></table>\
';

  document.write(htmlCode);
</script>

데이터의 1차 분리가 끝났습니다. 점점 프로그램 짜는 듯 느껴지십니까.

관련글: http://okjsp.tistory.com/tag/openapi


 

꽤 오랜 동안 제 웹 생활의 중심은 오페라가 되어 왔습니다. 지난 번 올블로그 3주년 행사에서 만난 하늘이님 블로그에 올린 글을 보고 9.2부터 사용하기 시작했습니다. 기능이나 이미지 렌더링이나 irc 채팅지원, RSS 뉴스리더 등의 특징을 잘 활용하고 있습니다.

하지만, 자바스크립트 해석이 달라서 오작동하거나 아예 동작을 하지 않거나, 혹은 원어데이 같은 사이트는 CPU 100%으로 가게 만들더군요.

다음 사이트의 경우입니다. daum 블로그는 읽기가 상당히 난해합니다. 스크린 캡쳐를 잡으면 이렇습니다. 글 우측에 보이는 스크롤바와 그 스크롤바가 가리는 글씨들... 음...
사용자 삽입 이미지

ie, ff에서는 잘 보입니다. 이케요. 브라우저 우측의 스크롤바 보이시죠.
사용자 삽입 이미지
contents from: http://blog.daum.net/miriya

그리고 최근 베타 오픈한 다음 검색쇼를 오페라에서 시도하다가 OTL 했습니다. 1단계에서 2단계로 잘 넘어갑니다. 하지만, 2단계 페이지에 있는 3단계 버튼을 아무리 클릭해도 꼼짝하지 않습니다.
사용자 삽입 이미지

저 다음 단계 버튼을 아무리 클릭해도 꿈쩍을 하지 않는다는 것이죠. 개똥벌래(firebug) 출동시켜서 코드를 비교해봤습니다. href="javascript:..." 와 같은 식으로 코딩을 하면 오페라에서 동작되지 않는 것을 알게 되었습니다. onclick 으로 수정하면 될 듯 합니다.
이 코드는 1단계에서 2단계로 넘어가는데 사용된 코드입니다. onclick 을 사용했습니다.
사용자 삽입 이미지

아래는 문제의 코드입니다.
사용자 삽입 이미지
href="javascript:..." 보이시죠.

브라우저가 많아지는데, 일일이 대응하기 힘들다는 것은 웹프로그래머인 저도 잘 알고 있습니다. 하지만 명품이냐 아니냐는 그 디테일이 어떠하냐로 구분되어집니다. 브라우저를 만드는 벤더나 오픈소스 그룹은 표준을 지키기 위해서 고군분투중입니다. 점차로 브라우저 특화된 함수보다는 웹표준에 입각한 빠른 성능의 브라우저를 만들고 있기 때문에 함수 사용만 웹표준에서 지정하는 방식으로 코딩을 하면 모든 브라우저에서 동작하는 잇점을 취할 수 있을 것입니다.

여튼 마이너 그룹에 속해서 투정 한 번 부려봅니다.
디버그(debug)는 쉽지 않은 작업입니다. 벌레 잡는 일이 프로그램에서 가장 정성이 많이 들어가는 작업이기도 합니다.
  1. 디버그의 기본
  2. 자바스크립트 디버그
  3. Java debugging
  4. JSP debugging
이 네 가지에 대해서 글을 써보려고 합니다.
디버그의 기원은 초기 계전기 사이에 있는 죽어있는 나방이 컴퓨터의 오작동을 일으켰고, 그 나방을 제거하자 정상 작동한 것에서 유래를 찾고 있습니다. 말 그대로 de+bug 입니다. ㅎㅎ

프로그래밍을 할 때 정상적인 데이터가 들어왔을 때를 기준으로 설계를 합니다. 하지만 프로그램을 실행할 때 발생하는 예상하지 못했던 경우로 인해 버그가 발생합니다. 숫자입력을 기대했는데, 문자가 들어오는 경우나 자료실을 운영하는데 서버의 하드디스크가 꽉 차는 경우를 예로 들 수 있습니다.

전자의 경우는 프로그램 수정을 통해서 디버그 하기 용이합니다. 후자의 경우는 하드디스크 공간 확장 내지는 불필요한 파일 삭제 등의 조치가 필요한데, 제가 설명하려는 영역에서 제외합니다.

프로그램을 디버깅하기 위해서는 버그를 발생시키는 코드와 그 때 사용된 테스트 값이 필요합니다. 버그를 재현할 수 있다면 프로그램의 약점을 파악한 것입니다. 따라서 디버깅이 쉽게 됩니다. 가장 어려운 경우는 간헐적으로 발생하는 버그입니다. 어떤 이유로 발생하는지 파악하기 어렵기 때문에 디버깅이 아주 어렵습니다. 범인 집 앞에 잠복해 있는 형사의 심정이라고 할까요.
디버깅을 의학에 비유한다면 내시경과 같습니다. 전신마취하지 않고 내시경 받아보셨나요. 아주 죽습니다. 디버깅도 프로그램을 한줄씩 살펴보는 작업이 동반되는데, 아주 고된 작업이 되기 쉽습니다.


debugging에서 알아야 할 용어들을 먼저 소개합니다.
  • breakpoint : 중단지점입니다. 실행 모드가 아닌 디버그 모드에서 프로그램을 중지하게 되는 지점의 표시입니다.
    보통 ide에서 소스 라인 맨 앞 여백을 더블클릭하면 생깁니다. 다시 더블클릭하면 없어집니다. resume을 실행하면 다음 중단점을 만날 때까지 실행됩니다.
  • step over : 한줄을 실행합니다. 함수가 있어도 실행 후 다음으로 넘어갑니다.
  • step into : 함수 내부로 들어갑니다.
  • step out : 함수를 끝까지 실행시키고 호출시킨 곳으로 되돌아 갑니다.
  • resume : 디버그로 한 줄 한 줄 실행시키는 트레이스 모드를 그만두고 실행모드로 전환합니다.

일단 기본적인 용어는 이상과 같습니다. 디버거의 종류에 따라 확장된 기능들이 있지만 기능이 소개될 때 같이 언급하겠습니다.
다음은 자바스크립트 디버깅을 설명하기 위한 소스입니다.

소스 : debug1.html (UTF-8)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>javascript debug</title>
<script type="text/javascript">
    // 전역변수 count
    var count = 0;
    /**
     * count값을 #place div에 출력하는 함수
     */
    function doPrint() {
        var place = document.getElementById("place");
        count++;
        place.innerHTML = count;
    }
</script>

</head>
<body>
<input type="button" value="trigger" onclick="doPrint()">
<div id="place"></div>
</body>
</html>

간단히 자바스크립트를 테스트할 수 있는 html과 javascript 코드입니다. input버튼을 클릭하면 doPrint() 자바스크립트 함수를 호출합니다.
디버깅을 위해서는 디버깅 도구가 필요합니다. firefox의 플러그인 firebug를 사용해보겠습니다.

소스1 debug1.html 파일을 만들고 firefox로 엽니다. 우측 하단의 firebug플러그인 활성화 영역을 클릭하여 그림1과 같이 firebug영역을 활성화합니다. 여러 개의 탭 중에서 Script 탭을 열면 HTML 소스와 함께 Script 소스들이 보입니다.

그림1 firebug script tab그림1 firebug script tab


디버깅은 쉽습니다. 그림2와 같이 JavaScript 함수의 내부인 14라인에서 앞쪽의 회색부분을 클릭하면 브레이크 포인트가 걸립니다. 디버그 준비 끝입니다.

그림2 JavaScript Debug Breakpoint그림2 JavaScript Debug Breakpoint

 
브라우저에서 버튼을 클릭하면 이 함수가 호출되는 소스인데 한 번 눌러보시면 화면에 브라우저 내의 객체들과 변수들이 그림3과 같이 firebug의 우측 패널에 나타납니다. 아울러 브레이크 포인트가 찍힌 곳에 화살표가 나타나면서 JavaScript의 실행이 중단 됩니다.

그림3 Debug start그림3 Debug start


id가 place인 element의 속성들을 확인할 수 있습니다. 여기서 디버깅을 계속하기 위해서 다음 아이콘들을 사용할 수 있습니다.

그림4 debug icons그림4 debug icons


하늘색 아이콘은 continue (F8) 입니다. resume 이라고 앞 서 설명드린 기능인데 다음 브레이크포인트를 만날 때까지 실행하게 됩니다. 만약 다음 브레이크포인트가 없다면 "기냥 고"가 되겠죠. ^^; 그 옆 아래로 향하는 아이콘은 Step Over (F10) 입니다. 한 줄 실행하고 대기하게 됩니다. 그 옆의 오른쪽으로 향하는 아이콘은 Step Into (F11), 라인에서 함수를 만나면 그 함수 안으로 비집고 들어가는 기능입니다. 그렇다면 나머지 한 개의 아이콘은 말 안해도 되죠? ㅎㅎ. 기냥 고?
삐질까봐 말씀드립니다. Step Out (F12) 인데 비집고 들어갔던 함수에 볼 게 없다면 나와야죠. 함수에서 밖으로 빠져나오게 됩니다.
흠... Step Over 를 실행해보죠. F10 키를 눌러도 됩니다. count 변수는 어디 숨었을까요? 함수 바깥에 있는 전역변수이기 때문에 this 안에 있습니다. 그림5를 참고하세요.

그림5 debug step over그림5 debug step over


to be continued...


+ Recent posts