![]() | ||||||
| ||||||
4월의 Technology Day! Powering the Participation Age
|
||
| 이번 호에서는, » 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 렌더 키트의 다양한 렌더러에 의해 생성된다. <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> 엘리먼트를 '폼' 엘리먼트로 취급하기 위해서 시작 '폼' 그룹의
<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>
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");
<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 컨트롤러로 전달되도록 매핑이 이루어진다.
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;
}
요청 처리하기 요청이 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);
}
...
}
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 브라우저를 사용해야 한다. 예제를 설치하고 실행하려면 다음의 작업 절차를 따르도록 한다.
저자 소개 Roger Kitain은 JavaServer Faces 공동 스펙 프로젝트를 이끌고 있으며, 1997년부터 서버 측 웹 기술 및 제품 분야에 폭넓게 참여해 왔다. Roger는 또한 2001년에 레퍼런스 구현 팀의 멤버로서 JavaServer Faces 기술 관련 업무를 맡기 시작했으며, Servlet 및 JSP 기술을 통해 풍부한 경험을 축적했다. 최근에 그는 JSF의 다양한 렌더링 기술에 참여하여 왕성한 활동을 벌이고 있다. 맨위로 |
||
| 자바 클라이언트 또는 Java Web Start 기술을 통해 시큐어 엔터프라이즈 빈에 액세스하기 | ||
|
본 테크 팁에서는 독립형 자바 클라이언트와 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 배치 서술자
<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 --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는 public Boolean login(String user, String password);
이번에는 시큐어 엔터프라이즈 빈을 위한 프로그램 보안의 예제를 살펴보기로 하자. 본 팁에는 시큐어 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();
이 코드는 먼저 이때, 독자들은 사용자 크리덴셜(또는 사용자 인증)이 어떻게 처리될지 궁금해할 수도 있을 것인데, 사용자 크리덴셜은 클라이언트가 엔터프라이즈 빈의 메소드를 호출할 때 서버에 전달된다. 메소드 호출은 IIOP/ORB 인프라에 의해 인터셉트되고 크리덴셜은 보안 컨텍스트 내에 저장된다. 호출되는 메소드가 허가를 필요로 할 경우, EJB 컨테이너는 보안 컨텍스트로부터 사용자 크리덴셜을 검색하여 검증하고, 크리덴셜이 유효하지 않을 경우 메소드는 보안 예외를 throw한다.
lookup과 narrow 메소드가 성공하면 이제 예제 애플리케이션을 시험해 볼 차례가 되었다. 이 예제의 경우, 사용자가 included in GlassFish와 Sun Java Application Server 8.1 또는 8.2에 포함된 ant나 asant에 액세스해야 한다. 독립형 클라이언트 예제 실행하기 독립형 클라이언트는 사전 설치된 시스템 애플리케이션을 이용하여 곧바로 사용이 가능하다. 독립형 클라이언트 예제를 설치하고 실행하려면 다음을 수행한다.
Java Web Start 기술 예제 실행하기 본 예제에는 애플리케이션 서버에 배치될 Jave EE 애플리케이션 클라이언트가 사용되며, 또한 앞의 예제와 마찬가지로 GlassFish도 사용된다. 본 예제의 경우, JDK 5.0 또는 JRE 5.0에서만 테스트가 실시되었다. 예제를 설치하고 실행하려면 다음의 작업 절차를 따르도록 한다.
저자 소개 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. |