메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

Ajax와 자바

한빛미디어

|

2006-01-12

|

by HANBIT

19,473

저자: 이창신

Ajax가 클라이언트 진영에 있어 크로스 브라우저 기술의 선두에 우뚝 서 있다면, 자바는 서버 진영에 있어 크로스 플랫폼 기술의 대표 주자라 할 수 있습니다. 특히, JavaScript와 자바 사이를 XML이라는 크로스 플랫폼 메시지 형식으로 잇는다는 점은 JavaScript, XML, 자바가 얼마나 클라이언트·서버 프로그래밍에 있어 잘 어울릴 수 있는지를 가늠케 합니다.


이 글은 주로 클라이언트를 작성하는 데에 초점이 맞추어져 있고, 따라서 서버측 프로그램은 PHP와 Perl이라는 상대적으로 Java EE(Enterprise Edition)보다는 쉬운 기술로 설명하고 있습니다만 현재 많은 웹 시스템이 Java EE로 이루어져 있으며, 앞으로도 엔터프라이즈 웹 시스템에 있어 Java EE는 SOA(Service Oriented Architecture)와 함께 계속 뻗어 나아가리라 전망하므로, 앞서 3장에서 본 기본 예제들의 서버측을 자바로 해보며 그 가능성을 음미하는 기회를 가져보려 합니다.

Java EE 개발 환경을 준비하기 앞서, 먼저 그 기반이 되는 Java SE 개발 환경이 필요합니다. 보통 JDK(Java Development Kit)이라고 부르는데, 현재 1.5가 최신 버전으로 이것을 받아 설치합니다.

URL - JDK 1.5 내려 받기
http://java.sun.com/j2se/1.5.0/download.jsp

글래스피쉬

글래스피쉬(GlassFish, 이하 GF)는 자바를 만든 썬(Sun Microsystems)이 내놓고 있는 Java EE 5 기술을 구현한 오픈 소스 서버입니다.

URL - GF 내려 받기
https://glassfish.dev.java.net/public/downloadsindex.html

위의 URL을 열어보면, Promoted binary builds란이 있고, 거기서 최신의 것을 받으면 좋습니다. 2005년 12월 23일 현재 b32가 가장 새 것이어서, 그것을 기준으로 설명하겠습니다. 해당 링크를 누르면 설치 안내와 더불어 각 플랫폼 별로 jar 파일의 링크들이 있습니다. 이 책에서는 윈도우를 기준으로 하려 합니다. GF 바이너리를 받은 후, 도스창에서 받은 파일이 있는 디렉토리로 가서 다음과 같이 실행합니다.

java -Xmx256m -jar filename.jar

그러고 나면, 현재 디렉토리 밑으로 glassfish라는 디렉토리가 생깁니다.

GF의 설치를 마칠려면 Ant라는 툴이 필요합니다.

URL - 아파치 Ant 내려 받기
http://ant.apache.org/bindownload.cgi

적당한 곳에 받은 압축 파일을 푼 후, 그 디렉토리를 ANT_HOME이라는 환경 변수로 잡아주고, 실행 경로 PATH에 추가해 줍니다.

set ANT_HOME=c:\apache-ant-1.6.5
set PATH=%ANT_HOME%\bin;%PATH%

위의 예는 Ant의 홈 디렉토리가  c:\apache-ant-1.6.5인 경우입니다. 아마 c:\에 압축을 풀면 그렇게 될 것입니다. ANT_HOME과 더불어 JAVA_HOME도 잡아줍니다.

set JAVA_HOME="c:\program files\jdk1.5.0_06"

위의 예는 JDK의 홈 디렉토리가 c:\program files\jdk1.5.0_06인 경우입니다. 아마도 설치 디렉토리 설정 없이 설치하면 그렇게 될 것입니다. 공백이 들어있는 디렉토리를 환경 변수로 잡는 경우 겹따옴표로 앞뒤를 막아 주는 것이 포인트입니다.

이와 같이 환경을 갖춘 다음, 실행하면, GF의 설치가 마무리됩니다.

ant -f setup.xml

GF를 설치할 때에는 8080 포트를 쓰는 다른 웹 서버가 떠 있으면 안됩니다. 다른 프로그램이 실행되지 않는 상태에서 설치하는 것이 안전하겠습니다.

GF가 설치된 디렉토리도 환경 변수로 잡아줍니다.

set GLASSFISH_HOME=c:\glassfish


%GLASSFISH_HOME%\bin으로 가서 다음을 실행하여 GF를 띄우도록 합시다.

asadmin start-domain domain1

기본적인 연동

클라이언트측 JavaScript -> sample.htm





        



    value   = "Java EE로 "가나다라"를 송신하여, 즉시 수신합니다"
    onclick = "sendRequest(on_loaded1,"&data=가나다라","POST","./echo",true,true)">


서버측 서블릿 -> EchoServlet.java

package ajax;

import java.net.URLEncoder;
import java.io.PrintWriter;
import java.io.IOException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class EchoServlet extends HttpServlet {
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
    request.setCharacterEncoding("UTF-8");
    String data = request.getParameter("data");
    data = URLEncoder.encode(data, "UTF-8");
    response.setCharacterEncoding("UTF-8");
    PrintWriter out = response.getWriter();
    out.print(data);
  }
}

이 서블릿 또한 기본적으로는 03-02-01의 echo.php와 같지만, HTML 엔티티 처리는 Java EE 표준 라이브러리에 해당 기능이 없어 생략했습니다(필요하다면 얼마든지 문자열 치환으로 구현 가능합니다). 그리고 결과는 간단하게 받은 데이터를 그대로 내보냅니다.

이 예제는 웹 애플리케이션 아카이브(WAR)로 GF에 배치한 후 실행 가능하도록 되어 있습니다. 예제 프로젝트 디렉토리(ajax-java)를 로컬 하드 디스크 드라이브에 복사한 다음, 도스창에서 복사된 ajax-java 디렉토리로 가서 다음을 실행하면

ant

예제 서버측 코드의 컴파일과 빌드, 배치가 이루어집니다. 성공적으로 위의 명령이 끝나면, 웹 브라우저로 http://localhost:8080/ajax-java/sample.htm을 열어 결과를 확인할 수 있습니다.

암호를 요구하며 배치가 안 되는 경우에는, 도스창에서 GF 홈 디렉토리 밑의 bin 디렉토리로 이동하여 다음과 같이 실행해줍니다.

asadmin change-master-password --savemasterpassword=true

DB 연동

Java EE에서 DB 처리는 EJB의 엔티티 빈(Entity Bean)을 씁니다만, Java EE 5 이전까지는 그 작성이 상당히 까다롭고 복잡했습니다. Java EE 5에 포함된 EJB 3은 그러한 문제를 해결하여, 매우 손쉽게 DB 연결과 쿼리 실행이 가능합니다.

먼저, 필요한 DB 서버를 기동합니다. GF에는 Derby라는 DB 서버가 포함되어 있습니다.

set DERBY_INSTALL=%GLASSFISH_HOME%\derby

위와 같이 Derby 홈 디렉토리를 잡아 준 후, 다음과 같이 실행하면 Derby 서버가 뜹니다.

%DERBY_INSTALL%\frameworks\NetworkServer\bin\startNetworkServer.bat

EJB 3가 제공하는 Java Persistence API(이하 JPA)를 이용하면 DB 테이블 생성 작업도 필요하지 않습니다. 그야말로 DB를 직접 건드릴 일이 전혀 없는 셈이죠. 오직 DB에 대해 해야 할 일은 DB를 기동하는 것뿐입니다.

클라이언트측 JavaScript -> sample.htm









            value   = "MySQL로부터、시도 코드로 시도 이름을 취득"
         onclick = "sendRequest(on_loaded1,"&code=01","GET","./db",true,true)">


달라진 점은 요청 URL(./db)뿐입니다.

서버측 엔티티(Entity) -> Sido.java

package ajax.entity;

import javax.persistence.*;

@Entity(access=AccessType.FIELD)
public class Sido implements java.io.Serializable {

    @Id
    private String code;

    private String name;

    protected Sido() {
    }

    public Sido(String code, String name) {
        this.code = code;
        this.name = name;
    }
    
    public String getName() {
      return name;
    }
}

아주 단순하지만, 이것이 DB의 데이터를 모델링한 자바 클래스입니다. @Entity나 @Id와 같은 어노테이션(annotation)과 함께 이 클래스는 해당 DB 테이블과 대응됩니다.

서버측 서블릿 -> DbServlet.java

package ajax.web;

import ajax.entity.Sido;

import java.net.URLEncoder;
import java.io.PrintWriter;
import java.io.IOException;

import javax.annotation.Resource;
import javax.persistence.PersistenceContext;
import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.UserTransaction;

public class DbServlet extends HttpServlet {

    @Resource
    private UserTransaction utx;
    
    @PersistenceContext
    private EntityManager em;

    public void service(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        String code = request.getParameter("code");
        Sido uc = em.find(Sido.class, code);
        String name = uc.getName();
        name = URLEncoder.encode(name, "UTF-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        out.print(name);
    }

    public void init() throws ServletException {
        try {
            utx.begin();
            em.persist(new Sido("01", "서울시"));
            em.persist(new Sido("02", "경기도"));
            em.persist(new Sido("03", "강원도"));
            em.persist(new Sido("04", "인천시"));
            em.persist(new Sido("05", "제주도"));
            utx.commit();
        } catch (Exception e) {
            throw new ServletException(e);
        }
    }
    
}

이 서블릿은 init() 메소드에서 DB 테이블을 초기화하고 있습니다. 이렇게 자료가 준비된 후 요청을 받으면 SQL 쿼리 문장을 작성할 필요 없이 매우 직관적으로 JPA의 EntityManager에게 code라는 프라이머리 키(Primary key)에 맞는 Sido 오브젝트를 DB로부터 검색해 가져오도록 합니다.

이 예제는 웹 애플리케이션 아카이브(WAR)로 GF에 배치한 후 실행 가능하도록 되어 있습니다. 예제 프로젝트 디렉토리(ajax-java-db)를 로컬 하드 디스크 드라이브에 복사한 다음, 도스창에서 복사된 ajax-java-db 디렉토리로 이동한 후 다음을 실행하면

ant

예제 서버측 코드의 컴파일과 빌드, 배치가 이루어집니다. 성공적으로 위의 명령이 끝나면, 웹 브라우저로 http://localhost:8080/ajax-java-db/sample.htm을 열어 결과를 확인할 수 있습니다.

끝으로, Java EE 5에 대한 자세한 사항은 GF의 공식 사이트를 참고하기 바랍니다.

URL GF 공식 사이트
https://glassfish.dev.java.net

JSF 응용

JSF(JavaServer Faces)는 서블릿-JSP-JSTL(JSP Standard Tag Library)의 계보로 이어지는 자바 웹 애플리케이션의 차세대 원동력인 웹 GUI 프레임웍입니다. JSP 2.0과 JSTL로 자바 코드 없는 JSP 페이지 작성의 물꼬가 트이면서, 많은 사람들은 더 나아가 웹 페이지를 마치 일반 GUI 애플리케이션 제작과 같이 컴포넌트 기반으로 하고 싶어 하기 시작했고, 그에 부응하기 위해 JSF라는 표준 기술이 출범하였습니다.

이러한 JSF의 취지에 비춰봤을 때, Ajax와 JSF는 그야말로 천생연분입니다. 그래서, Java EE에서는 JSF를 통한 Ajax 지원에 많은 관심을 기울여 오고 있습니다.

URL - Ajax BluePrints
http://java.sun.com/blueprints/ajax.html

간단히 말해, JSF의 컴포넌트들이 Ajax 기술을 응용, 개발자가 JavaScript를 짤 필요 없이 Ajax의 혜택을 누리게 해준다는 것입니다. 구체적으로, GF 위에서 운영 가능한 Ajax JSF 컴포넌트들을 예제와 함께 볼 수 있으므로 위의 URL을 참고하시기 바랍니다.
TAG :
댓글 입력
자료실