====== 문자메시지(SMS) 서비스 ====== ===== 개요 ===== 문자메시지(SMS) 서비스는 전자정부 SMS 서비스(모바일 전자정부 M-Gov)를 이용하기 위한 문자메시지 전송 인터페이스를 제공하며 별도의 M-Gov 신청을 통해 사용할 수 있다. 이 문자메시지(SMS) 서비스는 기존 기존 전자정부 표준프레임워크 및 공통컴포넌트의 공통 부분을 활용하고 있는 **문자메시지서비스**를 보다 쉽게 활용할 수 있도록 프레임워크 및 기타 공통모듈의 사용을 제외시켜 놓은 것이다. 전자정부 표준프레임워크가 적용된 경우는 [[egovframework:com:v2:cop:문자메시지서비스]] 부분을 적용하면 된다. ===== 전제조건 ===== 문자메시지서비스를 사용하기 위해서는 별도로 전자정부 SMS 서비스(모바일 전자정부 M-Gov)를 신청하여야 하며, 이는 행정안전부 정보통합전산센터에서 주관하고 있다. 서비스 신청 절차는 다음과 같다. ① 서비스이용신청 : 서비스 종류에 따라 별지 1호 내지 3호 서식(해당 사이트 이용규정 참조)의 이용신청서를 센터에 제출 \\ ② 이용통보 : 검토 결과를 접수일로부터 15일 이내에 이용신청기관에게 서면으로 통보 \\ ③ 서비스준비 : 이용신청기관은 센터에서 제공하는 "M-Gov 연동 API"를 사용하여 연동 \\ ④ 서비스개통 : 이용신청기관은 승인 후 60일 이내에 서비스 개통을 하지 않을 경우 센터는 이용통보를 취소할 수 있음 \\ 기타 자세한 정보 확인 및 문의는 모바일 전자정부 M-gov(http://www.mgov.go.kr)를 참고한다. ===== 설명 ===== 문자메시지(SMS) 서비스는 "M-Gov 연동 API"를 통해 SMS서비스를 제공할 뿐만 아니라 전송에 대한 이력 관리를 제공한다. (이력 관리가 필요없는 경우를 위해 별도의 메소드를 제공하고 있으나 송신 결과에 대한 내용을 확인할 수 없음) ==== 패키지 참조 관계 ==== 문자메시지서비스 패키지는 요소기술의 공통(cmm) 패키지에 대해서만 직접적인 함수적 참조 관계를 가진다. 하지만, 컴포넌트 배포 시 오류 없이 실행되기 위하여 패키지 간의 참조관계에 따라 포맷/날짜/계산 패키지와 함께 배포 파일을 구성한다. * 패키지 간 참조 관계 : [[egovframework:com:v2:init_pkg_dependency#게시판, 커뮤니티, 동호회|협업-게시판, 커뮤니티, 동호회 Package Dependency]] ==== 관련소스 ==== ^유형^대상소스^비고^공용여부^ |Service|egovframework.com.cop.sms.service.EgovSmsInfoService.java|문자메시지서비스를 위한 서비스 인터페이스| Y | |ServiceImpl|egovframework.com.cop.sms.service.impl.EgovSmsBasicServiceImpl.java|문자메시지서비스를 위한 서비스 구현 클래스| | |ServiceImpl|egovframework.com.cop.sms.service.impl.EgovSmsInfoSender.java|문자메시지 연동 처리를 위한 클래스| Y | |ServiceImpl|egovframework.com.cop.sms.service.impl.EgovSmsBasicReceiver.java|문자메시지 연동 결과 수신 처리를 위한 클래스| | |Model|egovframework.com.cop.sms.service.Sms.java|문자메시지서비스를 위한 모델 클래스| Y | |Model|egovframework.com.cop.sms.service.SmsRecptn.java|문자메시지서비스를 위한 모델 클래스 (수신정보)| Y | |VO|egovframework.com.cop.sms.service.SmsVO.java|문자메시지서비스를 위한 VO 클래스| Y | |VO|egovframework.com.cop.sms.service.SmsConnection.java|문자메시지서비스를 위한 모델 클래스 (연결정보)| Y | |DAO|egovframework.com.cop.sms.service.impl.SmsBasicDAO.java|문자메시지서비스를 위한 데이터처리 클래스| | |Util|egovframework.com.cop.sms.service.impl.SmsBasicDBUtil.java|데이터처리 Util (Pool 생성 등)| | ※ 공용여부는 기존 전자정부 표준프레임워크를 활용하는 [[egovframework:com:v2:cop:문자메시지서비스]] 와 공통적으로 사용하는 클래스를 나타냄 ==== 관련 클래스 다이어그램 ==== {{:egovframework:com:v2:cop:cdd_문자메시지_프레임워크미적용.jpg?740|}} ==== 관련테이블 ==== ^테이블명^테이블명(영문)^비고^ |문자메시지|COMTNSMS|문자메시지 전송 정보를 관리한다.| |문자메시지수신|COMTNSMSRECPTN|문자메시지 수신 정보를 관리한다.| ==== 환경설정 ==== * SMEConfig.properties 파일 처리 본 문자메시지서비스를 사용하기 위해서는 "M-Gov 연동 API"에서 제공하는 "SMEConfig.properties" 파일을 지정되어야 한다. 지정해야 할 부분은 **egovframework.com.cop.sms.service.impl.EgovSmsBasicServiceImpl** 부분으로 다음 생성자(public EgovSmsBasicServiceImpl())를 확인한다. public class EgovSmsBasicServiceImpl implements EgovSmsInfoService { ... public EgovSmsBasicServiceImpl() { //-------------------------------- // 속성 정보 얻기 // M-Gov에서 배포하는 SMEConfig.conf 파일을 절대경로로 지정하면 된다. //-------------------------------- //smeConfigPath = EgovProperties.getProperty("Globals.SMEConfigPath"); // ... String globalsPropertiesFile = System.getProperty("user.home") + System.getProperty("file.separator") + "egovProps" + System.getProperty("file.separator") + "conf" + System.getProperty("file.separator") + "SMEConfig.properties"; smeConfigPath = globalsPropertiesFile; } ... 위 부분에서 globalsPropertiesFile 변수에 SMEConfig.properties 파일에 대한 위치를 지정하여 사용한다. * SMEConfig.properties 처리 방식 변경 또는 다음과 같이 직접 smeConfigPath에 SMEConfig.properties 파일 위치를 지정하도록 변경할 수 있다. 가장 간단하지만.. 향후 해당 파일 위치변경 등의 경우에 소스를 직접 수정해야 되는 문제가 있다. (프로젝트 공통모듈에 속성에 대한 처리가 있다면.. 프로젝트의 속성처리 공통모듈로 처리되도록 변경할 것을 권장) public class EgovSmsBasicServiceImpl implements EgovSmsInfoService { ... public EgovSmsBasicServiceImpl() { //-------------------------------- // 속성 정보 얻기 // M-Gov에서 배포하는 SMEConfig.conf 파일을 절대경로로 지정하면 된다. //-------------------------------- smeConfigPath = "/product/jeus/egovProps/conf/SMEConfig.properties"; } ... ※ 위의 경우 단순하게 smeConfigPath에 SMEConfig.properties 파일에 대한 절대 경로만 지정하면 됨 참고로 SMEConfig.properties는 모바일 전자정부 M-Gov에서 제공하는 파일로 M-Gov 센터 정보 및 계정정보 등을 포함한다. === DBMS 정보 변경 === 프레임워크의 종속성을 배제하기 위하여 DBMS에 대한 처리도 독립적으로 제공한다. 현재는 **egovframework.com.cop.sms.impl.SmsBasicDBUtil** 부분에서 DBCP(http://commons.apache.org/dbcp/)를 통한 Connection Pool을 생성하여 처리한다. 관련되어 다음과 같은 DBMS 정보를 변경하면 된다. (또는 프로젝트에서 DB Connection과 관련된 공통모듈이 있으면.. 해당 모듈로 변경함) public class SmsBasicDBUtil { ... /** Connection Pool Alias */ private static final String JDBC_ALIAS = "default"; /** JDBC Driver 명 */ private static final String JDBC_DRIVER = "org.gjt.mm.mysql.Driver"; /** JDBC 접속 URL */ private static final String JDBC_URL = "jdbc:mysql://192.168.200.24:1621/com"; /** JDBC 접속 사용자ID */ private static final String JDBC_USER = "user"; /** JDBC 접속 패스워드 */ private static final String JDBC_PASSWORD = "password"; /** 한번에 pool에서 갖다 쓸 수 있는 최대 커넥션 개수 */ private static final int MAX_ACTIVE = 20; /** 사용되지 않고 pool에 저정될 수 있는 최대 커넥션 개수 */ private static final int MAX_IDLE = 5; /** 커넥션 timeout */ private static final int MAX_WAIT = 20000; /** auto commit 여부 */ private static final boolean DEFAULT_AUTOCOMMIT = true; /** read only 여부 */ private static final boolean DEFAULT_READONLY = false; ... 위 부분의 기존 DBMS 설정에 맞게 수정하여 사용한다. 추가적으로 **egovframework.com.cop.sms.service.impl.SmsBasicDAO**에서는 DBMS에 대한 query가 지정되어 있는데.. 현재는 mySql 기준으로 제공되고 있다. 이 부분도 Oracle인 경우 "for Oracle"로 주석처리된 부분을 사용하면 된다. (altibase, cubrid, tibero는 oracle과 동일) public String insertSmsInf(Sms sms) throws Exception { String smsId = null; //variables Connection conn = null; PreparedStatement pstmt = null; StringBuffer buffer = new StringBuffer(); try { // for mySql buffer.append("INSERT INTO COMTNSMS\n"); buffer.append(" (SMS_ID, TRNSMIT_TELNO, TRNSMIT_CN,\n"); buffer.append(" FRST_REGISTER_ID, FRST_REGISTER_PNTTM )\n"); buffer.append("VALUES\n"); buffer.append("(?, ?, ?, ?, SYSDATE())"); // for Oracle /* buffer.append("INSERT INTO COMTNSMS\n"); buffer.append(" (SMS_ID, TRNSMIT_TELNO, TRNSMIT_CN,\n"); buffer.append(" FRST_REGISTER_ID, FRST_REGISTER_PNTTM )\n"); buffer.append("VALUES\n"); buffer.append("(?, ?, ?, ?, SYSDATE)"); */ conn = SmsBasicDBUtil.getConnection(); conn.setAutoCommit(false); smsId = getNextId(conn); // SMS_ID 생성... pstmt = conn.prepareStatement(buffer.toString()); int index = 0; pstmt.setString(++index, smsId); pstmt.setString(++index, sms.getTrnsmitTelno()); pstmt.setString(++index, sms.getTrnsmitCn()); pstmt.setString(++index, sms.getFrstRegisterId()); pstmt.executeUpdate(); conn.commit(); return smsId; } catch (Exception ex) { if (conn != null) { conn.rollback(); } throw ex; } finally { SmsBasicDBUtil.close(null, pstmt, conn); } } === 전송결과 수신 daemon 실행 === 전송에 대한 결과는 별도의 프로그램을 통해 반영된다. (M-Gov 제공 API가 비동기식으로 수신을 별도로 처리하도록 되어 있음) 실행대상은 **egovframework.com.cop.sms.service.impl.EgovSmsBasicReceiver**으로 다음과 같이 실행시킨다. java [JVM Options] egovframework.com.cop.sms.service.impl.EgovSmsBasicReceiver /home/egovframe/conf/SMEConfig.conf JVM Options는 classpath 등이 지정되어야 하고 뒤 파라미터 부분은 SMEConfig.properties(또는 SMEConfig.conf)의 절대경로를 지정하여 실행한다. Unix의 경우는 "&" 뒤 부분에 추가하므로써 백그라운드로 실행할 수 있다. ===== 관련기능 ===== SMS서비스는 **문자메시지 전송**, **문자메시지 목록조회**, **문자메시지 상세조회** 기능으로 구분되어 있다. ==== 문자메시지 전송 ==== === 비즈니스 규칙 === 문자메시지 전송은 다음 인테페이스 메소드를 호출한다. === 관려코드 === N/A === 관련화면 및 수행메뉴얼 === (Implement 객체는 EgovSmsBasicServiceImpl를 사용) ^Interface^return^method^parameters^비고^ |EgovSmsInfoService|void|insertSmsInf|Sms| | * 사용 예 EgovSmsInfoService service = new EgovSmsBasicServiceImpl(); ... Sms sms = new Sms(); sms.setTrnsmitTelno("010-1234-5678"); sms.setTrnsmitCn("전송내용"); sms.setFrstRegisterId("USRCNFRM_00000000001"); sms.setRecptnTelno( new String[] { "010-1234-1234", "010-1234-1235" } ); service.insertSmsInf(sms); ... recptnTelno는 String[]로 동시에 여러 명에게 같은 내용을 전송할 수 있다. ==== 문자메시지 목록조회 ==== === 비즈니스 규칙 === 문자메시지 목록조회는 다음 인테페이스 메소드를 호출한다. === 관려코드 === N/A === 관련화면 및 수행메뉴얼 === (Implement 객체는 EgovSmsBasicServiceImpl를 사용) ^Interface^return^method^parameters^비고^ |EgovSmsInfoService|Map|selectSmsInfs|SmsVO| | * 사용 예 EgovSmsInfoService service = new EgovSmsBasicServiceImpl(); ... searchVO.setUniqId("USRCNFRM_00000000001"); searchVO.setRecordCountPerPage(10); // 페이지당 레코드 개수 searchVO.setFirstIndex(0); // 페이징 시작 ROW 지정 // 현재 페이지 번호에 따른 계산 방법 // currentPageNo = 현재 페이지 번호 (1부터 시작) // recordCountPerPage = 한 페이지당 레코드 건수 // firstRecordIndex = (currentPageNo - 1) * recordCountPerPage Map map = service.selectSmsInfs(searchVO); System.out.println("List action is successed..."); System.out.println("Total result list count : " + (String)map.get("resultCnt")); System.out.println("List count : " + ((List)map.get("resultList")).size()); ... 추가적인 조건으로 "수신전화번호", "전송내용"을 사용할 수 있다. * 수신전화번호 지정 searchVO.setSearchCnd(0); searchVO.setSearchWrd("1234"); * 전송내용 지정 searchVO.setSearchCnd(1); searchVO.setSearchWrd("확인"); ==== 문자메시지 상세조회 ==== === 비즈니스 규칙 === 문자메시지 상세조회는 다음 인테페이스 메소드를 호출한다. === 관려코드 === N/A === 관련화면 및 수행메뉴얼 === (Implement 객체는 EgovSmsBasicServiceImpl를 사용) ^Interface^return^method^parameters^비고^ |EgovSmsInfoService|SmsVO|selectSmsInf|SmsVO| | * 사용 예 SmsVO vo = new SmsVO(); vo.setSmsId("SMSID_00000000000001"); SmsVO detail = service.selectSmsInf(vo); System.out.println("Detail action is successed..."); System.out.println("Transmit tel. : " + detail.getTrnsmitTelno()); System.out.println("Transmit contents : " + detail.getTrnsmitCn()); System.out.println("First Reg. ID : " + detail.getFrstRegisterId()); System.out.println("First Reg. Name : " + detail.getFrstRegisterNm()); System.out.println("First Reg. Time : " + detail.getFrstRegisterPnttm()); System.out.println("Receive : "); List list = detail.getRecptn(); for (SmsRecptn recptn : list) { System.out.println("\tTel. : " + recptn.getRecptnTelno()); System.out.println("\tResult Code : " + recptn.getResultCode()); System.out.println("\tResult msg. : " + recptn.getResultMssage()); } ... 수신전화번호에 대한 내용은 List으로 얻어 위에서 처럼 처리된다.