Enterprise Java Technologies Tech Tip에 오신 여러분을 환영합니다
Enterprise Java Technologies
테크팁
2006년 4월 5일자
 

4월의 Technology Day!
Powering the Participation Age
참여의 시대 : 개발자와 함께 성장하는 썬마이크로시스템즈
  • 일시: 2006년 4월 19일(수) 10:30- 13:00
  • 장소: 코엑스 4층 그랜드 컨퍼런스룸
  • 대상: 자바 & 솔라리스 개발자 및 유저
  • 주제: IT 트렌드 및 썬의 전략
               Java & Solaris 로드맵
               오픈소스 지원 정책(Java, OpenSolaris 등)
  • 특혜: 사전 등록자 점심 제공
  • 자세한 내용 및 참가 신청 »
  • 문의 : SKDN@Sun.COM
   
  이번 호에서는,

» JSF에서 비 HTML 마크업으로 AJAX 사용하기
» 자바 클라이언트 또는 Java Web Start 기술을 통해 시큐어 엔터프라이즈 빈에 액세스하기

에 대해 다룹니다.

이 팁들은 Java EE 5의 오픈소스 구현(GlassFish)을 이용하여 개발되었으며, GlassFish 프로젝트 페이지에서 GlassFish를 다운로드 받으실 수 있습니다.

-샘플 아카이브 다운로드 받기-
JSF에서 비 HTML 마크업으로 AJAX 사용하기
Java Web Start
Standalone client

JSF에서 비 HTML 마크업으로 AJAX 사용하기
 

저자 Roger Kitain

JSF(JavaServer Faces) 기술은 Java EE 및 J2EE 애플리케이션을 위한 사용자 인터페이스의 구축을 간소화시켜주는 프레임워크로서, 2004년 3월 24일자 테크 팁, JavaServer Faces 기술 소개(영문)에서 이 기술을 간략하게 개관한 바 있다. 아울러, JSF 프레임워크에 의해 모델링되는 GUI 컴포넌트가 포함된 JSF 애플리케이션을 제작하는 방법에 대해서도 알아보았다. 이후 2004년 12월 25일자 팁에서 JavaServer Faces 기술과 사용자 정의 컴포넌트에 대해 다루었는데, 이 팁들이 출판된 이후에 JSF 기술은 1.2 레벨로 업그레이드되었다. 이 JSF 1.2에는 단일의 JSF 애플리케이션에서 복수의 렌더 키트를 지원하는 기능이 새로 포함되었다. 또한, JSF에서는 렌더 키트를 이용하여 HTML 같은 마크업으로 된 사용자 인터페이스를 제시한다. 한편, JSF의 경우 HTML 렌더 키트가 포함되어 있기는 하지만, SVG(Scalable Vector Graphics)나 XUL(XML User Interface Language) 같은 다른 마크업 언어로 된 사용자 인터페이스 컴포넌트를 디스플레이하기 위해 렌더 키트를 직접 작성할 수도 있다.

각 마크업 언어가 제공하는 강점들을 하나의 JSF 애플리케이션에 결합하여 활용하는 것도 가능한데, 예를 들어 SVG를 이용하여 애플리케이션을 위한 정교한 그래픽과 애니메이션을 제작할 수 있다. 하지만 SVG는 버튼이나 그 밖의 컴포넌트가 포함된 위젯 세트(widget set)를 가지고 있지 않으므로 사용자는 마크업을 이용하여 위젯을 생성해야 한다. 이와 대조적으로 XUL은 사용하기 쉬운 완벽한 사용자 인터페이스 컨트롤 세트를 가지고 있으나, SVG이 제공하는 그래픽 기능은 빠져 있다. 이 두 마크업에 있어서 공통된 점은 HTML에서 제공되는 것과 같은 빌트인(built-in) 폼 제출 메커니즘이 없다는 것이다. 하지만 AJAX(Asynchronous JavaScript and XML)를 일부 JSF 1.2 기능과 함께 사용하면 비 HTML 마크업으로 폼 제출을 효과적으로 구현할 수 있다. 본 팁에서는 JSF 애플리케이션에서 AJAX와 세 가지 렌더 키트(HTML, SVG, XUL)를 사용하는 방법(데모 포함)에 대해 알아보도록 한다. (AJAX에 관한 자세한 내용은 2005년 12월 27일자 테크 팁, 자바 기술을 이용한 AJAX 활용하기 를 참조할 것.)

JSF 라이프 사이클 예제

JSF 애플리케이션과의 사용자 상호작용은 'JSF 라이프 사이클'이라고 하는 일련의 단계를 거쳐 처리되며, 일반적으로 라이프 사이클은 각 박스가 프로세스의 한 단계를 나타내는 일련의 연결된 박스로 예시된다. 화살표가 있는 선은 특정 단계에서 다음 단계로의 흐름을 나타낸다. 본 팁에는 JSF 라이프 사이클을 애니메이션으로 디스플레이하는 예제 JSF 애플리케이션이 포함되어 있지 않으며, 앞서 언급한 것처럼 애플리케이션에는 HTML, SVG, XUL 등의 렌더 키트가 사용되었다.

아래 도표는 서로 다른 마크업 페이지들 사이를 이동하는 데모의 흐름을 보여준다.

애플리케이션은 데모를 비롯하여 관련 배경과 디자인 세부사항을 보여주는 HTML 페이지의 디스플레이로 시작된다.

이 페이지는 표준 HTML 렌더 키트로 제작되었는데, 페이지 하단의 Next 버튼을 클릭하면 SVG 렌더 키트로 렌더링된 SVG 페이지가 디스플레이된다. SVG 페이지는 JSF 라이프 사이클을 그래픽으로 예시한다.

라이프 사이클 단계(가령 Retore View Phase)를 나타내는 임의의 상자를 클릭하면 AJAX에 의해 폼 제출이 생성되고, 이어서 JSF 라이프 사이클 단계에 관한 자세한 내용을 보여주는 XUL 페이지가 표시된다.

JSF 라이프 사이클 예시의 아래쪽에는 Initial Request, Validation Error 등의 라벨이 붙은 다양한 버튼이 포함된 더 큰 박스가 있다. 이 버튼을 클릭하면 라이프 사이클 단계들을 통과하는 특정 프로세스 흐름(가령, 초기 요청을 처리하는 프로세스 흐름)이 애니메이션으로 디스플레이된다.

데모를 위한 코드 몇 가지를 살펴보기로 하자.

클라이언트에서 포스팅하기

먼저 SVG 페이지를 살펴보자. 다음은 JSF 태그로 작성한 SVG 페이지의 단편이다.

   <%@ page contentType="image/svg+xml"%>
   <%@ taglib uri="http://java.sun.com/jsf/svg" prefix="g" %>
   <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
   ...
      <f:view renderKitId="SVG" >
         <g:form id="form">
   ...
            <g:commandButton id="restore" width="120" 
                   height="50" x="100" y="100" type="submit"
                   action="xul-restore"
                   style="stroke:black; fill:#8470ff;" >
                 <g:outputText x="130" y="120"
                    textAnchor="middle" value="Restore" />
                 <g:outputText x="135" y="140"
                    textAnchor="middle" value="View" />
            </g:commandButton>
   ...
         </g:form>
      </f:view>

페이지의 컨텐츠 타입을 나타내는 페이지 지시어, 그리고

   <%@ page contentType="image/svg+xml"%>

SVG가 페이지의 렌더링 기술임을 나타내는 다음 태그에 유의할 것.

   <f:view renderKitId="SVG" >

커스텀 렌더 키트 생성하고 사용하기(영문) 문서에서는 SVG 등의 렌더 키트를 사용하는 페이지에 표시되어야 할 지시어, 태그, 속성 등에 관한 자세한 설명이 포함되어 있다.

SVG 페이지의 정보에 대응하여, 서버 상의 SVG 렌더 키트는 다음과 같은 SVG 마크업을 생성한다.

   <svg xmlns="http://www.w3.org/2000/svg"
        xmlns:xlink="http://www.w3.org/1999/xlink">
   ...
     <script xlink:href="/jsf-renderkits/src/script/http-svg.es">
     </script>
     <script xlink:href="/jsf-renderkits/src/script/lifecycle.es">
     </script>
     <g id="form" method="post" 
         action="/jsf-renderkits/render/svg.jsp">
   ...
       <g id="form:restore" onclick="form_post(evt)">
         <rect width="120" height="50" x="100" y="100" 
            style="stroke:black; fill:#8470ff;"></rect>
         <text x="100" y="150" text-anchor="middle"></text>
         <text x="130" y="120">Restore</text>
         <text x="135" y="140">View</text>
       </g>
   ...
       <text name="javax.faces.ViewState" 
       id="javax.faces.ViewState" value="_id4:_id6" 
          visibility="hidden">_id4:_id6</text>
       <text name="javax.faces.RenderKitId" 
          id="javax.faces.RenderKitId" value="SVG" 
          visibility="hidden">SVG</text>
     </g>
   <script><![CDATA[
   function form_post(evt) {
     var control = evt.target;
     var form = getForm(control);
     var postData = getPostData(form, control);
     var url = "/jsf-renderkits/render/svg.jsp";
     sendRequest(url, postData);
   }
   //]]>
   </script>
   </svg>

이 코드는 SVG 렌더 키트의 다양한 렌더러에 의해 생성된다. FormRendererencodeBegin() 메소드는 다음과 같은 ECMAScript 파일 레퍼런스, 그리고

   <script xlink:href="/jsf-renderkits/src/script/http-svg.es">
   </script>
   <script xlink:href="/jsf-renderkits/src/script/lifecycle.es">
   </script>

시작 '폼' 그룹을 생성한다.

  <g id="form" method="post" 
      action="/jsf-renderkits/render/svg.jsp">

이 SVG <g> 엘리먼트를 '폼' 엘리먼트로 취급하기 위해서 시작 '폼' 그룹의 action 속성이 사용된다. 한편, SVG에는 <g> 엘리먼트가 널리 사용된다.

ButtonRendererTextRenderer 인코딩 메소드는 버튼 컨트롤의 시작 및 종료 그룹 엘리먼트, 그리고 관련 치수 및 라벨을 생성한다.

   <g id="form:restore" onclick="form_post(evt)">
     <rect width="120" height="50" x="100" y="100" 
        style="stroke:black; fill:#8470ff;"></rect>
     <text x="100" y="150" text-anchor="middle"></text>
     <text x="130" y="120">Restore</text>
     <text x="135" y="140">View</text>
   </g>

onclick 메소드 이름 form_post가 버튼 컨트롤의 상위 폼 컴포넌트에서 결정된다는 점에 유의할 것.

   public void encodeBegin(FacesContext context, 
     UIComponent component)
          throws IOException {
   ...
       UIComponent root = context.getViewRoot();
       UIComponent myForm = component;
       while (!(myForm instanceof UIForm) && root != myForm) {
           myForm = myForm.getParent();
       }
       String formMethodName = myForm.getClientId(context) + 
           "_post(evt)";
       writer.writeAttribute(
           "onclick", formMethodName, "onclick");      

FormRenderer.encodeEnd() 메소드는 페이지 상태와 폼 컨트롤의 종료 그룹 엘리먼트를 작성한다.

   <text name="javax.faces.ViewState" 
   id="javax.faces.ViewState" value="_id4:_id6" 
      visibility="hidden">_id4:_id6</text>
    <text name="javax.faces.RenderKitId" 
        id="javax.faces.RenderKitId" value="SVG" 
        visibility="hidden">SVG</text>
  </g>

아울러, 포스트 데이터를 수집하고 요청을 전송하는 JavaScript 함수가 생성된다.

   <script><![CDATA[
   function form_post(evt) {
     var control = evt.target;
     var form = getForm(control);
     var postData = getPostData(form, control);
     var url = "/jsf-renderkits/render/svg.jsp";
     sendRequest(url, postData);
   }
   //]]>
   </script>

요청이 JSF 컨트롤러로 전달되도록 매핑이 이루어진다.

getForm, getPostData, sendRequest 등의 함수는 모두 http-svg.es ECMAScript 파일에서 정의된다. (http-svg.es 파일은 예제 JSF 애플리케이션의 renderkits\src\script 디렉토리에 들어 있음.) 예를 들어, 다음은 getPostData 함수에 대한 정의의 일부이다.

   function getPostData(form, control) {
       
       var formValues = new Array();
       formValues[0] = new Object();
       formValues[0].id = control.parentNode.id;
       formValues[0].value = control.parentNode.id;
       formValues[1] = new Object();
       formValues[1].id = form.id;
       formValues[1].value = form.id;
   
   ...
       
       var postData = "";
       for (var i=0; i<formValues.length; i++) {
           if (formValues[i].id == "javax.faces.ViewState") {
               var re = new RegExp("\\+", "g");
               var val = formValues[i].value;
               formValues[i].value = val.replace(re, "\%2B");
           }
           postData += formValues[i].id + "=" + 
               formValues[i].value;
           if (i != formValues.length-1) {
               postData += "&";
           }
       }
       return postData;
   }

getPostData는 숨겨진 필드 javax.faces.ViewState를 전송한다는 점에 유의할 것. JSF는 이런 식으로 요청이 포스트 백이라는 것을 판단한다.

요청 처리하기

요청이 JSF에 전송될 때는 통상적인 JSF 라이프 사이클 처리 단계를 거치게 된다. 그러나 애플리케이션 호출 단계 후에(즉, 응답 단계를 렌더링하기 직전에) 실행되도록 등록된 특별한 JSF 단계 리스너가 있다. 요청이 AJAX 요청인 경우(요청 헤더에서 XML-HTTP 문자열에 의해 지시됨), 이 단계 리스너는 다음에 렌더링되는 뷰의 뷰 식별자를 얻게 되고, 이어서 단계 리스너는 뷰 식별자를 응답 헤더에 포함시킨다.

   public class ResponsePhaseListener implements PhaseListener {

      private static final String XML_HTTP = "XML-HTTP";
       private static final String VIEW_URI = "VIEW-URI";
   ...
       public void afterPhase(PhaseEvent event) {
           // Disregard requests that are not XMLHttpRequest(s)
           Map<String, String> requestHeaderMap =
                 event.getFacesContext().getExternalContext().
                       getRequestHeaderMap();
           if (requestHeaderMap.get(XML_HTTP) == null) {
               return;
           }
           // If we're dealing with an XMLHttpRequest...
           // Get the URI and stuff it in the response header.
           FacesContext context = event.getFacesContext();
           String viewId = context.getViewRoot().getViewId();
           String actionURL = 
               context.getApplication().getViewHandler()
                 .getActionURL(context, viewId);
           HttpServletResponse response = (HttpServletResponse) 
               context.getExternalContext().getResponse();
           response.setHeader("Cache-Control", "no-cache");
           response.setHeader(VIEW_URI, actionURL);
       }
   ...
   }

processResponse 메소드는 응답 헤더로부터 뷰 식별자를 얻고, 이어서 클라이언트는 해당 위치를 로드한다. processResponse 메소드는 http-svg.es ECMAScript 파일에서 정의된다.

   function processResponse() {
       var request = getXMLHttpRequest();
       if (request.readyState == 4) {
           if (request.status == 200) {
               var action = 
                   request.getResponseHeader("VIEW-URI");
               window.location.href = action;
               return;
           }
      }
   }

JSF에서의 렌더 키트 사용법에 관한 자세한 내용을 보려면 커스텀 렌더 키트 생성하고 사용하기 기술문서를 참조할 것.

예제 코드 실행하기

예제 패지키에는 팁에서 다룬 기법을 예시하는 본 팁이 포함되어 있으며, 사용자는 Servlet 2.5 API, JSP(JavaServer Pages) Technology 2.1 및 JSF 1.2를 지원하는 어떠한 웹 컨테이너에라도 예제 패키지를 설치할 수 있다. 아울러 JDK 5도 필요하고, 클라이언트(브라우저)의 경우에는 Firefox 1.5처럼 빌트인 SVG를 지원하는 Mozilla 브라우저를 사용해야 한다.

예제를 설치하고 실행하려면 다음의 작업 절차를 따르도록 한다.

  1. GlassFish가 설치되어있지 않다면 GlassFish 커뮤니티 다운로드 페이지에서 다운로드한다. GlassFish는 Servlet 2.5와 JSP 2.1을 'out of the box' 방식으로 지원한다.

  2. 해당 팁의 예제 패키지를 다운로드하여 압축을 해제한다. 이 때, 새로 압축이 풀린 디렉토리는 <sample_install_dir>/renderkits로 표시되어야 하는데, 여기서 <sample_install_dir>은 예제 패키지가 설치된 디렉토리이다. 예를 들어, Windows의 C:\에 압축을 해제했다면 새로 생성된 디렉토리는 C:\renderkits이 되어야 한다. 렌더 키트 디렉토리에는 애플리케이션을 위한 웹 아카이브 renderkits.war와 소스를 뷰하기 위한 서브디렉토리 srcweb이 포함되어 있다.

  3. 다음 명령어를 입력하여 GlassFish 애플리케이션 서버를 시작한다.

    <GF_install_dir>/bin/asadmin start-domain domain1

    이 때, <GF_install_dir>은 GlassFish가 설치된 디렉토리이다.

  4. <sample_install_dir>/renderkits/jsf-renderkits.war<GF_install_dir>/domains/domain1/autodeploy에 복사하여 예제를 설치한다.

  5. 브라우저를 실행하고 다음의 URL을 연다.
    http://localhost:8080/jsf-renderkits/. 앞에서 언급한 것처럼, Firefox 1.5와 같은 내장 빌트인 SVG를 지원하는 Mozilla 브라우저를 사용해야 한다.

저자 소개

Roger Kitain은 JavaServer Faces 공동 스펙 프로젝트를 이끌고 있으며, 1997년부터 서버 측 웹 기술 및 제품 분야에 폭넓게 참여해 왔다. Roger는 또한 2001년에 레퍼런스 구현 팀의 멤버로서 JavaServer Faces 기술 관련 업무를 맡기 시작했으며, Servlet 및 JSP 기술을 통해 풍부한 경험을 축적했다. 최근에 그는 JSF의 다양한 렌더링 기술에 참여하여 왕성한 활동을 벌이고 있다.

맨위로

자바 클라이언트 또는 Java Web Start 기술을 통해 시큐어 엔터프라이즈 빈에 액세스하기
 
저자 Sreenivas Munnangi

본 테크 팁에서는 독립형 자바 클라이언트와 Java Web Start 기술을 사용하는 Java EE 애플리케이션 클라이언트에서 시큐어 Enterprise JavaBeans 컴포넌트(일명 '엔터프라이즈 빈')를 액세스하는 방법을 알아본다. 또한 여기에는 이 클라이언트들이 J2EE Management 스펙, JSR 77을 준수하는 시큐어 MEJB(Management Enterprise JavaBean)을 액세스하는 것을 설명해주는 예제도 포함되어 있다. J2EE Mnagement 스펙은 J2EE 컴포넌트의 관리 정보, 오퍼레이션, 속성 공개 및 액세스를 위한 표준 관리 모델을 제공하며, MEJB는 어떠한 표준 J2EE 애플리케이션에서도 모델에 대한 상호운용적 원격 액세스를 가능하게 해주는 기능을 제공한다.

본 팁에서는 사용자가 Sun Java System Application Server 8.x 또는 GlassFish 빌드를 사용하고 있는 것으로 가정하며, J2EE 1.4 다운로드 페이지에서 J2EE 1.4 SDK에 포함된 Sun Java Application Server 8.2 또는 8.1을 다운로드할 수 있다. GlassFish는 오픈 소스 Java EE 기반의 애플리케이션 서버로, GlassFish 커뮤니티 다운로드 페이지에서 다운로드할 수 있다.

엔터프라이즈 빈의 보안

엔터프라이즈 빈과 같은 J2EE 애플리케이션 컴포넌트의 보안은 각각의 해당 컨테이너가 담당하며, 컨테이너는 두 가지의 보안 기능, 즉 선언적 보안과 프로그램 보안을 제공한다. 선언적 보안은 보안 역할, 액세스 제어, 인증 요건 등을 포함한 애플리케이션의 보안 구조를 애플리케이션에 외부적인 형태로(즉, 배치 서술자로) 표현하고, 프로그램 보안은 애플리케이션에 내장되어 보안 결정을 내리는 데 사용된다. 특히, 프로그램 보안은 선언적 보안만으로는 애플리케이션의 보안 모델을 표현하는 데 충분치 않은 경우에 유용하다.

이 리소스의 선언적 보안을 제공하는 과정에는 배치 서술자 내에서 개별 사용자 ID 또는 사용자 그룹 ID, 즉 애플리케이션 내의 특정 리소스 세트에 대한 액세스를 허가하기 위한 추상 이름을 역할에 매핑하는 작업이 수반된다.

예를 들어, Sun Java Application Server 배치 서술자 sun-application.xml 내의 다음 요소들은 그룹 이름 'asadmin'을 보안 역할 'admin-role'에 매핑한다.

   <security-role-mapping>
     <role-name>admin-role</role-name>
     <group-name>asadmin</group-name>
   </security-role-mapping> 
 

Sun Java System Application Server 8.x나 GlassFish 같은 애플리케이션 서버는 그룹들을 연결하는 동시에 principal(즉, 인증 가능한 개별 사용자 ID)을 생성하는 수단을 제공하는데, 이 작업은 asadmin create-file-user 명령어를 이용하여 수행할 수 있다(신택스는 다음과 같다).

   asadmin create-file-user --port <port> --host <host> 
   --user <user-id> --passwordfile <passwordfile-location> 
   --authrealmname admin-realm --groups <admingrp> 
   <realm-user-id>

매핑이 완료된 후, 컨테이너는 사용자가 시큐어 엔터프라이즈 빈처럼 보호되는 리소스에 액세스하는 데 필요한 허가를 받았는지 여부를 판단한다.

독립형 클라이언트의 경우, 선언적 보안은 시큐어 엔터프라이즈 빈과 통신하기에 충분치 않으므로 프로그램 보안 기능을 제공해야 한다.

시큐어 엔터프라이즈 빈을 위한 프로그램 보안

독립형 클라이언트의 프로그램 보안의 경우, 해당 클라이언트에 프로그램 로그인을 제공하는 API가 필요하다. 따라서 Sun Java System Application Server 8.x와 GlassFish는 com.sun.appserv.security.ProgrammaticLogin 클래스를 통해 이 API를 제공하는데, 이 클래스는 프로그램 로그인 오퍼레이션의 수행을 위해 관련 메소드를 공개한다. 본 팁의 예제에서는 아래의 ProgrammaticLogin 메소드를 이용하여 MEJB를 액세스한다.

   public Boolean login(String user, String password); 

login() 메소드는 사용자 이름과 비밀번호를 제공하는데, 이 정보는 기본 인증 렐름(즉, 동일한 인증 정책에 의해 제어되는 사용자 및 그룹의 집단)에 대한 로그인을 시도하는 데 사용된다. 인증이 성공하면(즉, 사용자의 ID가 검증되면) 사용자를 나타내는 보안 컨텍스트가 정해지고, 이로써 애플리케이션은 프로그램 방식으로 인증을 처리할 수 있게 된다.

이번에는 시큐어 엔터프라이즈 빈을 위한 프로그램 보안의 예제를 살펴보기로 하자. 본 팁에는 시큐어 MEJB에 액세스하는 독립형 클라이언트를 위한 코드가 들어 있는 패키지가 포함되어 있다. 다음은 독립형 클라이언트 코드에서 발췌한 코드의 한 부분이다.

   ProgrammaticLogin pm = new ProgrammaticLogin(); 
   pm.login(userId, password);
   Context initial = new InitialContext();
   Object objref = initial.lookup("ejb/mgmt/MEJB");
   ManagementHome home =
       (ManagementHome)PortableRemoteObject.narrow(
           objref, ManagementHome.class);
   Management mejb = home.create();
   String domain = mejb.getDefaultDomain();

이 코드는 먼저 ProgrammaticLogin을 인스턴스화한 다음 login() 메소드에 액세스하여 사용자 ID와 비밀번호를 제공한다. login() 메소드는 클라이언트에서 엔터프라이즈 빈이 호출될 때까지 이 정보를 클라이언트 측에 캐시하고, 이어서 코드는 MEJB에 대한 액세스를 처리한다. 코드는 InitialContext를 인스턴스화한 다음 MEJB 홈 오브젝트 ejb/mgmt/MEJB의 JNDI 이름을 지정하여 ManagementHome 오브젝트를 검색한다.

이때, 독자들은 사용자 크리덴셜(또는 사용자 인증)이 어떻게 처리될지 궁금해할 수도 있을 것인데, 사용자 크리덴셜은 클라이언트가 엔터프라이즈 빈의 메소드를 호출할 때 서버에 전달된다. 메소드 호출은 IIOP/ORB 인프라에 의해 인터셉트되고 크리덴셜은 보안 컨텍스트 내에 저장된다. 호출되는 메소드가 허가를 필요로 할 경우, EJB 컨테이너는 보안 컨텍스트로부터 사용자 크리덴셜을 검색하여 검증하고, 크리덴셜이 유효하지 않을 경우 메소드는 보안 예외를 throw한다.

lookup과 narrow 메소드가 성공하면 Management 오브젝트에 대한 레퍼런스가 생성되는데, 이 작업은 ManagementHomecreate() 메소드를 호출함으로써 수행된다 -- 이는 표준 엔터프라이즈 빈 호출 프로세스의 일부이다. 이에 관한 내용은 Sun Java Application Server Platform Edition 8.1 개발자 안내서의 ACC 없이 클라이언트 개발하기 섹션에 자세히 설명되어 있다.

이제 예제 애플리케이션을 시험해 볼 차례가 되었다. 이 예제의 경우, 사용자가 included in GlassFish와 Sun Java Application Server 8.1 또는 8.2에 포함된 ant나 asant에 액세스해야 한다.

독립형 클라이언트 예제 실행하기

독립형 클라이언트는 사전 설치된 시스템 애플리케이션을 이용하여 곧바로 사용이 가능하다. 독립형 클라이언트 예제를 설치하고 실행하려면 다음을 수행한다.

  1. Sun Java System Application Server 8.2 또는 GlassFish가 설치되어 있는지 확인한다. 본 지침에서는 GlassFish를 사용하며, 이는 GlassFish 커뮤니티 다운로드 페이지에서 다운로드할 수 있다.

  2. 해당 팁의 예제 패키지를 다운로드하여 압축을 푼다. 이 때, 새로 압축이 풀린 디렉토리는 <sample_install_dir>/stand_alone_client로 표시되어야 하는데, 여기서 <sample_install_dir>은 예제 패키지가 설치된 디렉토리이다. 예를 들어, Windows의 C:\에 압축을 풀었다면, 새로 생성된 디렉토리는 C:\stand_alone_client가 되어야 한다. stand_alone_client 디렉토리에는 클라이언트와 관련한 소스 코드 MEJBClient.java, 빌드 파일 build.xml, 출력 파일 output.txt 등이 포함되어 있다.

  3. 다음 명령어를 입력하여 GlassFish 애플리케이션 서버를 시작한다.

         <GF_install_dir>/bin/asadmin start-domain domain1
    
    이 때, <GF_install_dir>은 GlassFish가 설치된 디렉토리이다.

  4. 애플리케이션 서버 설치에 필요한 경우, build.xml 파일의 <user defined properties> 섹션을 수정한다. 반면에 build.xml의 다른 부분은 전혀 편집할 필요가 없다.

  5. 다음과 같이 asadmin 명령어 라인 유틸리티를 사용하여 기본 렐름 사용자를 생성한다(명령어는 포맷상의 이유로 여러 줄로 표시되었음).

        <GF_install_dir>/bin/asadmin create-file-user 
        --host <host-name> --port <admin-port-number> 
        --user <admin-user> --passwordfile <admin-password-file-path> 
        --groups <security-role-mapping-group-name> <realm.user.id> 
    
    사용자는 다음 행을 포함하는 비밀번호를 생성해야 한다.

         AS_ADMIN_PASSWORD=<admin-password>
         AS_ADMIN_USERPASSWORD=<realm.user.password>
    
    이제 --passwordfile 옵션과 함께 이 파일을 패스한다.

    앞서 설명한 것처럼 realm.user.id and realm.user.password에 대한 값들이 build.xml에 주어진 값들과 일치하고, security-role-mapping-group-name에 대한 값들이 sun-application.xml에 주어진 값들과 일치하는지 확인한다. 명령어 실행에 앞서 다른 값들을 적절히 대체한다.

    asadmin 명령어 'list-file-users'를 사용하여 기본 렐름 사용자가 성공적으로 생성되었는지 확인한다. asadmin 명령어에 관한 자세한 정보를 보려면 명령어 라인에서 asadmin help를 입력하면 된다.

  6. MEJBClient.java를 컴파일하고 실행한다.
          > cd stand_alone_client
          > ant run
    
    그러면 다음과 유사한 결과가 표시되어야 한다.

          run:
            [java] Jan 17, 2006 2:48:49 PM com.sun.corba.ee.spi.
            logging.LogWrapperBase doLog
            [java] INFO: "IOP00710299: (INTERNAL) Successfully 
            created IIOP listener on the specified host/port: 
            all interfaces/52185"
            [java] ***Got the MEJB!!
            [java] ***MEJB default domain = DefaultDomain
            ...
            BUILD SUCCESSFUL
    
    output.txt 파일의 내용에는 전체 결과물이 포함되어 있다.

Java Web Start 기술 예제 실행하기

본 예제에는 애플리케이션 서버에 배치될 Jave EE 애플리케이션 클라이언트가 사용되며, 또한 앞의 예제와 마찬가지로 GlassFish도 사용된다. 본 예제의 경우, JDK 5.0 또는 JRE 5.0에서만 테스트가 실시되었다.

예제를 설치하고 실행하려면 다음의 작업 절차를 따르도록 한다.

  1. 예제 아카이브를 다운로드한다.

  2. 배치 명령어를 이용하여 애플리케이션 클라이언트를 배치한다.
          <GF_install_dir>/bin/asadmin deploy --host <host-name>
          --port <admin-port-number> --user <admin-user> 
          --passwordfile >admin-password-file-path> 
          ttfeb2006acc-mejbClient.jar
  3. 애플리케이션 서버 로그(예를 들어 <GF_install_dir>/domains/domain1/log/server.txt)를 연다. 이 때, 로그 내 어딘가에 다음과 같은 링크가 표시되어야 한다.

          [#|2006-01-17T15:10:21.112-0800|... Java Web Start 
          services started for stand-alone app client ... 
          name=acc-mejbClient, context root=/ ttfeb2006acc-mejbClient, 
          module name=|#] 
    
    Java Web Start를 이용하여 애플리케이션 클라이언트를 액세스하기 위한 URL은 기본값 GlassFish 인스턴스 URL과 컨텍스트 루트(위에 표시된 행의 'Name=' 값)로 구성된다. 따라서, http://8080의 기본값 인스턴스 GlassFish URL과 acc-mejbClient의 컨텍스트 루트의 경우, Java Web Start를 이용하여 애플리케이션 클라이언트를 액세스하기 위한 URL은 http://localhost:8080/ttfeb2006acc-mejbClient이다.

  4. 본 예제는 Java Console에 출력을 디스플레이하는데, 출력을 보려면 Java Console이 표시되도록 Java Web Start를 구성해야 한다. Java Console 옵션을 구성하려면 먼저 Java Web Start의 위치를 파악하고(일반적으로 <jre-install-dir>/bin/javaws or <jre-install-dir>/bin/jws), 그런 다음 Java Web Start를 호출하여 'show console' 옵션을 활성화한다. 다음은 브라우저 타입과 운영체제에 따라 Java Web Start의 위치를 파악하는 방법이다.

    • Windows 상의 Internet Explorer와 FireFox:
      • <시작> <내 컴퓨터>를 클릭한다.
      • '내 컴퓨터' 창에서 <도구> 메뉴 항목을 선택한 다음 <폴더 옵션>을 선택한다.
      • '폴더 옵션' 창에서 <파일 형식> 탭을 선택한다.
      • 확장명이 'JNLP'인 항목을 선택한다.
      • <고급> <편집>을 클릭하고 '명령을 실행할 응용 프로그램'의 값을 확인한다. 이것이 Java Web Start의 위치이다.

    • Windows/Solaris 상의 Netscape:
      • Netscape 브라우저를 연다.
      • <Edit> 메뉴 항목을 선택하고 <Preferences>를 선택한다.
      • <Navigator> 노드를 확장하고 <Helper Applications>를 선택한다. 오른쪽에 File Types 목록이 표시되어야 한다.
      • application/x-java-jnlp-file을 선택한다.
      • <Edit>을 클릭하고 'Open it with'의 값을 확인한다. 이것이 Java Web Start의 위치이다.

      위에서 파악한 Java Web Start의 위치를 이용하여 명령어 창에서 Java Web Start를 호출한다. 그러면 'the 'Java Application Cache Viewer' 창이 열린다.

      그런 다음,

      • 'Java Application Cache Viewer' 창에서 <Edit> 메뉴 항목을 선택하고 <Preferences>를 선택한다. 이제 'Java Control Panel'이 표시된다.
      • <Advanced Tab>을 선택한다.
      • <Java Console>을 확장하고 <Show Console>을 선택한다. <OK> 버튼을 클릭한다.

      <File> 메뉴 항목을 선택한 다음 <Exit>를 선택하면 Java Web Start가 종료된다.

  5. 웹 브라우저를 열고 단계 3에서 파악한 URL을 입력하면 Java Web Start가 시작된다. 이어서 사용자 ID와 비밀번호를 묻는 프롬프트가 표시된다. 프롬프트에 응답하고 나면 애플리케이션 클라이언트에 독립형 클라이언트 예제의 출력과 유사한 출력이 표시되어야 한다.

저자 소개

Sreenivas Munnangi는 Sun Java Application Server의 Administration & Management 팀 고참 멤버이다. 그는 지난 3년 동안 J2EE 그룹에 참여해 왔으며, Application Server Enterprise Edition의 설계와 구현에 크게 기여한 바 있다. 이전에는 전자 상거래 애플리케이션, 웹 애플리케이션, N-티어 애플리케이션 아키텍처 등의 분야에서 경험을 쌓기도 했다.

맨위로

THE JAVA EE 5 SDK PREVIEW를 경험하세요!
 

2006년 2월 21일, 썬마이크로시스템즈에서는 Java EE 5 SDK Preview를 출시하였습니다. Application Server Platfor Edition 9 베타를 포함하고 있습니다. 이번 버전은 NetBeans Enterprise Pack 5.5와 동시에 출시되어, 개발자들이 비지니스상의 문제를 해결하기 위해 엔터프라이즈 Java와 SOA 탑재 애플리케이션 등을 구축하고 디플로이하는데 있어 차세대 Java 플랫폼과 툴을 경험할 수 있는 기회를 제공합니다. 썬사는 이런 새로운 기술들의 개발을 주도자로써, 오픈소스 GlassFish 프로젝트, NetBeans.org 커뮤니티등과 긴밀하게 협조하여 엔터프라이즈 Web 2.0 개발에 적합한 혁신적이고 견고하며 확장가능한 개발 플랫폼을 창조하기 위해 노력하고 있습니다.

맨위로

본 메일은 수신을 동의한 회원님에게만 발송됩니다.
본 메일의 수신을 거부하거나 수신주소를 변경하려면 SKDN@Sun.com으로 문의 주시기 바랍니다.

SKDN(Sun Korea Developers Network)에서 J2EE/J2SE 테크팁 등 다양한 아티클들을 참고하세요.

Copyright 2003-2006 Sun Korea, Ltd. All rights reserved.