====== WEB SERVICE 가이드 ====== 이 화면은 xFrame5-DevStudio에서 프로젝트 실행시 WEB SERVICE 방식 설명을 위한 예시화면이다. WEB SERVICE 방식은 xFrame5-DevStudio에서 직접 개발 DB에 접속하지 않고 웹 서비스 호출에 의해서 실행되는 개발 방식이다. 초기 실행 방식만 다르고 접속 후에는 DATABASE 개발 방식과 동일하다. ===== WEB SERVICE 방식 관련 환경 설정 ===== xFrame5-DevStudio 실행 후, 프로젝트 실행창에서 WEB 탭을 선택한다. Service URL 부분에 서비스 URL을 지정하고 연결 버튼을 클릭한다. ex) http://127.0.0.1/webservice.jsp 이후는 Database 프로젝트 개발 방식과 동일하게 진행한다. ===== 예시 ===== WEB SERVICE 방식에 대한 샘플 JSP는 툴 설치 디렉토리\template\STUDIO\WEBSERVICE 안에 JSP 파일을 참조한다. Service URL : webservice.jsp.txt -> webservice.jsp 이름 변경 후 사용한다. 템플릿 위치: /STUDIO/WEBSERVICE/webservice 템플릿 파일 * [[xf5projecthome>template/screen/STUDIO/WEBSERVICE/webservice.xml|webservice.xml]] * [[xf5projecthome>template/screen/STUDIO/WEBSERVICE/webservice.js|webservice.js]] * [[xf5projecthome>template/screen/STUDIO/WEBSERVICE/webservice.jsp.txt|webservice.jsp.txt]] * [[xf5projecthome>template/template.html?xframe_screen_url=/STUDIO/WEBSERVICE/webservice|새창으로 실행]] echo ''; echo ''; echo ''; ==== webservice.jsp 스크립트 ==== <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.sql.*" %> <%@ page import="java.io.*" %> <%@ page import="javax.naming.*" %> <%@ page import="javax.sql.*" %> <%! /** * @File Name : webservice.jsp * @Description : xFrame 웹 서비스 프로젝트 서비스 JSP * @Modification Information * @ * @ 수정일 수정내용 * @ --------- --------- ------------------------------- * @ 2018.09.03 최초생성 * @ 2020.10.06 수정배포 * @ 2021.09.02 수정배포 MYSQL DB 연결 정보 문자열 오류 수정 및 소스 정렬 수정 * * @author 소프트베이스 솔루션 개발팀 * @since 2018. 09. 03 * @version 1.0 * @see * * Copyright (C) by Softbase All right reserved. */ %> <%! // 데이터에 쌍따옴표로 묶여 있는경우 제거 public static String fnRemoveDobubleQuot(String strString) { if (strString == null || strString.contentEquals("")) { return strString; } if (strString.substring(0, 1).contentEquals("\"")) { strString = strString.substring(1, strString.length()); } if (strString.substring(strString.length() - 1, strString.length()).contentEquals("\"")) { strString = strString.substring(0, strString.length() - 1); } return strString; } // 숫자를 bytearray 4byte로 변환 public static byte[] getByteArrayFromInt(int nValue) { byte[] baBuff = new byte[4]; baBuff[0] = (byte)((nValue & 0xff000000) / 0x1000000); baBuff[1] = (byte)((nValue & 0x00ff0000) / 0x10000); baBuff[2] = (byte)((nValue & 0x0000ff00) / 0x100); baBuff[3] = (byte)(nValue & 0x000000ff); return baBuff; } // 데이터 전송 public static void fnWriteOneFieldData(OutputStream outStream, String strData, String strCharSet) { try { byte[] baData = strData.getBytes(strCharSet); int nDataLength = baData.length; // 데이터 길이(4byte) outStream.write(getByteArrayFromInt(baData.length), 0, 4); // 데이터 outStream.write(baData, 0, nDataLength); } catch (Exception e) { } } // 파라미터값에서 한글이 깨지는 경우, 파라미터 코드 변환용 함수 public static String asc2kscUTF8(String asc) throws UnsupportedEncodingException { if(asc == null) return null; return new String(asc.getBytes("ISO-8859-1"), "UTF-8"); } %> <% //Dev@Studio에서 데이터 처리 시 사용하는 구분자 final byte DATASTART_DEL = 0x03; //데이터 시작 final byte DATAEND_DEL = 0x03; //데이터 끝 final String S_CHARSET = "UTF-8"; Connection conn = null; // DB Connection Object PreparedStatement pstmt = null; // JDBC PreparedStatement Object ResultSet rs = null; // Query Result Set Object ResultSetMetaData rsMetaData = null; //Jsp Servlet 기본 out 객체 초기화(java class 파일에서는 필요하지않음) out.clear(); out = pageContext.pushBody(); try { // DATABASE 접속 설정.(접속할 DATABASE 환경에 맞게 수정하여 사용) // Case1. JDBC 연결 방식 /* ORACLE */ String strDBServiceName = "orcl"; String strDatabaseNm = "ORACLE"; String strDriverClass = "oracle.jdbc.driver.OracleDriver"; String strDBUrl = "jdbc:oracle:thin:@127.0.0.1:1521:" + strDBServiceName; String strDBUserID = "xframe"; String strDBUserPWD = "xframe"; /* MYSQL String strDBServiceName = "xframe"; String strDatabaseNm = "MYSQL"; String strDriverClass = "com.mysql.jdbc.Driver"; String strDBUrl = "jdbc:mysql://127.0.0.1:3306/" + strDBServiceName + "?useUnicode=true&characterEncoding=utf8"; String strDBUserID = "xframe"; String strDBUserPWD = "xframe"; */ /* MariaDB String strDBServiceName = "xframe"; String strDatabaseNm = "MARIADB"; String strDriverClass = "org.mariadb.jdbc.Driver"; String strDBUrl = "jdbc:mariadb://127.0.0.1:3306/" + strDBServiceName; String strDBUserID = "xframe"; String strDBUserPWD = "xframe"; */ /* DB2 String strDBServiceName = "dev2db"; String strDatabaseNm = "DB2"; String strDriverClass = "com.ibm.db2.jcc.DB2Driver"; String strDBUrl = "jdbc:db2://127.0.0.1:50000/" + strDBServiceName; String strDBUserID = "xframe"; String strDBUserPWD = "xframe"; */ /* MS-SQL String strDBServiceName = "xframe"; String strDatabaseNm = "MS-SQL"; String strDriverClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver"; String strDBUrl = "jdbc:sqlserver://127.0.0.1:1433,databaseName=" + strDBServiceName; String strDBUserID = "xframe"; String strDBUserPWD = "xframe"; */ /* JDBC 연결 */ Class.forName(strDriverClass); conn = DriverManager.getConnection(strDBUrl, strDBUserID, strDBUserPWD); /* Case2. DBCP JNDI 방식 Context context = new InitialContext(); DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/oracle"); // WAS JNDI 이름으로 변경 conn = dataSource.getConnection(); String strDatabaseNm = "ORACLE"; String strDBServiceName = "orcl"; */ // 결과 전송을 위한 스트림 객체 생성 OutputStream outStream = response.getOutputStream(); //PrintWriter outWriter = response.getWriter(); // 데이터 시작 표시 outStream.write(DATASTART_DEL); // 파라미터중 command값을 읽어들인다. String strCommand = request.getParameter("command"); // 앞뒤에 쌍따옴표 있으면 제거 strCommand = fnRemoveDobubleQuot(strCommand); // command 처리. command는 3가지중 하나. (open, select, execute) if (strCommand.contentEquals("open")) { // 데이터베이스에 연결된 결과를 반환. if (conn == null) { // 성공/실패여부 // 로그 System.out.println("[xFrame WebService] " + strDatabaseNm +" Connection is null : Database 접속 실패."); outStream.write("0".getBytes(S_CHARSET)); // 에러 메세지 outStream.write("open fail".getBytes(S_CHARSET)); } else { // open에 대한 결과 데이터 - 성공실패여부(1,0) + DB종류 + 접속한 oracle serivce명 // - DB종류 : "ORACLE", "MYSQL", "MS-SQL", "DB2", "TIBERO" // 성공/실패여부 // 로그 System.out.println("[xFrame WebService] " + strDatabaseNm +" Connection is Success."); outStream.write("1".getBytes(S_CHARSET)); // 필드 갯수 outStream.write(getByteArrayFromInt(2), 0, 4); // DB종류 전송 fnWriteOneFieldData(outStream, strDatabaseNm, S_CHARSET); // 접속한 Database serivce명 전송 fnWriteOneFieldData(outStream, strDBServiceName, S_CHARSET); } } else if (strCommand.contentEquals("select")) { // select할 쿼리문을 읽어들인다. String strQuery = request.getParameter("query"); if (strQuery != null && !strQuery.contentEquals("")) { strQuery = fnRemoveDobubleQuot(strQuery); } // 쿼리 실행 pstmt = conn.prepareStatement(strQuery); rs = pstmt.executeQuery(); // 결과 데이터 확인 rsMetaData = rs.getMetaData(); // 성공여부 전송 (성공:1, 실패:0) outStream.write("1".getBytes(S_CHARSET)); // 필드 갯수 전송 outStream.write(getByteArrayFromInt(rsMetaData.getColumnCount()), 0, 4); // 레코드단위 필드 단위로 데이터 조립 for (int nRow = 0; rs.next(); nRow++) { for (int nCol = 1; nCol <= rsMetaData.getColumnCount(); nCol++) { String strData = rs.getString(nCol); if (strData == null) { strData = ""; } // 데이터 전송 fnWriteOneFieldData(outStream, strData, S_CHARSET); } } } else if (strCommand.contentEquals("execute")) { // execute할 쿼리문을 읽어들인다. String strQuery = request.getParameter("query"); if(strQuery != null && !strQuery.contentEquals("")) { strQuery = fnRemoveDobubleQuot(strQuery); } // 쿼리 실행 pstmt = conn.prepareStatement(strQuery); // clob데이터가 전달되었는지 확인하고 처리. // clob데이터 개수를 먼저 읽어들이고 개수만큼 clob데이터를 읽어 들인다. String strCLOBCount = request.getParameter("clobcount"); strCLOBCount = fnRemoveDobubleQuot(strCLOBCount); if (strCLOBCount != null && !strCLOBCount.contentEquals("")) { int nCLOBCount = Integer.parseInt(strCLOBCount); // clob데이터 파라미터 이름은 clobdata0, clobdata1, clobdata2.. 순으로 전달받음. String strCLOBData; String strCLOBParam; for (int nCount = 0;nCount < nCLOBCount;nCount++) { strCLOBParam = "clobdata" + Integer.toString(nCount); strCLOBData = request.getParameter(strCLOBParam); if (strCLOBData == null) { strCLOBData = ""; } if (!strCLOBData.contentEquals("")) { strCLOBData = fnRemoveDobubleQuot(strCLOBData); } pstmt.setCharacterStream(nCount + 1 , new StringReader(strCLOBData), strCLOBData.length()); } } int nRet = pstmt.executeUpdate(); // 성공/실패 여부 전송 if (-1 < nRet) { // 성공/실패여부, 성공 outStream.write("1".getBytes(S_CHARSET)); } else { // 성공/실패여부, 실패 outStream.write("0".getBytes(S_CHARSET)); // 에러 메세지 outStream.write("execute fail".getBytes(S_CHARSET)); } } else { // command(open, select, execute) 가 아닐경우 에러 처리 outStream.write("0".getBytes(S_CHARSET)); // 에러 메세지 outStream.write("알 수 없는 command입니다. 관리자에게 문의하세요.".getBytes(S_CHARSET)); } // 데이터 끝 표시 outStream.write(DATAEND_DEL); outStream.flush(); outStream.close(); } catch (Exception e) { // outputstream에 데이터를 쓰는 중간에 오류가 나면 response를 reset한 후 에러메세지 전송. response.reset(); OutputStream outStream = response.getOutputStream(); // 데이터 시작 표시 outStream.write(DATASTART_DEL); // 실패 코드 설정 outStream.write("0".getBytes(S_CHARSET)); // 에러메세지 설정 outStream.write(e.getMessage().getBytes(S_CHARSET)); // 데이터 끝 표시 outStream.write(DATAEND_DEL); outStream.flush(); outStream.close(); // 콘솔 에러 메세지 출력 e.printStackTrace(); } finally { // Release a database resources try { if (rs != null) { rs.close(); } if (pstmt != null) { pstmt.close(); } if (conn != null) { conn.close(); } } catch (Exception ignore) {} } %>