반응형
 
  Enterprise Java Technologies Tech Tip에 오신 여러분을 환영합니다
Enterprise Java Technologies
테크팁
2005년 12월 27일자
  이번 호에서는,

» 자바 기술을 이용한 AJAX의 활용
» POJO를 Persistent Entity로 변환하기

를 다룹니다.

이 테크팁은 Java EE 5의 오픈소스 레퍼런스를 구현(프로젝트명: GlassFish)하여 개발되었습니다.GlassFish는 https://glassfish.dev.java.net/ 에서 다운로드 할 수 있습니다.

-샘플 아카이브 받기-
자바 기술을 이용한 AJAX의 활용
POJO를 Persistent Entity로 변환하기


자바 기술을 이용한 AJAX의 활용
 


저자 Greg Murray

AJAX는 'Asynchronous JavaScript and XML'의 머리글자를 딴 것으로, 웹 애플리케이션이 웹 페이지에 대한 사용자 인터랙션을 효율적으로 처리할 수 있도록 하는 수단을 제공한다(사용자 인터랙션이 이루어질 때마다 페이지를 리프레시(새로 고침)하거나 전체 페이지를 리로드하는 번거로움을 덜어줌). 이는 또한 브라우저를 이용한 리치 비헤이비어(rich behavior)를 가능케 해준다(데스크톱 애플리케이션 또는 플러그인 기반 애플리케이션의 경우와 유사). AJAX 인터랙션은 백그라운드에서 비동기적으로 처리되고, 그 동안 사용자는 페이지에 대한 작업을 계속할 수 있다. AJAX 인터랙션은 웹 페이지 내의 JavaScript에 의해 시작되는데, AJAX 인터랙션이 완료되면 JavaScript는 페이지의 HTML 소스를 업데이트한다. 변경 작업은 페이지 리프레시 없이 즉시 이루어진다. 이 AJAX 인터랙션은 서버측 논리를 이용한 폼 엔트리 검증(사용자가 입력하는 동안), 서버의 상세 데이터 검색, 페이지 상의 데이터에 대한 동적 업데이트, 그리고 페이지에서 폼을 부분적으로 제출하는 등의 작업에 이용될 수 있다.

여기서 특히 흥미를 끄는 부분은 AJAX 애플리케이션이 별도의 플러그인을 요구하지 않으며 플랫폼/브라우저 중립적 특성을 지니고 있다는 점이다. 첨언하자면, 구형 브라우저에서는 AJAX가 충분히 지원되지 않으며, 브라우저간의 차이를 유발하는 클라이언트측 스크립트를 작성할 때는 주의를 기울여야 한다. 따라서 브라우저의 차이를 추상화(abstract)하는 JavaScript 라이브러리를 사용하거나 경우에 따라서는 대체 인터랙션 기법을 이용하여 구형 브라우저를 지원하는 것도 좋은 방법이 될 수 있다. 자세한 내용은 자바 개발자를 위한 AJAX FAQ(영문)를 참조할 것.

자바 기술은 어떤 작업에 적합한가?

자바 기술과 AJAX는 서로 궁합이 잘 맞는다. 자바 기술은 AJAX 인터랙션을 위한 서버측 프로세싱 기능을 제공하는데, 이는 서블릿, JSP(JavaServer Pages) 기술, JSF(JavaServer Faces) 기술, 웹 서비스 등을 통해 제공될 수 있다. AJAX 요청 처리를 위한 프로그래밍 모델은 종래의 웹 애플리케이션에서 사용하던 것과 동일한 API를 사용한다. JSF 기술은 클라이언트측 JavaScript와 그에 대응하는 서버측 AJAX 프로세싱 코드를 작성하는 재사용 가능 컴포넌트를 생성하는 데 사용될 수 있다. 이제 AJAX와 서블릿의 활용 예제를 살펴보기로 하자.

자동 완성(autocomplete) 예제

사용자가 종업원에 관한 정보를 검색할 수 있는 웹 페이지를 상상해보자. 이 페이지에는 사용자가 종업원의 이름을 입력할 수 있는 필드가 포함되어 있다. 이 예제에서 엔트리 필드는 자동 완성(autocomplete) 기능을 가지고 있는데, 다시 말해 사용자가 종업원 이름의 일부를 입력하면 웹 애플리케이션은 입력한 문자로 이름이나 성이 시작되는 모든 종업원을 열거하여 이름을 자동으로 완성하게 된다. 자동 완성 기능은 사용자가 종업원의 정식 이름을 일일이 기억하거나 다른 페이지에서 이름을 찾아보아야 하는 번거로움을 덜어준다.

autocomplete example

검색 필드의 자동 완성 기능은 AJAX를 이용해서 구현될 수 있으며, 이를 위해서는 클라이언트와 서버 상에 코드를 제공해야 한다.

클라이언트 상에서

먼저, 사용자가 브라우저에 의해 로드되는 페이지의 URL을 지정한다. 한편, 이 예제에서는 JSF 컴포넌트, 서블릿, 또는 JSP 페이지에 의해 생성되는 HTML 페이지가 사용되었다고 가정하자. 페이지에는 JavaScript 함수 doCompletion()의 이름으로 된 onkeyup 속성을 가지는 폼 텍스트 필드가 포함되고, 이 함수는 폼 텍스트 필드에서 키를 누를 때마다 호출된다.

<input type="text" size="20" autocomplete="off" id="complete-field" name="id" onkeyup="doCompletion();">

사용자가 폼 텍스트 필드에 문자 "M"을 입력한다고 가정해보자. 그에 대한 응답으로 doCompletion() 함수가 호출되고, doCompletion() 함수는 다시 XMLHttpRequest 오브젝트를 초기화한다.

function initRequest(url) { if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else if (window.ActiveXObject) { isIE = true; return new ActiveXObject("Microsoft.XMLHTTP"); } } function doCompletion() { if (completeField.value == "") { clearTable(); } else { var url = "autocomplete?action=complete&id=" + escape(completeField.value); var req = initRequest(url); req.onreadystatechange = function() { if (req.readyState == 4) { if (req.status == 200) { parseMessages(req.responseXML); } else if (req.status == 204){ clearTable(); } } }; req.open("GET", url, true); req.send(null); } }

XMLHttpRequest 오브젝트는 현재 표준 JavaScript에 포함되지는 않지만(표준화를 위한 노력이 진행중임), 사실상의 표준이자 AJAX의 핵심이라 할 수 있다. 이 오브젝트는 HTTP를 통해 서버측 컴포넌트(이 경우에는 서블릿)와 상호 작용하는 부분을 담당한다.

XMLHttpRequest 오브젝트 생성 시 URL, HTTP 메소드(GET 또는 POST), 그리고 상호작용의 비동기 여부 등 세 가지 매개변수가 지정된다. XMLHttpRequest 예제에서 매개변수는 다음과 같다.

  • URL autocomplete 및 전체 필드(complete-field)의 텍스트(M 문자):
    var url = "autocomplete?action=complete&id=" + escape(completeField.value);
  • GET(HTTP 인터랙션이 GET 메소드를 사용함을 의미) 및 true(인터랙션이 비동기적임을 의미):
    req.open("GET", url, true);

비동기 호출을 이용할 때는 callback 함수를 설정해야 하는데, XMLHttpRequestreadyState 속성이 변경될 경우 이 callback 함수는 HTTP 인터랙션 과정의 특정 포인트에서 비동기적으로 호출된다. 예제에서 callback 함수는 processRequest()이며, 함수에 대해 XMLHttpRequest.onreadystatechange 속성으로 설정된다. readState가 "4"’일 경우 parseMessages 함수에 대한 호출에 주목할 것. "4"의 XMLHttpRequest.readyState는 HTTP 인터랙션이 성공적으로 완수되었음을 나타낸다.

XMLHttpRequest.send()가 호출되면 HTTP 인터랙션이 시작되고, 인터랙션이 비동기적이면 브라우저는 계속해서 페이지의 이벤트를 처리한다.

서버 상에서

XMLHttpRequest는 URL 자동 완성에 대해 HTTP GET을 요청하고, autocomplete라 불리는 서블릿으로의 매핑이 수행된다. 그리고, AutoComplete 서블릿의 doGet() 메소드가 호출된다. 다음은 doGet() 메소드의 형태이다.

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { ... String targetId = request.getParameter("id"); Iterator it = employees.keySet().iterator(); while (it.hasNext()) { EmployeeBean e = (EmployeeBean)employees.get( (String)it.next()); if ((e.getFirstName().toLowerCase().startsWith(targetId) || e.getLastName().toLowerCase().startsWith(targetId)) && !targetId.equals("")) { sb.append("<employee>"); sb.append("<id>" + e.getId() + "</id>"); sb.append("<firstName>" + e.getFirstName() + "</firstName>"); sb.append("<lastName>" + e.getLastName() + "</lastName>"); sb.append("</employee>"); namesAdded = true; } } if (namesAdded) { response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); response.getWriter().write("<employees>" + sb.toString() + "</employees>"); } else { response.setStatus(HttpServletResponse.SC_NO_CONTENT); } }

이 서블릿을 보면 알 수 있듯이, AJAX 처리를 위해 서버측 코드 작성 방법을 배우는 데 필요한 새로운 내용은 전혀 나와있지 않다. XML 문서를 교환하고자 할 경우에 대비해서 응답 컨텐트 유형을 text/xml로 설정해야 하는데, AJAX의 경우에는 평문(plain text) 또는 심지어 클라이언트 상의 callback 함수에 의해 평가되거나 실행될 수 있는 JavaScript의 단편도 교환이 가능하다. 일부 브라우저는 결과를 캐시할 수 있으므로 Cache-Control HTTP 헤더를 no-cache로 설정할 필요가 있을 수 있다는 점에도 역시 유의할 것. 이 예제에서 서블릿은 이름이나 성이 문자 M으로 시작되는 모든 종업원을 포함하는 XML 문서를 생성한다. 다음은 호출을 한 XMLHttpRequest 오브젝트로 반환되는 XML 문서의 예제이다.

<employees> <employee> <id>3</id> <firstName>George</firstName> <lastName>Murphy</lastName> </employee> <employee> <id>2</id> <firstName>Greg</firstName> <lastName>Murphy</lastName> </employee> <employee> <id>11</id><firstName>Cindy</firstName> <lastName>Murphy</lastName> </employee> <employee> <id>4</id> <firstName>George</firstName> <lastName>Murray</lastName> </employee> <employee> <id>1</id> <firstName>Greg</firstName> <lastName>Murray</lastName> </employee> </employees>

다시 클라이언트로

처음 호출을 한 XMLHttpRequest 오브젝트가 응답을 받을 경우, parseMessages() 함수가 호출된다(자세한 내용은 이 예제의 앞 부분에 있는 XMLHttpRequest의 초기화를 참조). 다음은 parseMessages() 함수의 모습이다.

function parseMessages(responseXML) { clearTable(); var employees = responseXML.getElementsByTagName( "employees")[0]; if (employees.childNodes.length > 0) { completeTable.setAttribute("bordercolor", "black"); completeTable.setAttribute("border", "1"); } else { clearTable(); } for (loop = 0; loop < employees.childNodes.length; loop++) { var employee = employees.childNodes[loop]; var firstName = employee.getElementsByTagName( "firstName")[0]; var lastName = employee.getElementsByTagName( "lastName")[0]; var employeeId = employee.getElementsByTagName( "id")[0]; appendEmployee( firstName.childNodes[0].nodeValue, lastName.childNodes[0].nodeValue, employeeId.childNodes[0].nodeValue); } }

parseMessages() 함수는 AutoComplete 서블릿이 반환한 XML 문서의 오브젝트 표현을 매개변수로 수신하는데, 이 함수는 XML 문서를 프로그램적으로 traverse한 다음 결과를 이용하여 HTML 페이지의 컨텐츠를 업데이트한다. 이 작업은 XML 문서 내의 이름에 대한 HTML 소스를 ID가 "menu-popup"’인 <div> 엘리먼트로 inject함으로써 수행된다.

<div style="position: absolute; top:170px;left:140px" id="menu-popup">

사용자가 문자를 더 많이 입력할수록 목록 길이는 줄어들게 되고, 이어서 사용자는 여러 이름 중 하나를 클릭할 수 있다.

이제 여러분은 AJAX가 단순히 페이지의 백그라운드에서 HTTP를 통해 정보를 교환하고 결과를 토대로 해당 페이지를 동적으로 업데이트한다는 것을 알게 되었을 것이다. AJAX와 자바 기술에 관한 자세한 내용은 테크니컬 아티클 Asynchronous JavaScript Technology and XML (AJAX) With Java 2 Platform, Enterprise Edition(영문)을 참조하기 바란다. 아울러 AJAX BluePrints 페이지(영문)와 Greg Murray의 블로그에 실려 있는 AJAX FAQ for the Java Developer(영문)의 내용도 함께 참조할 것.

예제 코드 실행하기

본 팁에는 본문에서 다루어진 기법을 예시하는 예제 패키지가 첨부되어 있는데, Servlet 2.4 이상의 API를 지원하는 웹 컨테이너라면 모두 예제 패키지 설치가 가능하다. 예제를 설치하고 실행하려면 다음 단계를 따르도록 한다.

  1. 먼저 GlassFish Project 페이지(영문)에서 GlassFish를 다운로드해야 하는데, GlassFish는 Servlet 2.5와 JSTL(JSP Standard Tag Library)을 곧바로 지원한다. 만약 J2EE 1.4 또는 Servlet 2.4 컨테이너를 사용하고 있다면 JSTL JAR 파일을 web/WEB-INF/lib 디렉터리에 포함시켜야 할 수도 있다.
  2. 다음의 환경 변수를 설정한다.
    • GLASSFISH_HOME. This should point to where you installed GlassFish (for example C:\Sun\AppServer) GLASSFISH_HOME. GlassFish 설치 장소를 가리켜야 한다(가령 C:\Sun\AppServer).
    • ANT_HOME. ant 설치 장소를 가리켜야 한다. ant는 다운로드한 GlassFish 번들에 포함되어 있다. (Windows의 경우에는 lib\ant 서브디렉터리 내에 위치함.)
    • JAVA_HOME. 시스템에서의 JDK 5.0 위치를 가리켜야 한다.

    아울러, ant 위치를 PATH 환경 변수에 추가한다.

  3. 예제 파일을 다운로드하여 압축을 해제한다. 이제 새로 추출된 디렉터리가 <install_dir>\ajax-autocomplete로 표시되어야 하는데, 예를 들어 Windows 컴퓨터의 C:\에 압축을 풀었다면 새로 생성된 디렉터리는 C:\ajax-autocomplete가 되어야 한다

  4. ajax-autocomplete 디렉터리로 이동해서 build.properties 파일에 build.properties.sample을 복사한다.

  5. build.properties 파일을 열고 Servlet 2.4 이상의 API를 포함하는 JAR 파일에 servlet.jar 속성을 설정한다. GlassFish의 경우 JAR 파일은 <gf_install_dir>/glassfish/lib/javaee.jar인데, 여기서 <gf_install_dir>은 GlassFish가 설치된 곳이다. javaee.autodeploy를 웹 컨테이너가 애플리케이션을 자동 설치할 디렉터리로 설정한다. GlassFish의 경우 이 디렉터리는 <gf_install_dir>/glassfish/domains/domain1/autodeploy이다.

  6. 6. 다음 명령어를 입력하여 GlassFish를 시작한다. <GF_install_dir>\bin\asadmin start-domain domain1 이 때, <GFinstall_dir>은 Glassfish가 설치된 디렉터리이다.

  7. ant 툴을 이용하여 애플리케이션을 구축하고 설치한다. Glassfish는 /glassfish/bin/asant 디렉터리에 ant의 사본을 가지고 있고, 또한 Apache Ant Project 페이지(영문)에서 ant를 다운로드할 수도 있다.

    애플리케이션을 구축하려면 다음 명령어를 입력한다. ant 애플리케이션을 설치하려면 다음 명령어를 입력한다. ant deploy
  8. 브라우저를 다음의 URL로 연다: http://localhost:8080/ajax-autocomplete/.

    NetBeans 4.1 이상을 사용하고 있다면 예제가 포함되어 있을 것이고, Help -> BluePrints Solutions Catalog를 선택하여 툴에서 이를 실행할 수 있다. 여기서 AJAX -> Autocomplete 예제를 선택하면 된다. 이제 NetBeans 내에서 예제를 실행할 수 있으며 원할 경우 수정도 가능하다.

    예제를 실행하면 다음과 같은 모습이 된다.
    example autocomplete

    목록의 이름을 클릭하면 종업원에 관한 정보가 표시된다.
    example autocomplete - Employee Info

필자 소개

서블릿 스펙 분야를 주도하고 있는 Greg Murray는 Java BluePrints 팀의 전 멤버로, 웹 티어 권고(recommendations) 부문을 담당한 바 있으며, 현재 그는 BluePrints 팀의 도움을 받아 썬의 AJAX 프로젝트를 이끌고 있습니다. 또한 Greg은 국제화, 웹 서비스, J2SE 독립형 클라이언트, AJAX 기반 웹 클라이언트 등의 분야에서 다양한 경력을 쌓기도 했습니다.

반응형

'JAVA' 카테고리의 다른 글

Tomcat 5.5.9 Admin  (0) 2007.03.12
이클립스 사용법 1  (0) 2007.03.12
JCO 주최 제 8회 한국 자바 개발자 컨퍼런스 참관 후기  (0) 2007.03.11
Posted by Real_G