화면 만들기 (X-API)

화면 만들기 (트랜잭션)에서는 미리 작성해 저장한 XML 파일 데이터를 가져와 화면에 보여주는 기능을 설명했습니다. 하지만 실제 비즈니스 환경에서는 다양한 데이터베이스에서 데이터를 조회하고 입력한 데이터를 데이터베이스에 저장하는 등의 복잡한 업무 처리가 필요합니다.

넥사크로플랫폼 애플리케이션은 화면(Form)에서 입력 받은 데이터를 서버로 전송하고 데이터를 받아오기 위해 transaction() 메소드를 사용합니다. transaction() 메소드는 입력 받은 변수와 데이터셋을 XML 형식으로 변형해 서버에 전달하고 콜백 함수를 통해 받아온 데이터를 처리합니다.

이런 과정에서 클라이언트가 전달한 변수와 데이터셋을 처리하고 데이터베이스에 있는 데이터를 처리하기 위해 서버단에서 동작하는 서비스가 필요합니다. 서버에 구현한 서비스에서는 요청받은 데이터를 다양한 데이터베이스에서 가져와 이를 적절한 형태로 가공하고 클라이언트에 전달해줍니다. 요청에 문제가 생겼을 때 어떤 문제인지 확인할 수 있는 에러 코드와 메시지를 반환해줍니다.

서비스는 JSP, Servlet, ASP, PHP 등 서버 환경에 따라 다양한 프로그래밍 언어로 작성할 수 있습니다. 이번 장에서는 간단한 JSP 서비스를 만들고 어떻게 동작하는지 살펴봅니다.

서비스

화면에서 입력 받은 데이터를 transaction() 메소드를 통해 서버에 전달해 처리하고 서버에 저장된 데이터를 다시 조회하는 서비스를 구현합니다.

간단한 테스트를 위해 데이터베이스에 연결하는 대신 파일 형태로 서버에 저장합니다.

아래 3가지 서비스를 설명합니다.

X-API

배포 파일

넥사크로플랫폼 X-API 라이브러리는 데이터 처리를 위한 서비스 구현 시 필요한 기능을 라이브러리 형태로 구현해 제공하고 있습니다. 제공하는 파일은 아래와 같습니다.

예제에서는 데이터 처리를 위해 넥사크로플랫폼 X-API를 사용하고 있습니다. X-API는 데이터 처리를 위해 필요한 기능을 구현한 라이브러리일뿐 X-API를 꼭 사용해야 하는 것은 아닙니다.

설치

jar 파일과 라이선스 파일을 사용하고 있는 WAS의 WEB-INF 폴더 아래 복사합니다.

/WEB-INF/lib/nexacro-xapi-1.0.jar
/WEB-INF/lib/commons-logging-1.1.1.jar
/WEB-INF/lib/nexacro14_server_license.xml

라이브러리를 복사할 위치는 사용하고 있는 WAS 설정에 따라 달라질 수 있습니다.

라이브러리 파일과 라이선스 파일은 같은 위치에 복사해야 인식할 수 있습니다.

정상적으로 배포가 설치가 되었다면 아래 코드로 설치 여부를 확인할 수 있습니다.

<%@ page contentType="text/html; charset=UTF-8" %>

<html>
<head>
<title>JarInfo</title>
<style>
* { font-family: Verdana }
</style>
</head>
<body>
<pre>
<%
new com.nexacro.xapi.util.JarInfo().info(out);
%>
</pre>
</body>
</html>

전용객체

연결된 라이브러리에서 사용되는 전용객체는 다음과 같습니다.

자세한 설명은 라이브러리에 포함된 X-API 매뉴얼을 참고해주세요.

initdata.jsp

기본 자료를 생성하고 서버에 파일로 저장합니다.

pseudo code

// 1. 자바 라이브러리 지정 (nexacro platform X-API 포함)
// 2. MIME Type 정의
// 3. nexacro platform 기본객체(PlatformData) 생성
try {
	// 4. Data 처리
	// 5. ErrorCode, ErrorMsg 처리하기 (성공 메시지)
} catch (Error) {
	// 5. ErrorCode, ErrorMsg 처리하기 (실패 메시지)
}
// 6. 결과 Data Client에게 보내기

코드 구현

자바 라이브러리 지정

JSP 서비스를 작성하기 위해 기본 자바 라이브러리를 지정합니다. 코드는 아래와 같습니다.

<!-- 1. Designating a Java library -->
<%@ page import="java.io.*" %>
<%@ page import="com.nexacro.xapi.data.*" %>
<%@ page import="com.nexacro.xapi.tx.*" %>

MIME 타입 정의

XML 생성을 위한 MIME(Multipurpose Internet Mail Extensions) 타입을 정의합니다.

<!-- 2. Defining a MIME type -->
<%@ page contentType="text/xml; charset=UTF-8" %>

기본객체(PlatformData) 생성하기

데이터를 처리하기 위한 기본객체를 선언합니다. 기본 객체인 PlatformData는 넥사크로플랫폼 애플리케이션에서 사용하는 모든 데이터(Dataset, 변수)를 한꺼번에 담을 수 있는 객체입니다.

PlatformData를 선언하는 코드는 다음과 같습니다.

/** 3. Creating a basic object of Nexacro Platform **/
PlatformData pdata = new PlatformData();

Dataset을 생성하여 File로 저장하기

Dataset을 생성하여 column 정보를 입력하고 2개의 row을 생성한 후 각 row마다 column을 입력합니다. 생성한 DataSet은 쉽게 다룰 수 있도록 PlatformData에 등록합니다.

등록된 PlatformData 객체를 사용하여 "./saveFile.bin"이라는 이름의 파일로 저장합니다. Dataset을 생성하고 파일로 저장하는 코드는 다음과 같습니다.

/** 4. Processing data: saving data as a file **/
/** 4.1 Creating a dataset and inputting basic data to the dataset **/
DataSet ds = new DataSet("customers");
ds.addColumn("id",DataTypes.STRING, 4);
ds.addColumn("name",DataTypes.STRING, 16);
...

int row = 0;
int i = 0;
String[] customers = new String[8];
    
customers[0] = "TC-001";
customers[1] = "Harry A. Brown";
...

for (i = 0; i < 2; i++)
{
	row = ds.newRow(); 
	ds.set(row,"id",customers[0]);
	ds.set(row,"name",customers[1]);
	...
}

pdata.addDataSet(ds);

/** 4.2 Saving a dataset to a file **/
String targetFilename = "./saveFile.bin";
OutputStream target = new FileOutputStream(targetFilename);
PlatformResponse res = new PlatformResponse(target, 
	PlatformType.CONTENT_TYPE_BINARY);
res.setData(pdata);
res.sendData();
target.close();

ErrorCode, ErrorMsg 처리하기

예외 상황이 발생했을 때 이를 처리하기 위한 부분입니다.

/** 5.1 Processing ErrorCode and ErrorMsg **/
int nErrorCode = 0;
String strErrorMsg = "START";
try {
	/** 5.2 Setting ErrorCode and ErrorMsg for success **/
	nErrorCode = 0;
	strErrorMsg = "SUCC";
} catch (Throwable th) {
	/** 5.3 Setting ErrorCode and ErrorMsg for failure **/
	nErrorCode = -1;
	strErrorMsg = th.getMessage();
}

/** 5.4 Saving ErrorCode and ErrorMsg to send them to the client **/
PlatformData senddata = new PlatformData();
VariableList varList = senddata.getVariableList();
varList.add("ErrorCode", nErrorCode);
varList.add("ErrorMsg", strErrorMsg);

결과값 Client에게 보내기

초기값이 정상적으로 파일에 저장되었는지 여부를 사용자에게 전달하기 위하여 PlatformData 객체를 사용합니다. 이때, 앞에서 저장한 ErrorCode와 ErrorMsg가 전달됩니다.

VariableList는 PlatformData의 멤버이므로 수행 결과값은 PlatformData 객체에 들어있습니다. 이제 PlatformData의 데이터를 넥사크로플랫폼에서 처리할 수 있는 XML Format으로 추출하여 전송하는 부분을 구현해 보겠습니다. 데이터를 전송하는 기능을 쉽게 구현하기 위해 PlatformResponse 객체를 만들고 PlatformData 객체에서 데이터를 출력시키는 코드는 다음과 같습니다.

/** 6. Sending result data to the client **/
HttpPlatformResponse res = new HttpPlatformResponse(response, 
	PlatformType.CONTENT_TYPE_XML,"UTF-8");
res.setData(senddata);
res.sendData();

정상적으로 데이터가 처리되었다면 클라이언트에게 전달되는 XML 값은 아래와 같습니다.

<Root xmlns="http://www.nexacro.com/platform/dataset" ver="5000">
	<Parameters>
		<Parameter id="ErrorCode" type="int">0</Parameter>
		<Parameter id="ErrorMsg" type="string">SUCC</Parameter>
	</Parameters>
</Root>

전체 코드

<!-- 1.Designating a Java library -->
<%@ page import="java.io.*" %>
<%@ page import="com.nexacro.xapi.data.*" %>
<%@ page import="com.nexacro.xapi.tx.*" %>

<!-- 2. Defining a MIME type -->
<%@ page contentType="text/xml; charset=UTF-8" %>

<%
/** 3. Creating a basic object of Nexacro Platform **/
PlatformData pdata = new PlatformData();

/** 5-1. Processing ErrorCode and ErrorMsg **/
int nErrorCode = 0;
String strErrorMsg = "START";

try {
    /** 4. Processing data: saving data as a file **/
    /** 4.1 Creating a dataset and inputting basic data to the dataset **/
    DataSet ds = new DataSet("customers");
    ds.addColumn("id",DataTypes.STRING, 4);
    ds.addColumn("name",DataTypes.STRING, 16);
    ds.addColumn("email", DataTypes.STRING, 32);
    ds.addColumn("phone", DataTypes.STRING, 16);
    ds.addColumn("comp_name", DataTypes.STRING, 32);
    ds.addColumn("department", DataTypes.STRING, 32);
    ds.addColumn("comp_phone", DataTypes.STRING, 16);
    ds.addColumn("comp_addr", DataTypes.STRING, 256);
    
    int row = 0;
    int i = 0;
    String[] customers = new String[8];
    
    customers[0] = "TC-001";
    customers[1] = "Harry A. Brown";
    customers[2] = "ceo@tobesoft.com";
    customers[3] = "6987-6543";
    customers[4] = "TOBESOFT";
    customers[5] = "0";
    customers[6] = "6506-7000";
    customers[7] = "Seoul";

    for (i = 0; i < 1; i++)
    {
        row = ds.newRow(); 
        ds.set(row,"id",customers[0]);
        ds.set(row,"name",customers[1]);
        ds.set(row,"email",customers[2]);
        ds.set(row,"phone",customers[3]);
        ds.set(row,"comp_name",customers[4]);
        ds.set(row,"department",customers[5]);
        ds.set(row,"comp_phone",customers[6]);
        ds.set(row,"comp_addr",customers[7]);
    }

    pdata.addDataSet(ds);

    /** 4.2 Saving a dataset to a file **/
    String targetFilename = "./saveFile.bin";
    OutputStream target = new FileOutputStream(targetFilename);
    PlatformResponse res = new PlatformResponse(target, 
    	PlatformType.CONTENT_TYPE_BINARY);
    res.setData(pdata);
    res.sendData();
    target.close(); 
    System.out.println("after file write.."); 

    /** 5.2 Setting ErrorCode and ErrorMsg for success**/
    nErrorCode = 0;
    strErrorMsg = "SUCC";
    
} catch (Throwable th) {
    /** 5.3 Setting ErrorCode and ErrorMsg for failure **/
    nErrorCode = -1;
    strErrorMsg = th.getMessage();
}

/** 5.4 Saving the ErrorCode and ErrorMsg to send them to the client **/
PlatformData senddata = new PlatformData();
VariableList varList = senddata.getVariableList();
varList.add("ErrorCode", nErrorCode);
varList.add("ErrorMsg", strErrorMsg);
    
/** 6. Sending result data to the client **/
HttpPlatformResponse res = new HttpPlatformResponse(response, 
	PlatformType.CONTENT_TYPE_XML,"UTF-8");
res.setData(senddata);
res.sendData();
%>

데이터 초기화 이벤트

화면 만들기 (트랜잭션)에서 만든 화면에 버튼 컴포넌트를 추가하고 아래와 같이 onclick 이벤트를 추가합니다. 화면 내 버튼을 클릭하면 initdata.jsp 서비스가 호출되면서 서버에 데이터셋이 담긴 파일을 생성합니다.

this.btnInitdata_onclick = function(obj:Button,  e:nexacro.ClickEventInfo)
{
     var id = "initdata";  
     var url = "SvcList::initdata.jsp";
     var reqDs = "";
     var respDs = "";
     var args = "";
     var callback = "received";

     this.transaction(id, url, reqDs, respDs, args, callback);	
}

this.received = function(id, code, message)
{
     if (code == 0) {
          this.alert(message);
          trace(message);
     } else {
          this.alert("Error["+code+"]:"+message);
          trace("Error["+code+"]:"+message);
     }
}

url 속성은 전체 URL을 지정할 수 있습니다. 매번 전체 URL을 지정하는 것이 번거롭고 자주 사용하는 도메인이라면 TypeDefinition에 서비스 URL을 추가하고 변경되는 파일명만 지정할 수 있습니다.

지정된 서비스는 아래와 같이 사용합니다.

var url = "[Service ID]::[file name]";

search.jsp

저장된 파일에서 데이터를 읽어 Dataset을 만들고 클라이언트로 전송합니다.

pseudo code

// 1. 자바 라이브러리 지정 (nexacro platform X-API 포함)
// 2. MIME Type 정의
// 3. nexacro platform 기본객체(PlatformData) 생성
try {
	// 4. Data 처리
	// 5. ErrorCode, ErrorMsg 처리하기 (성공 메시지)
} catch (Error) {
	// 5. ErrorCode, ErrorMsg 처리하기 (실패 메시지)
}
// 6. 결과 Data Client에게 보내기

코드 구현

자바 라이브러리 지정

JSP 서비스를 작성하기 위해 기본 자바 라이브러리를 지정합니다. 코드는 아래와 같습니다.

<!-- 1. Designating a Java library -->
<%@ page import="java.io.*" %>
<%@ page import="com.nexacro.xapi.data.*" %>
<%@ page import="com.nexacro.xapi.tx.*" %>

MIME 타입 정의

XML 생성을 위한 MIME(Multipurpose Internet Mail Extensions) 타입을 정의합니다.

<!-- 2. Defining a MIME type -->
<%@ page contentType="text/xml; charset=UTF-8" %>

기본객체(PlatformData) 생성하기

데이터를 처리하기 위한 기본객체를 선언합니다. 기본 객체인 PlatformData는 넥사크로플랫폼 애플리케이션에서 사용하는 모든 데이터(Dataset, 변수)를 한꺼번에 담을 수 있는 객체입니다.

PlatformData를 선언하는 코드는 다음과 같습니다.

/** 3. Creating a basic object of Nexacro Platform **/
PlatformData pdata = new PlatformData();

File의 내용을 읽어서 Dataset 생성하기

"./saveFile.bin" 파일의 내용을 읽어서 PlatformData 객체에 저장합니다. PlatformData 객체에 Dataset이 담겨 있습니다.

파일에서 내용을 읽어서 PlatformData에 담는 코드는 다음과 같습니다.

/** 4. Processing data: Loading data from the file: loading data from the file **/
/** 4.1 Loading data from the file **/
String sourceFilename = "./saveFile.bin";
InputStream source = new FileInputStream(sourceFilename);

PlatformRequest req = new PlatformRequest(source, 
	PlatformType.CONTENT_TYPE_BINARY);
req.receiveData();
source.close();

/** 4.2 Copying the loaded data to the dataset **/
pdata = req.getData();

ErrorCode, ErrorMsg 처리하기

예외 상황이 발생했을 때 이를 처리하기 위한 부분입니다.

/** 5.1 Processing ErrorCode and ErrorMsg **/
int nErrorCode = 0;
String strErrorMsg = "START";
try {
	/** 5.2 Setting ErrorCode and ErrorMsg for success**/
	nErrorCode = 0;
	strErrorMsg = "SUCC";
} catch (Throwable th) {
	/** 5.3 Setting ErrorCode and ErrorMsg for failure **/
	nErrorCode = -1;
	strErrorMsg = th.getMessage();
}

/** 5.4 Saving ErrorCode and ErrorMsg to send them to the client **/
PlatformData pdata = new PlatformData();
VariableList varList = pdata.getVariableList();
varList.add("ErrorCode", nErrorCode);
varList.add("ErrorMsg", strErrorMsg);

결과값 Client에게 보내기

초기값이 정상적으로 파일에 저장되었는지 여부를 사용자에게 전달하기 위하여 PlatformData 객체를 사용합니다. 이때, 앞에서 저장한 ErrorCode와 ErrorMsg가 전달됩니다.

initdata.jsp에서 PlatformData 객체는 ErrorCode와 ErrorMsg만을 담고 있지만, search.jsp에서는 PlatformData에 Client가 사용하는 명함리스트 Dataset을 담고 있습니다.

VariableList는 PlatformData의 멤버이므로 수행 결과값은 PlatformData 객체에 들어있습니다. 이제 PlatformData의 데이터를 넥사크로플랫폼에서 처리할 수 있는 XML Format으로 추출하여 전송하는 부분을 구현해 보겠습니다. 데이터를 전송하는 기능을 쉽게 구현하기 위해 PlatformResponse 객체를 만들고 PlatformData 객체에서 데이터를 출력시키는 코드는 다음과 같습니다.

/** 6. Sending result data to the client **/
HttpPlatformResponse res = new HttpPlatformResponse(response, 
	PlatformType.CONTENT_TYPE_XML,"UTF-8");
res.setData(pdata);
res.sendData();

정상적으로 데이터가 처리되었다면 클라이언트에게 전달되는 XML 값은 아래와 같습니다.

<Root xmlns="http://www.nexacro.com/platform/dataset" ver="5000">
	<Parameters>
		<Parameter id="ErrorCode" type="int">0</Parameter>
		<Parameter id="ErrorMsg" type="string">SUCC</Parameter>
	</Parameters>
	<Dataset id="customers">
		<ColumnInfo>
			<Column id="id" type="string" size="4"/>
			<Column id="name" type="string" size="16"/>
			<Column id="email" type="string" size="32"/>
			<Column id="phone" type="string" size="16"/>
			<Column id="comp_name" type="string" size="32"/>
			<Column id="department" type="string" size="32"/>
			<Column id="comp_phone" type="string" size="16"/>
			<Column id="comp_addr" type="string" size="256"/>
		</ColumnInfo>
		<Rows>
			<Row>
				<Col id="id">TC-001</Col>
				<Col id="name">Harry A. Brown</Col>
				<Col id="email">ceo@tobesoft.com</Col>
				<Col id="phone">6987-6543</Col>
				<Col id="comp_name">TOBESOFT</Col>
				<Col id="department">0</Col>
				<Col id="comp_phone">6506-7000</Col>
				<Col id="comp_addr">Seoul</Col>
			</Row>
		</Rows>
	</Dataset>
</Root>

전체 코드

<!-- 1.Designating a Java library -->
<%@ page import="java.io.*" %>
<%@ page import="com.nexacro.xapi.data.*" %>
<%@ page import="com.nexacro.xapi.tx.*" %>

<!-- 2. Defining a MIME type -->
<%@ page contentType="text/xml; charset=UTF-8" %>
<%
/** 3. Creating a basic object of Nexacro Platform **/
PlatformData pdata = new PlatformData();

/** 5.1 Processing ErrorCode and ErrorMsg **/
int nErrorCode = 0;
String strErrorMsg = "START";

try {
	/** 4. Processing data : Loading data from the file: loading data from the file **/
	/** 4.1 Loading data from the file **/
	String sourceFilename = "./saveFile.bin";;
	InputStream source = new FileInputStream(sourceFilename);

	PlatformRequest req = new PlatformRequest(source, 
		PlatformType.CONTENT_TYPE_BINARY);
	req.receiveData();
	source.close();

	/** 4.2 Copying the loaded data to the dataset **/
	pdata = req.getData();

	/** 5.2 Setting ErrorCode and ErrorMsg for success **/
	nErrorCode = 0;
	strErrorMsg = "SUCC";

} catch (Throwable th) {
	/** 5.3 Setting ErrorCode and ErrorMsg for failure **/
	nErrorCode = -1;
	strErrorMsg = th.getMessage();
}

/** 5.4 Saving ErrorCode and ErrorMsg to send them to the client **/
VariableList varList = pdata.getVariableList();
varList.add("ErrorCode", nErrorCode);
varList.add("ErrorMsg", strErrorMsg);

/** 6. Sending result data to the client **/
HttpPlatformResponse res = new HttpPlatformResponse(response, 
	PlatformType.CONTENT_TYPE_XML,"UTF-8");
res.setData(pdata);
res.sendData();
%>

데이터 조회 이벤트

화면 만들기 (트랜잭션)에서 만든 화면에서 조회 버튼에 지정된 onclick 이벤트를 수정합니다. 화면 내 버튼을 클릭하면 search.jsp 서비스가 호출되면서 서버에 저장된 파일을 읽어 데이터셋을 반환해줍니다.

서버에서 보낸 데이터셋 정보는 화면 내 작성된 dsCustomers 데이터셋에 담겨 해당 데이터를 그리드에 표시합니다.

this.divCommand_btnSearch_onclick = function(obj:Button,  e:nexacro.ClickEventInfo)
{
     var id = "search";  
     var url = "SvcList::search.jsp";
     var reqDs = "";
     var respDs = "dsCustomers=customers";
     var args = "";
     var callback = "received";

     this.transaction(id, url, reqDs, respDs, args, callback);	
}

this.received = function(id, code, message)
{
     if (code == 0) {
		var rowcount = this.dsCustomers.rowcount;
		this.alert(rowcount + " numbers of data have been found.");
		trace(rowcount + " numbers of data have been found.");
     } else {
          this.alert("Error["+code+"]:"+message);
          trace("Error["+code+"]:"+message);
     }
}

데이터베이스 연결

예제에서는 파일로 저장된 데이터셋을 가져와 그대로 클라이언트에게 전달합니다. 파일이 아닌 데이터베이스에 연결한 경우에는 아래와 같이 적용할 수 있습니다.

<%@ page import = "java.util.*" %>
<%@ page import = "java.sql.*" %>
<%@ page import="com.nexacro.xapi.data.*" %>
<%@ page import = "java.io.*" %>

<%@ page contentType="text/xml; charset=utf-8" %>

<%
/****** Service API initialization ******/
PlatformData pdata = new PlatformData();

int nErrorCode = 0;
String strErrorMsg = "START";

/******* JDBC Connection *******/
Connection conn = null;
Statement  stmt = null;
ResultSet  rs   = null;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
conn = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;;DatabaseName=Sample",
	"guest","guest");
stmt = conn.createStatement();

try {
	/******* SQL query *************/
	String SQL = "select * from sample_customers_list";
	rs = stmt.executeQuery(SQL);

	/********* Dataset Create ************/
	DataSet ds = new DataSet("customers");
	ds.addColumn("id",DataTypes.STRING, 4);
	ds.addColumn("name",DataTypes.STRING, 16);
	ds.addColumn("email", DataTypes.STRING, 32);
	ds.addColumn("phone", DataTypes.STRING, 16);
	ds.addColumn("comp_name", DataTypes.STRING, 32);
	ds.addColumn("department", DataTypes.STRING, 32);
	ds.addColumn("comp_phone", DataTypes.STRING, 16);
	ds.addColumn("comp_addr", DataTypes.STRING, 256);
	int row = 0;
	while(rs.next())
	{
		row = ds.newRow();
		ds.set(row, "id", rs.getString("id"));	
		ds.set(row, "name", rs.getString("name"));
		ds.set(row, "email", rs.getString("email"));
		ds.set(row, "phone", rs.getString("phone"));
		ds.set(row, "comp_name", rs.getString("comp_name"));
		ds.set(row, "department", rs.getString("department"));
		ds.set(row, "comp_phone", rs.getString("comp_phone"));
		ds.set(row, "comp_addr", rs.getString("comp_addr"));
	}

	/********* Adding Dataset to PlatformData ************/
	pdata.addDataSet(ds);

	nErrorCode = 0;
	strErrorMsg = "SUCC";
}
catch(SQLException e) {
	nErrorCode = -1;
	strErrorMsg = e.getMessage();
}

/******** JDBC Close *******/
if ( stmt != null ) try { stmt.close(); } catch (Exception e) {}
if ( conn != null ) try { conn.close(); } catch (Exception e) {}

PlatformData senddata = new PlatformData();
VariableList varList = senddata.getVariableList();
varList.add("ErrorCode", nErrorCode);
varList.add("ErrorMsg", strErrorMsg);

/******** XML data Create ******/
HttpPlatformResponse res = new HttpPlatformResponse(response, 
	PlatformType.CONTENT_TYPE_XML,"UTF-8");
res.setData(pdata);
res.sendData();
%>

save_list.jsp

서버로 전송한 데이터를 파일로 저장합니다.

pseudo code

initdata.jsp, search.jsp와 다르게 '클라이언트 요청 받기'라는 단계가 추가되었습니다.

// 1. Designating a Java library (including nexacro platform X-API)
// 2. Defining a MIME type
// 3. Creating a basic object of Nexacro Platform (PlatformData)
try {
	// 4. Receiving a request from the client
	// 5. Processing data
	// 6. Processing ErrorCode and ErrorMsg (success message)
} catch (Error) {
	// 6. Processing ErrorCode and ErrorMsg (failure message)
}
// 7. Sending result data to the client

코드 구현

자바 라이브러리 지정

JSP 서비스를 작성하기 위해 기본 자바 라이브러리를 지정합니다. 코드는 아래와 같습니다.

<!-- 1. Designating a Java library -->
<%@ page import="java.io.*" %>
<%@ page import="com.nexacro.xapi.data.*" %>
<%@ page import="com.nexacro.xapi.tx.*" %>

MIME 타입 정의

XML 생성을 위한 MIME(Multipurpose Internet Mail Extensions) 타입을 정의합니다.

<!-- 2. Defining a MIME type -->
<%@ page contentType="text/xml; charset=UTF-8" %>

기본객체(PlatformData) 생성하기

데이터를 처리하기 위한 기본객체를 선언합니다. 기본 객체인 PlatformData는 넥사크로플랫폼 애플리케이션에서 사용하는 모든 데이터(Dataset, 변수)를 한꺼번에 담을 수 있는 객체입니다.

PlatformData를 선언하는 코드는 다음과 같습니다.

/** 3. Creating a basic object of Nexacro Platform **/
PlatformData pdata = new PlatformData();

클라이언트 요청 받기

클라이언트가 매개변수로 보낸 Dataset을 받아서 처리합니다.

/** 4. Receiving a request from the client **/
// create HttpPlatformRequest for receive data from client
HttpPlatformRequest req = new HttpPlatformRequest(request);
req.receiveData();

클라이언트가 보낸 데이터 추출 후 파일로 저장하기

클라이언트가 보낸 정보를 처리할 수 있도록 PlatformData로 변환한 후 Dataset을 추출합니다. 생성된 PlatformData는 "./saveFile.bin" 파일로 저장합니다.

/** 5. Processing data: Loading data from the file **/
/** 5.1 Loading data from the http object **/ 
pdata = req.getData();

/** Obtaining a dataset from the received data **/
DataSet ds = pdata.getDataSet("dsCustomers");

/** Saving data as a file with init data **/
String targetFilename = "./saveFile.bin";
OutputStream target = new FileOutputStream(targetFilename);
PlatformResponse res = new PlatformResponse(target, 
	PlatformType.CONTENT_TYPE_BINARY);
res.setData(pdata);
res.sendData();
target.close();

ErrorCode, ErrorMsg 처리하기

예외 상황이 발생했을 때 이를 처리하기 위한 부분입니다. 성공적으로 처리한 경우에는 정상적으로 저장되었다는 메시지를 반환합니다.

/** 6.1 Processing ErrorCode and ErrorMsg **/
int nErrorCode = 0;
String strErrorMsg = "START";
try {
	/** 6.2 Setting ErrorCode and ErrorMsg for success **/
	nErrorCode = 0;
	strErrorMsg = "person list saved complete : row count("+ds.getRowCount()+")";
} catch (Throwable th) {
	/** 6.3 Setting ErrorCode and ErrorMsg for failure **/
	nErrorCode = -1;
	strErrorMsg = th.getMessage();
}

/** 6.4 Saving ErrorCode and ErrorMsg to send them to the client **/
PlatformData senddata = new PlatformData();
VariableList varList = senddata.getVariableList();
varList.add("ErrorCode", nErrorCode);
varList.add("ErrorMsg", strErrorMsg);

결과값 Client에게 보내기

초기값이 정상적으로 파일에 저장되었는지 여부를 사용자에게 전달하기 위하여 PlatformData 객체를 사용합니다. 이때, 앞에서 저장한 ErrorCode와 ErrorMsg가 전달됩니다.

VariableList는 PlatformData의 멤버이므로 수행 결과값은 PlatformData 객체에 들어있습니다. 이제 PlatformData의 데이터를 넥사크로플랫폼에서 처리할 수 있는 XML Format으로 추출하여 전송하는 부분을 구현해 보겠습니다. 데이터를 전송하는 기능을 쉽게 구현하기 위해 PlatformResponse 객체를 만들고 PlatformData 객체에서 데이터를 출력시키는 코드는 다음과 같습니다.

/** 7. Sending result data to the client **/
HttpPlatformResponse res = new HttpPlatformResponse(response, 
	PlatformType.CONTENT_TYPE_XML,"UTF-8");
res.setData(senddata);
res.sendData();

전체 코드

<!-- 1. Designating a Java library -->
<%@ page import="java.io.*" %>
<%@ page import="com.nexacro.xapi.data.*" %>
<%@ page import="com.nexacro.xapi.tx.*" %>

<!-- 2. Defining a MIME type -->
<%@ page contentType="text/xml; charset=UTF-8" %>

<%
/** 3. Creating a basic object of Nexacro Platform **/
PlatformData pdata = new PlatformData();

/** 6.1 Processing ErrorCode and ErrorMsg **/
int nErrorCode = 0;
String strErrorMsg = "START";

try {
	/** 4. Receiving a request from the client **/
	// create HttpPlatformRequest for receive data from client
	HttpPlatformRequest req = new HttpPlatformRequest(request);
	req.receiveData();
	/** 5. Processing data: Loading data from the file **/
	/** 5.1 Loading data from the http object **/ 
	pdata = req.getData();

	/** Obtaining a dataset from the received data **/
	DataSet ds = pdata.getDataSet("dsCustomers");

	/** Saving data as a file with init data **/
	String targetFilename = "./saveFile.bin";
	OutputStream target = new FileOutputStream(targetFilename);
	PlatformResponse res = new PlatformResponse(target, 
		PlatformType.CONTENT_TYPE_BINARY);
	res.setData(pdata);
	res.sendData();
	target.close(); 

	/** 6.2 Setting ErrorCode and ErrorMsg for success **/
	nErrorCode = 0;
	strErrorMsg = "person list saved complete : row count("+ds.getRowCount()+")";
	
} catch (Throwable th) {
	/** 6.3 Setting ErrorCode and ErrorMsg for failure **/
	nErrorCode = -1;
	strErrorMsg = th.getMessage();
	System.out.println("ERROR:"+strErrorMsg); 
}

/** 6.4 Saving ErrorCode and ErrorMsg to send them to the client **/
PlatformData senddata = new PlatformData();
VariableList varList = senddata.getVariableList();
varList.add("ErrorCode", nErrorCode);
varList.add("ErrorMsg", strErrorMsg);

/** 7. Sending result data to the client **/
HttpPlatformResponse res = new HttpPlatformResponse(response, 
	PlatformType.CONTENT_TYPE_XML,"UTF-8");
res.setData(senddata);
res.sendData();
%>

데이터 저장 이벤트

화면 만들기 (트랜잭션)에서 만든 화면에 버튼 컴포넌트를 추가하고 아래와 같이 onclick 이벤트를 추가합니다. 화면 내 버튼을 클릭하면 save_list.jsp 서비스가 호출되면서 화면에서 수정한 데이터셋을 서버로 전송하고 다시 파일로 저장합니다.

데이터를 수정할 수 있는 기능을 간단하게 추가합니다. 화면 내 그리드를 더블클릭하고 Grid Contents Editor를 실행한 다음 Name 항목을 선택한 후 edittype 속성을 'text'로 수정합니다.

데이터 조회 후 해당 항목을 더블 클릭하면 데이터를 수정할 수 있습니다.

데이터 수정 후 저장(save) 버튼을 클릭해 데이터를 서버로 전송합니다.

화면을 새로 고침한 다음 조회(Search) 버튼을 클릭하면 수정한 데이터가 조회되는 것을 확인할 수 있습니다.

this.btnSaveList_onclick = function(obj:Button,  e:nexacro.ClickEventInfo)
{
     var id = "search";  
     var url = "SvcList::save_list.jsp";
     var reqDs = "customers=dsCustomers";
     var respDs = "";
     var args = "";
     var callback = "received";

     this.transaction(id, url, reqDs, respDs, args, callback);
}

this.received = function(id, code, message)
{
     if (code == 0) {
          this.alert(message);
          trace(message);
     } else {
          this.alert("Error["+code+"]:"+message);
          trace("Error["+code+"]:"+message);
     }
}