이번 장은 로컬 웹 서버로 실행할 수 없습니다. 톰캣이나 다른 WAS 서비스를 설정해주고 해당 서버를 사용해야 합니다.
톰캣 서버 설정에 관해서는 아파치 톰캣(Apache Tomcat) 항목을 참고해주세요.
화면 만들기 (트랜잭션)에서는 미리 작성해 저장한 XML 파일 데이터를 가져와 화면에 보여주는 기능을 설명했습니다. 하지만 실제 비즈니스 환경에서는 다양한 데이터베이스에서 데이터를 조회하고 입력한 데이터를 데이터베이스에 저장하는 등의 복잡한 업무 처리가 필요합니다.
넥사크로 앱은 화면(Form)에서 입력받은 데이터를 서버로 전송하고 데이터를 받아오기 위해 transaction() 메소드를 사용합니다. transaction() 메소드는 입력 받은 변수와 데이터셋을 XML 형식으로 변형해 서버에 전달하고 콜백 함수를 통해 받아온 데이터를 처리합니다.
이런 과정에서 클라이언트가 전달한 변수와 데이터셋을 처리하고 데이터베이스에 있는 데이터를 처리하기 위해 서버단에서 동작하는 서비스가 필요합니다. 서버에 구현한 서비스에서는 요청받은 데이터를 다양한 데이터베이스에서 가져와 이를 적절한 형태로 가공하고 클라이언트에 전달해줍니다. 요청에 문제가 생겼을 때 어떤 문제인지 확인할 수 있는 에러 코드와 메시지를 반환해줍니다.
서비스는 JSP, Servlet, ASP, PHP 등 서버 환경에 따라 다양한 프로그래밍 언어로 작성할 수 있습니다. 이번 장에서는 간단한 JSP 서비스를 만들고 어떻게 동작하는지 살펴봅니다.
서비스
화면에서 입력받은 데이터를 transaction() 메소드를 통해 서버에 전달해 처리하고 서버에 저장된 데이터를 다시 조회하는 서비스를 구현합니다.
간단한 테스트를 위해 데이터베이스에 연결하는 대신 파일 형태로 서버에 저장합니다.
아래 3가지 서비스를 설명합니다.
initdata.jsp: 서버에 기본 자료를 생성하고 파일로 저장합니다.
search.jsp: 저장된 파일에서 데이터를 읽어 Dataset을 만들고 클라이언트로 전송합니다.
save_list.jsp: 서버에 전송한 데이터로 기존 파일을 수정합니다.
확장자 JSP는 JavaServer Pages의 약자로 HTML 코드 안에 Java 코드를 추가해 동적으로 화면을 생성할 수 있는 언어를 의미합니다. 기본적인 화면 구조는 HTML 코드로 구성하고 데이터베이스에서 값을 받아 처리하거나 연산이 필요한 부분만 Java 코드를 사용합니다.
X-API
배포 파일
넥사크로 X-API 라이브러리는 데이터 처리를 위한 서비스 구현 시 필요한 기능을 라이브러리 형태로 구현해 제공하고 있습니다. 제공하는 파일은 아래와 같습니다.
nexacro-xapi-java-1.0.0.jar (X-API 라이브러리 파일)
commons-logging-1.1.1.jar (http://commons.apache.org/proper/commons-logging/)
NexacroN_server_license.xml (라이선스 파일)
docs > api (X-API 매뉴얼)
예제에서는 데이터 처리를 위해 넥사크로 X-API를 사용하고 있습니다. X-API는 데이터 처리를 위해 필요한 기능을 구현한 라이브러리일뿐 X-API를 꼭 사용해야 하는 것은 아닙니다.
X-API 배포 파일은 기술지원사이트에서 내려받을 수 있습니다.
http://support.tobesoft.co.kr > PRODUCT > Nexacro N > Download > Server [API, XENI]
개발용 라이선스 파일은 LICENSE 메뉴 아래 [개발용라이선스] 링크에서 신청할 수 있습니다.
설치
톰캣을 설치하고 X-API 예제에서 사용할 컨텍스트 파일을 생성합니다. 톰캣 설치와 컨텍스트 파일을 생성하는 자세한 방법은 아파치 톰캣(Apache Tomcat) 항목을 참고하세요.
1
컨텍스트 파일을 생성합니다. 아래 경로에 CustomerList.xml 파일을 생성합니다.
C:\Program Files\Apache Software Foundation\Tomcat 8.5\conf\Catalina\localhost
$r_title(CustomerList.xml) <Context path="/CustomerList" docBase="E:\88_TEST\02_BUILD\CustomerList" debug="0" prvileged="true" reloadable="true"> <Logger className="org.apache.catalina.logger.FileLogger" directory="logs" prefix="localhost_log." suffix=".txt" timestame="true"/> </Context>
2
내려받은 X-API 파일의 압축을 해제합니다. 압축을 해제하면 docs, lib 폴더 2개가 보이는데 그중에서 lib 폴더 안에 있는 3개의 jar 파일을 사용할 겁니다.
3
docBase로 지정한 폴더를 생성하고 해당 폴더 안에 WEB-INF 폴더를 생성합니다. 그리고 WEB-INF 폴더 안에 lib 폴더를 생성하고 jar 파일과 라이선스 파일을 복사합니다.
E:\88_TEST\02_BUILD\CustomerList\WEB-INF\lib
4
docBase로 지정한 폴더 아래에 테스트를 위한 jsp 파일을 생성합니다.
E:\88_TEST\02_BUILD\CustomerList
$r_title(test.jsp) <%@ page contentType="text/html; charset=UTF-8" %> <html> <head> <title>JarInfo</title> <style> * { font-family: Verdana } </style> </head> <body> <pre> <% new com.nexacro.java.xapi.util.JarInfo().info(out); %> </pre> </body> </html>
5
웹브라우저에서 아래 주소로 접근했을 때 설치 정보가 정상적으로 표시되는지 확인합니다. 설치정보가 표시된다면 정상적으로 X-API가 설치된 겁니다.
http://localhost:8080/CustomerList/test.jsp
WEB-INF는 Web Information의 약자입니다. 컨텍스트 루트 디렉토리 내에 있지만 사용자가 접근할 수 없으며 내부적으로 참조하기 위한 정보를 담고 있습니다.
lib 디렉토리는 jar 파일을 넣어 둘 수 있는 공간입니다. jar는 Java Archive의 약자로 여러개의 자바 클래스 파일과 리소스 등을 하나의 파일로 묶어서 라이브러리처럼 관리하는 파일입니다.
라이브러리를 복사할 위치는 사용하고 있는 WAS 설정에 따라 달라질 수 있습니다.
라이브러리 파일을 복사한 후에는 WAS 서비스를 재시작해주어야 합니다.
WAS 설정에 따라 재시작이 필요없는 경우도 있습니다.
라이브러리 파일과 라이선스 파일은 같은 위치에 복사해야 인식할 수 있습니다.
전용객체
연결된 라이브러리에서 사용되는 전용객체는 다음과 같습니다.
PlatformData : 데이터를 보관하는 기본객체
PlatformRequest : JSP 요청 시에 XML Format Data를 읽고 객체화하는 Input 객체
PlatformResponse : JSP 요청 시에 XML Format Data를 출력하는 output 객체
DatasetList & Dataset : 데이터를 2차원 Table 형태 또는 Table Array 타입으로 보관
VariableList & Variable : I/O 인자값으로 사용되는 단일 값을 보관
자세한 설명은 라이브러리에 포함된 X-API 매뉴얼을 참고해주세요.
화면에 Button 컴포넌트 추가
기존 화면에 데이터 초기화, 저장을 위한 Button 컴포넌트를 추가합니다.
컴포넌트 | 속성 | 값 | 설명 |
---|---|---|---|
1 Button | id | btnSaveList | |
text | Save | 버튼에 표시할 문자열 | |
2 Button | id | btnInitdata | |
text | Initdata | 버튼에 표시할 문자열 |
initdata.jsp
기본 자료를 생성하고 서버에 파일로 저장합니다.
pseudo code
// 1. 자바 라이브러리 지정 (Nexacro X-API 포함) // 2. MIME Type 정의 // 3. Nexacro 기본객체(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.java.xapi.data.*" %> <%@ page import="com.nexacro.java.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 **/ 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] = "Tzuyu"; ... 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>
전체 코드
$r_title(initdata.jsp) <!-- 1.Designating a Java library --> <%@ page import="java.io.*" %> <%@ page import="com.nexacro.java.xapi.data.*" %> <%@ page import="com.nexacro.java.xapi.tx.*" %> <!-- 2. Defining a MIME type --> <%@ page contentType="text/xml; charset=UTF-8" %> <% /** 3. Creating a basic object of Nexacro **/ 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] = "Tzuyu"; customers[2] = "ceo@twice.com"; customers[3] = "6987-6543"; customers[4] = "TWICE"; 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.divCommand_btnInitdata_onclick = function(obj:nexacro.Button, e:nexacro.ClickEventInfo) { var id = "initdata"; var url = "SvcList::initdata.jsp"; var reqDs = ""; var respDs = ""; var args = ""; var callback = "initdata_received"; this.transaction(id, url, reqDs, respDs, args, callback); } this.initdata_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]";
저장된 파일
버튼을 클릭해 initdata.jsp 파일을 호출하면 "saveFile.bin"이라는 이름의 파일이 생성됩니다. 생성된 파일은 WAS(예제에서는 아파치 톰캣)을 설치한 폴더 아래에 생성됩니다.
특정 경로에 파일을 저장하고자 하는 경우에는 아래와 같이 initdata.jsp 파일을 수정해 적용할 수 있습니다.
//String targetFilename = "./saveFile.bin"; File targetFile = new File("c:/saveFile.bin"); OutputStream target = new FileOutputStream(targetFile);
search.jsp
저장된 파일에서 데이터를 읽어 Dataset을 만들고 클라이언트로 전송합니다.
pseudo code
// 1. 자바 라이브러리 지정 (Nexacro X-API 포함) // 2. MIME Type 정의 // 3. Nexacro 기본객체(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.java.xapi.data.*" %> <%@ page import="com.nexacro.java.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 **/ 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">Tzuyu</Col> <Col id="email">ceo@twice.com</Col> <Col id="phone">6987-6543</Col> <Col id="comp_name">TWICE</Col> <Col id="department">0</Col> <Col id="comp_phone">6506-7000</Col> <Col id="comp_addr">Seoul</Col> </Row> </Rows> </Dataset> </Root>
전체 코드
$r_title(search.jsp) <!-- 1.Designating a Java library --> <%@ page import="java.io.*" %> <%@ page import="com.nexacro.java.xapi.data.*" %> <%@ page import="com.nexacro.java.xapi.tx.*" %> <!-- 2. Defining a MIME type --> <%@ page contentType="text/xml; charset=UTF-8" %> <% /** 3. Creating a basic object of Nexacro **/ 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:nexacro.Button, e:nexacro.ClickEventInfo) { var id = "search"; var url = "SvcList::search.jsp"; var reqDs = ""; var respDs = "dsCustomers=customers"; var args = ""; var callback = "search_received"; this.transaction(id, url, reqDs, respDs, args, callback); } this.search_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); } }
데이터베이스 연결
예제에서는 파일로 저장된 데이터셋을 가져와 그대로 클라이언트에게 전달합니다. 파일이 아닌 데이터베이스에 연결한 경우에는 아래와 같이 적용할 수 있습니다.
아래 예제에서 데이터베이스 설정은 예시를 위한 코드입니다. 실제 코드에서는 사용하는 환경에 맞게 수정해서 사용해야 합니다.
$r_title(search.jsp (JDBC Connect)) <%@ page import = "java.util.*" %> <%@ page import = "java.sql.*" %> <%@ page import = "java.io.*" %> <%@ page import="com.nexacro.java.xapi.data.*" %> <%@ page import="com.nexacro.java.xapi.tx.*" %> <%@ 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 X-API) // 2. Defining a MIME type // 3. Creating a basic object of Nexacro (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.java.xapi.data.*" %> <%@ page import="com.nexacro.java.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 **/ 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("customers"); /** 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();
전체 코드
$r_title(save_list.jsp) <!-- 1. Designating a Java library --> <%@ page import="java.io.*" %> <%@ page import="com.nexacro.java.xapi.data.*" %> <%@ page import="com.nexacro.java.xapi.tx.*" %> <!-- 2. Defining a MIME type --> <%@ page contentType="text/xml; charset=UTF-8" %> <% /** 3. Creating a basic object of Nexacro **/ 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("customers"); /** 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.divCommand_btnSaveList_onclick = function(obj:nexacro.Button, e:nexacro.ClickEventInfo) { var id = "save_list"; var url = "SvcList::save_list.jsp"; var reqDs = "customers=dsCustomers"; var respDs = ""; var args = ""; var callback = "save_list_received"; this.transaction(id, url, reqDs, respDs, args, callback); } this.save_list_received = function(id, code, message) { if (code == 0) { this.alert(message); trace(message); } else { this.alert("Error["+code+"]:"+message); trace("Error["+code+"]:"+message); } }