OpenSocial은 가젯으로 알려진 브라우저 기반 구성 요소 모델과 사용자의 프로파일 정보에 대한 정보에 액세스하는 데 필요한 API 및 해당 소셜 그래프(친구 및 활동 등 포함)를 정의하는 커뮤니티 중심 스펙이다. API를 구현하는 애플리케이션은 iGoogle, MySpace, Yahoo, Orkut, Hi5, LinkedIn 등과 같은 광범위한 소셜 네트워킹 사이트와 상호운용 가능하게 된다. 이 기사에서는 OpenSocial 가젯에 초점을 두고 이러한 가젯이 웹에서 애플리케이션의 도달 범위를 확장하는 강력한 방법이 될 수 있는 방법에 대해 설명한다.
OpenSocial 가젯이란?
- OpenSocial 가젯은 특정 API 세트를 구현하는 웹 애플리케이션의 작은 프리젠테이션이다. 가젯은 OpenSocial 스펙을 준수하는 XML 문서에 의해 설명된다. 이 정의에는 HTML, CSS 스타일시트 및 비즈니스 로직을 위한 JavaScript와 같은 사용자 인터페이스와 작성자, 제목 등에 대한 추가 메타데이터가 포함되어 있다.
- OpenSocial 스펙을 구현하고 애플리케이션을 호스트할 수 있는 사이트를 OpenSocial 컨테이너라고 부른다. 이는 OpenSocial 컨테이너가 가젯 XML 정의를 처리할 수 있고 적절한 HTML을 브라우저에 제공할 수 있다는 것을 의미한다. 컨테이너를 제공하는 사이트에서 가젯 정의를 호스트할 필요는 없다는 것을 인식하는 것이 중요하다. 또한 가젯은 일반적으로 완전히 다른 사이트로부터 서비스를 노출한다. 컨테이너에서는 서명된 HTML 요청과 같은 메커니즘을 제공하여 사이트에 있는 가젯에서 호출이 발생하도록 보장한다. 사이트가 OpenSocial 컨테이너가 되면 웹에서 서비스 콜렉션을 쉽게 집계하는 방법을 제공할 수 있다.
이 페이지에서는 사용자에게 Universal Services에서 제공하는 기본 함수 세트를 테스트하는 기능을 제공하고 사용자에게 결과를 표시한다.
그림 1은 샘플 테스트 애플리케이션의 화면 캡처이다. 이 그림은 샘플 OpenSocial 가젯을 빌드하는 데 사용하는 템플리트로 사용된다. 여기서는 Universal Services와 상호작용하기 위해 필요한 기본 UI 기능을 사용자에게 제공한다.
그림 1. 샘플 테스트 애플리케이션
먼저 몇 가지 JavaScript 함수를 작성하여 pureXML 서비스에 대한 연결을 제어하는 기본 쿼리를 제공한다. 그런 다음 지원되는 HTML을 가젯 스펙과 함께 추가한다. 그러면 이 애플리케이션을 작성하고 전개하는 방법을 알게 된다.
pureXML 서비스에 연결하는 JavaScript 함수
Listing 1에서는 요청을 처리하기 위해 작성된 샘플 JavaScript를 제공한다.
Listing 1. PureJSON JavaScript 함수
var prefs = new gadgets.Prefs();
function getPrimaryKeys() {
var args = {};
doPOST("getPrimaryKeys",args,displayJSONobj);
};
function getJSONDocumentByKey(key) {
var args = {
id: key
};
doPOST("getDocumentByKey",args,displayJSONobj);
};
function insertJSON(key, data) {
var args = {
id: key,
doc: data
};
doPOST("insert",args,response);
};
function updateJSON(key, data) {
var args = {
id : key,
doc : data
};
doPOST("update",args,response);
};
function deleteDocument(key) {
var args = {
id : key
};
doPOST("delete",args,response);
};
function doPOST(command,args,processResponseCallback) {
var url = "http://" + prefs.getString("pureXMLHostAddress") +
"/" + prefs.getString("contextRoot") + "/query/"+command;
var params = {};
postdata = gadgets.io.encodeValues(args);
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
params[gadgets.io.RequestParameters.POST_DATA]= postdata;
gadgets.io.makeRequest(url, processResponseCallback, params);
};
function response(obj) {
alert("Gadget implementation responsibility.");
};
function displayJSONobj(obj) {
alert("Gadget implementation responsibility.");
};
|
각 함수의 용도를 살펴본다.
getPrimaryKeys는 getPrimaryKeys 요청을 서비스에 게시하여 DB2 테이블의 모든 기본 키를 검색하고 트랜잭션이 완료되면 콜백 함수displayJSONobj를 사용하여 결과를 표시한다.getJSONDocumentByKey는 키 값을 사용하여 getDocumentByKey를 서비스에 게시하여 입력 값과 일치하는 기본 키가 포함된 단일 JSON 레코드를 검색한다. 이 함수는 콜백 함수displayJSONobj를 사용하여 결과를 표시한다.insertJSON은 기본 키의 고유 키 값과 JSON 형식의 행 데이터라는 두 가지 입력 매개변수를 예상한다. 이 함수는 요청을 서비스에 게시하여 DB2 테이블에서 새 행을 작성하고 콜백 함수response를 사용하여 트랜잭션이 리턴될 때 삽입 상태를 확인한다.updateJSON은 요청을 서비스에 게시하는 기능을 제공하여 JSON 형식으로 입력 데이터로 지정된 업데이트된 데이터와 입력 키 값과 일치하는 기본 키가 포함된 JSON 레코드를 업데이트한다. 또한 이 함수는 콜백 함수response를 호출하여 트랜잭션이 완료될 때 업데이트를 확인한다.deleteDocument는 지정된 입력 기본 키를 기반으로 레코드 제거 요청을 서비스에 게시하는 인터페이스를 제공한다. 또한 이 함수는response콜백 함수를 호출하여 요청 완료 후 삭제를 확인한다.displayJSONobj는 개발자가 브라우저에서 호출 결과를 렌더링하는 데 다양한 접근 방식을 제공하기 위해 필요한 후크를 제공하는 추상 JavaScript 함수이다.response는 JSON이 아닌 리턴값을 처리하는 함수이다. 이 함수는 개발자가 함수를 자체 구현으로 대체하기를 기대하면서 displayJSONobj와 같은 비슷한 전략을 따른다.
위의 함수는 doPOST 함수를 호출하여 요청을 제출한다.
doPOST 함수는 서비스에서 리턴되는 결과를 처리하는 콜백 함수,
서비스 쿼리 명령 및 쿼리 입력 값을 예상한다. 이 함수는 이러한 입력 매개변수를 사용하여
서비스에 대한 gadgets.io.makeRequest 호출을 빌드한다.
gadgets.io.makeRequest는 써드파티 사이트에서 데이터를 가져오고
데이터를 게시하는 가젯에 대한 지원을 제공하는 OpenSocial 가젯 함수이다. 서명의
형식은 gadgets.io.makeRequest(url, callback, opt_params)이다.
매개변수는 다음과 같다.
url- 요청을 전송할 사이트의 URL이 포함된 문자열이다. URL을 만들기 위해doPOST함수가prefs오브젝트에서getString메소드를 사용하여 두 개의 문자열을 검색한다는 것을 알게 된다. (pureXMLHostAddress및contextRoot매개변수는 다음 섹션에서 다루는 가젯 정의에 있는 요소 이름을 참조한다.) 이러한 두 문자열은/query/및 명령(insert, getDocumentByKey, update, delete 등)과 연결된다. 예를 들어,insertJSON()함수가doPOST를 호출하면 URL은 다음과 같다.
http://xmlim.watson.ibm.com:9080/JSONUniversalServices/query/insertcallback- 요청이 리턴될 때 호출되는 함수에 대한 참조이다. 예를 들어,response는 트랜잭션의 상태를 표시하는 콜백 함수이고displayJSONobj는 오브젝트가 비어 있는 경우 리턴되는 JSON 오브젝트 또는 메시지를 표시하는 콜백 함수이다.opt_params- 호출에 대한 추가 매개변수가 포함된 JavaScript 오브젝트이다(HTTP 메소드 및 POST 데이터). 여기서는 요청의 HTTP 메소드를gadgets.io.MethodType.POST로 설정하여 POST 메소드임을 표시한다. 또한postdata오브젝트(gadgets.io.encodeValues()를 사용하여 입력args를 형식화하여 키/값 쌍이 포함된 오브젝트로 지정됨)에 있는 게시 데이터를 전달한다.
Listing 1을 PureJSON.js로 저장한다. 다음 단계에서 가젯 정의를 빌드하고 이 파일을 로드한다.
필요한 JavaScript가 있으므로 이제 가젯 정의를 작성한다.
단순한 가젯 정의가 필요하다. Listing 2에서는 샘플 가젯 정의를 제공한다.
각각의 가젯 정의는 <Module> 태그로 둘러싸여 있다.
<ModulePrefs>는 가젯에 대한 기본 정보 및 기능을 정의한다.
Listing 2. OpenSocial 가젯에 대한 XML 정의
<?xml version="1.0" encoding="UTF-8"?> <Module> <ModulePrefs title="Universal Services"> <Require feature="opensocial-0.8"/> <Require feature="dynamic-height"/> <Require feature="minimessage"/> </ModulePrefs> <UserPref name="pureXMLHostAddress" display_name="PureXML Host Address" default_value="xmlim.watson.ibm.com:9080"/> <UserPref name="contextRoot" display_name="Context Root" default_value="JSONUniversalServices"/> <Content type="html"> <![CDATA[ <!-- Note: We will add more code and expand this section later --> ]]> </Content> </Module> |
가젯 정의에서 먼저 유의할 항목은 <ModulePrefs> 요소에 있는
<title> 속성이다. 제목, 작성자, 이메일 등과 같은
가젯에 대한 정보를 정의하는 속성을 지정할 수 있다. 이 데모의 목적상 여기서는 title
속성만 사용한다. 하지만 일부 컨테이너에서는 실제 전개를 위해 특정 속성을 제공해야
한다는 점을 유의해야 한다. 이 정보에 대한 플랫폼 개발자 문서를 참조해야 하고
가젯에 필요한 기능도 제공한다. 샘플 가젯은 다음 기능을 로드한다.
opensocial-0.8- 이 가젯은 OpenSocial 버전 0.8 구현 API를 사용하기 때문에 OpenSocial v0.8 스펙을 지원하는 컨테이너에 전개될 수 있다.dynamic-height- 이 기능을 사용하여 가젯 개발자는 컨텐츠가 추가 또는 제거될 때 가젯 높이를 조정할 수 있다. 이 기능은 가젯에 있는 DB2 트랜잭션 메시지를 표시하거나 제거할 때 호출된다.minimessage- 이 기능은 가젯에서 사용자에 대한 메시지를 작성하고 표시하는 API 세트를 제공한다. 이 예제에서는minimessage를 사용하여 DB2 트랜잭션 상태 메시지를 작성한다.
또한 사용자 환경 설정 세트(<UserPref>)를 정의하여 가젯이 전개될 애플리케이션의
컨텍스트 경로와 pureXML Universal Service 엔드포인트를 동적으로 설정했다. 정의된 <UserPref>
요소는 가젯이 렌더링될 때 가젯 인터페이스에서 사용자 입력으로 노출된다. 그러면 사용자가 이러한 설정을
적절하게 편집하고 수정할 수 있다. 이러한 <UserPref> 요소의 name
속성은 엔드포인트 URL을 구성하기 위해 사용된 문자열을 가져오기 위해 Listing 1의 JavaScript doPOST
함수에 사용된 것과 동일한 이름이다.
네 번째로 컨텐츠 섹션 <Content>는 HTML인 가젯의 컨텐츠 유형을 정의한다.
CDATA(문자 데이터) 섹션에서 minimessage와 결합된 사용자 입력, 사용자 환경 설정 및
실행 중인 가젯이 될 JavaScript 함수를 캡처하기 위해 HTML 테이블이 작성되는 가젯 컨텐츠 자체를 정의한다.
다음 단계에서 이 섹션을 펼쳐 pureXML 서비스에 연결하는 클라이언트를 빌드한다.
이전 단계에서 설명한 가젯 정의의 CDATA
섹션에서 이제 샘플 HTML 테이블 및 JavaScript 함수를 추가하여 사용자 입력 및 조치를 캡처한다.
먼저 Listing 3과 같이 HTML 테이블에 사용된 스타일시트를 추가한다.
Listing 3. 테이블에 사용된 스타일시트
<style type="text/css">
table.layout {border:0; width:50%;}
td.green {background-color:#BFFF80;
font-family:sans-serif, verdana;}
td.white {background-color:#FFFFFF;
font-family:sans-serif, verdana;}
th.green {background-color:#BFFF80;
font-family:sans-serif, verdana;}
th.white {background-color:#FFFFFF;
font-family:sans-serif, verdana;}
td.row-bright{background-color:#FFFFBF;
font-family:sans-serif, verdana;
text-align:center;}
td.row-dark {background-color:#FFFF8C;
font-family:sans-serif, verdana;
text-align:center;}
tr.row-bright {background-color:#FFFFBF;
font-family:sans-serif, verdana;}
tr.row-dark {background-color:#FFFF8C;
font-family:sans-serif, verdana;}
tr.empty {background-color:#FFFFFF;
height: 10px;}
tr.empty-small {background-color:#FFFFFF;
height: 5px;}
</style>
|
두 번째로 Listing 1의 JavaScript 파일 PureJSON.js를 포함시킨다. 가젯이 로드될 때
PureJSON.js는 페이지에 포함되어 모든 POST 요청 함수를 HTML 테이블 조치에서 사용할 수 있다.
Listing 4. JavaScript 파일 로드하기
<script type="text/javascript" src="./PureJSON.js"></script>
|
세 번째로 Listing 5와 같이 또다른 <script>를 추가한다.
각각의 JavaScript 함수는 HTML 테이블(다음 섹션에서 정의함)에 선언된 사용자 조치와
일치하며 Listing 1에서 PureJSON.js에 정의된 함수 중 하나를 호출한다. 이 코드 블록이
로드되면 new gadgets.MiniMessage(_MODULE_ID_)를 사용하여 minimessage 오브젝트가 작성된다.
태그의 맨 아래에 있는 gadgets.util.registerOnLoadHandler(gadgets.window.adjustHeight)
함수가 호출되어 가젯을 OpenSocial 컨테이너에 등록하고 렌더링 시 가젯 컨텐츠에 맞게 프레임을 수정하도록 지시한다.
또한 이 스크립트 태그에서는 response 및 displayJSONobj 함수를
대체하여 쿼리 결과를 사용자에게 표시한다.
Listing 5. 가젯 함수 추가하기
<script type="text/javascript" src="./PureJSON.js"></script>
<script type="text/javascript">
var msg = new gadgets.MiniMessage(__MODULE_ID__);
function displayJSONobj(obj) {
var str = "The returned record is empty, it might not exist";
if(obj.text!=""){
str = obj.text;
}
msg.createDismissibleMessage(str);
gadgets.window.adjustHeight();
};
function callGetJSONDoc() {
getJSONDocumentByKey(document.getElementById("key1").value);
};
function getJSONDocumentByKeyReturn(obj) {
var str = obj.text;
msg.createDismissibleMessage(str);
gadgets.window.adjustHeight();
};
function callInsertJSON() {
insertJSON(document.getElementById("key2").value,
document.getElementById("document1").value);
};
function callUpdateJSON() {
updateJSON(document.getElementById("key3").value,
document.getElementById("document2").value);
};
function callDeleteDoc() {
deleteDocument(document.getElementById("key4").value);
};
function response(obj) {
var str = gadgets.json.parse(gadgets.util.unescapeString(obj.text));
if(str.updateCount == 1){
var successMsg = msg.createDismissibleMessage(
"Received returned code = 1. Transaction successful!");
successMsg.style.color = "green";
}
else {
var failMsg = msg.createDismissibleMessage(
"Did not receive returned code = 1. Transaction may have failed!");
failMsg.style.color = "red";
}
gadgets.window.adjustHeight();
};
gadgets.util.registerOnLoadHandler(gadgets.window.adjustHeight);
</script>
|
마지막으로 HTML 테이블을 추가하여 사용자 입력 및 조치를 캡처한다. Listing 6에서는 HTML 코드를 보여 준다. 가젯 정의를 JSONclient.xml로 저장한다. 그림 1에 있는 화면 캡처는 테이블이 렌더링될 때 표시되는 내용이다.
Listing 6. HTML 테이블
<table class="layout" cellspacing="2">
<tr>
<th class="green">Web Service</th>
<th class="green" colspan="2">Input</th>
<th class="green">Action</th>
</tr>
<tr class="row-bright">
<td>getPrimaryKeys</td>
<td colspan="2" align="center">none</td>
<td align="center">
<input type="submit" value="Invoke" onClick="getPrimaryKeys()"/>
</td>
</tr>
<tr class="row-dark" >
<td>getJSONDocumentByKey</td>
<td align="right">ID:</td>
<td align="center"><input type="text" id="key1" size="40" /></td>
<td align="center">
<input type="submit" value="Invoke" onClick="callGetJSONDoc()"/>
</td>
</tr>
<tr class="row-bright">
<td rowspan="2">insertJSON</td>
<td align="right">ID:</td>
<td align="center"><input type="text" id="key2" size="40" /></td>
<td align="center" rowspan="2">
<input type="submit" value="Invoke" onClick="callInsertJSON()"/>
</td>
</tr>
<tr class="row-bright">
<td align="right">Document:</td>
<td align="center">
<textarea id="document1" cols="30" rows="5" ></textarea>
</td>
</tr>
<tr class="row-dark" >
<td rowspan="2">updateJSON</td>
<td align="right">ID:</td>
<td align="center"><input type="text" id="key3" size="40" /></td>
<td rowspan="2" align="center">
<input type="submit" value="Invoke" onClick="callUpdateJSON()"/>
</td>
</tr>
<tr class="row-dark">
<td align="right">Document:</td>
<td align="center">
<textarea id="document2" cols="30" rows="5" ></textarea>
</td>
</tr>
<tr class="row-bright">
<td>deleteDocument</td>
<td align="right">ID:</td>
<td align="center"><input type="text" id="key4" size="40" /></td>
<td align="center">
<input type="submit" value="Invoke" onClick="callDeleteDoc()"/>
</td>
</tr>
</table>
|
이제 가젯을 전개한 후 테스트한다.
새 Universal Services 테스트 애플리케이션을 테스트하려면 PureJSON.js와 JSONclient.xml을 모두 HTTP 서버에 단순히 전개하기만 하면 된다. URL을 통해 이러한 파일을 사용할 수 있는 한 OpenSocial 컨테이너는 가젯 스펙을 검색하고 이에 따라 컨텐츠를 렌더링할 수 있다. OpenSocial 서버에는 오픈 소스 프로젝트와 외부적으로 호스트된 플랫폼을 통해 사용할 수 있는 로컬 전개를 위한 다수의 옵션이 있다. 단순하게 하기 위해 OpenSocial 컨테이너를 제공할 iGoogle 샌드박스에 이 샘플 가젯을 전개한다.
- http://www.google.com/ig/sandbox에 로그인한다.
- 로그인했으면 페이지의 오른쪽 상단 섹션에 있는 Add stuff 링크로 이동한다. 기존의 등록된 가젯에 대한
검색 기능을 제공하는 페이지로 링크된다. 그림 2를 참조한다. URL은 웹에서 액세스할 수 있어야 한다.
예를 들어, 방화벽 뒤에서 실행 중인 경우에는 OpenSocial 컨테이너(이 경우에는 iGoogle)가 가젯 정의를 로드하고
처리할 수 없기 때문에 전개가 작동하지 않을 수 있다. (그림 2의 확대 버전 보기)
그림 2. iGoogle 샌드박스에 애플리케이션 추가하기
- 다음으로 URL을 사용하여 이 새 가젯을 추가해야 한다. 왼쪽 탐색 메뉴에 Add feed or gadget의 링크가 표시된다.
이 링크는 JSONclient.xml의 전체 URL을 입력해야 하는 대화 상자를 연다. 그림 3을 참조한다.
그림 3. iGoogle 샌드박스에 OpenSocial 가젯 추가하기
- 이제 iGoogle 홈 페이지로 돌아가서 페이지에서 새로 추가된 가젯을 볼 수 있다.
그림 4에서는 iGoogle에서 렌더링된 가젯을 보여 준다.
그림 4. iGoogle에서 렌더링된 가젯
- 가젯 설정을 편집하려면 삼각형 아이콘을 선택하여 옵션 드롭 다운 목록을 연다. Edit settings를 선택한다.
- pureXML 호스트 주소와 컨텍스트 루트 경로를 업데이트하여 Universal Services를 가리킨다.
- getJSONDocumentByKey 필드에 문서 키를 입력하여 JSON 레코드를 검색한 후 Invoke를 클릭한다. 다른 트랜잭션을 테스트하려면 이 단계를 반복한다.
- 미니 메시지에 결과가 표시된다. 메시지를 제거하려면 행의 끝에 있는 x를 선택한다.
이 기사에서는 웹의 다수 플랫폼에 신속하게 전개할 수 있는 구성 가능하고 이동 가능한 애플리케이션으로 전형적인 테스트 웹 애플리케이션을 마이그레이션하는 샘플 코드 세트를 제공했다. 애플리케이션 자체는 상대적으로 단순하여 이 참조를 사용하여 새 애플리케이션을 신속하게 어셈블하고 프로토타입화할 수 있다. OpenSocial 가젯 클라이언트는 사용자에게 UserPrefs 지원을 통해 pureXML Universal Services에 동적으로 연결하는 편리한 방법을 제공한다. POST makeRequest를 사용하여 가젯 개발자는 단순히 데이터베이스 트랜잭션을 수행하기 위해 서비스에 연결하는 쿼리를 작성할 수 있다. 가젯 이용자는 컨텐츠 및 인프라 관리 부담 없이 실제로 전개 및 호스트되는 위치에 관계없이 OpenSocial 컨테이너에 가젯을 추가할 수 있다.
| 설명 | 이름 | 크기 | 다운로드 방식 |
|---|---|---|---|
| JavaScript POST request functions | PureJSON.js.zip | 1KB | HTTP |
| OpenSocial gadget definition XML | JSONclient.xml.zip | 2KB | HTTP |
교육
- pureXML 및 JSON 애플리케이션 빌드하기, Part 1: DB2 pureXML로 JSON 저장 및 쿼리하기(Nuno Job, Susan Malaika 및 Michael Schenke, developerWorks, 2009년 10월): 이 시리즈의 첫 번째 기사를 살펴보고 세션에서 상태를 유지하는 지속되는 JSON 오브젝트의 혜택을 받아보자. DB2 pureXML과 단순한 JSON 대 XML 맵핑을 사용하여 JSON을 저장하고 관리하고 쿼리해 보자. (세 편으로 구성된 시리즈 중 Part 1임)
- Build a pureXML and JSON application, Part 2: Create Universal Services for pureXML that expose JSON(Faton (Tony) Avdiu, Susan Malaika 및 Michael Schenke, developerWorks, 2009년 10월): 이 기사에 있는 단계를 수행하면 JSON Universal Services를 통해 시리즈의 첫 번째 기사에서 설명한 JSON 데이터를 노출할 수 있다. (세 편으로 구성된 시리즈 중 Part 2임)
- OpenSocial 커뮤니티: 기사, 튜토리얼 및 기술 스펙에 대한 링크를 찾아보고 소셜 네트워크에 OpenSocial API를 임베드하여 웹의 소셜 데이터에 액세스하거나 소셜 데이터를 공유하는 방법을 살펴보자.
- iGoogle 개발자 가이드 참조: 이 환경에서 OpenSocial 지원과 애플리케이션 개발 및 전개에 대한 세부사항을 살펴보자.
- Apache Shindig: 이 OpenSocial 컨테이너를 살펴 가젯을 렌더링하고 요청을 프록시하고 REST 및 RPC 요청을 처리하는 코드로 OpenSocial 애플리케이션을 신속하게 호스트해 보자. 이 오픈 소스 커뮤니티는 이 환경에서 OpenSocial 스펙 및 전개를 위한 참조 전개를 개발하고 있다.
- IBM XML 인증: XML 및 관련 기술에 대한 IBM 인증 개발자가 되는 방법을 찾아볼 수 있다.
- XML Technical library: developerWorks XML 영역에서 다양한 기술 관련 기사와 팁, 튜토리얼, 표준 및 IBM Redbook을 볼 수 있다.
- developerWorks 기술 행사 및 웹 캐스트: 이들 세션에 참가하여 최신 기술에 대한 정보를 얻을 수 있다.
- developerWorks
팟캐스트: 소프트웨어 개발자의 흥미로운 인터뷰와 토론을 확인할 수 있다.
제품 및 기술 얻기
- DB2 Express-C: DB2 데이터 서버의 이 무료 커뮤니티 에디션을 다운로드하자.
- IBM 제품 평가판: IBM SQA Sandbox의 온라인 시험판을 다운로드하거나 살펴보고 DB2®,
Lotus®, Rational®, Tivoli® 및
WebSphere®.
토론
- 포럼에 참여하기.
- XML 영역 토론 포럼: 여러 XML 관련 토론에 참여해 볼 수 있다.
- developerWorks 블로그: 이 블로그를 읽고 developerWorks 커뮤니티에 참여하자.
