2022년 11월 16일 수요일

네이버 ncloud SENS (Simple & Easy Notification Service) jsp로 SMS 전송 개발

어쩌다 보니 2부가 된

네이버 ncloud SENS (Simple & Easy Notification Service) 로 문자 전송

대망의 JSP 편!!

할말이 없으니 바로 소스

앞선 글에서 귀찮아서 안 적었는데 혹시 모르니..

일단 사용하고 있는 라이브러리 인증샷!


하일라이트는 아무 의미 없는 것이다!!

gson은 다른 서비스 개발하느라 쓰는 중이고.. 

문자 때문에 추가한 라이브러리는 하단의 4개

json-20220924.jar
json-simple-1.1.1.jar
security~~~~~.jar 
server-1.0~~~~~.jar

json 라이브러리는 구글링 하면 나오고.. 밑에 2개는 네이버에서 제공하는 SDK임..


위에 들어가서 Server와 Security 만 받으면 됨.

자 이제 진짜 소스!!

  1. <%@ include file="내가 만든 개발 환경 설정용 코드.jsp" %>
  2. <%@page import = "java.io.BufferedReader" %>
  3. <%@page import = "java.io.DataOutputStream" %>
  4. <%@page import = "java.io.InputStreamReader" %>
  5. <%@page import = "java.io.PrintWriter" %>
  6. <%@page import = "java.io.UnsupportedEncodingException" %>
  7. <%@page import = "java.net.HttpURLConnection" %>
  8. <%@page import = "java.net.URL" %>
  9. <%@page import = "java.net.HttpURLConnection" %>
  10. <%@page import = "java.security.InvalidKeyException" %>
  11. <%@page import = "java.security.NoSuchAlgorithmException" %>
  12. <%@page import = "java.util.Base64" %>
  13. <%@page import = "org.json.JSONArray" %>
  14. <%@page import = "org.json.JSONException" %>
  15. <%@page import = "org.json.JSONObject" %>
  16. <%@page import = "javax.crypto.Mac" %>
  17. <%@page import = "javax.crypto.spec.SecretKeySpec" %>
  18. <%!
  19. //jsp는 final static 선언이 안되서 이렇게 따로 선언부를 두고 써야 함.
  20. String idx = "";
  21. String tgt = "";
  22. String msgbody = "";
  23. String title = "";
  24. String msgImgPath = "";
  25. String host = "첨부파일 앞에 붙일 host 주소";
  26. %>
  27. <%
  28. idx = request.getParameter("idx")==null ? "" : request.getParameter("idx");
  29. tgt = request.getParameter("tgt")==null ? "" : request.getParameter("tgt");
  30. msgbody = request.getParameter("msgbody")==null ? "" : request.getParameter("msgbody");
  31. title = request.getParameter("title")==null ? "" : request.getParameter("title");
  32.  
  33. Class.forName("org.mariadb.jdbc.Driver");
  34. Connection conn = DriverManager.getConnection(dbURL, dbID, dbPassword);
  35. PreparedStatement pstmt = null;
  36. ResultSet rs = null;
  37.  
  38. String sql = "첨부링크로 보낼 파일 경로를 가져오는 쿼리가 있었음";
  39.  
  40. try {
  41.     pstmt = conn.prepareStatement(sql);
  42.     rs = pstmt.executeQuery();
  43.    
  44.     if(rs.next()) {
  45.         msgImgPath = rs.getString("filepath");
  46.         sendSMS();
  47.     }  
  48.     rs.close();
  49.     pstmt.close();
  50. } catch (Exception e) {
  51.     e.printStackTrace();
  52. }
  53.  
  54. %>
  55. <%!
  56. // https://api.ncloud-docs.com/docs/common-ncpapi
  57. public String makeSignature(String url, String timestamp, String method, String accessKey, String secretKey) throws NoSuchAlgorithmExceptionInvalidKeyException {
  58.     String space = " ";                    // one space
  59.     String newLine = "\n";                 // new line
  60.     String message = new StringBuilder()
  61.         .append(method)
  62.         .append(space)
  63.         .append(url)
  64.         .append(newLine)
  65.         .append(timestamp)
  66.         .append(newLine)
  67.         .append(accessKey)
  68.         .toString();
  69.    
  70.     SecretKeySpec signingKey;
  71.     String encodeBase64String;
  72.     try {
  73.        
  74.         signingKey = new SecretKeySpec(secretKey.getBytes("UTF-8")"HmacSHA256");
  75.         Mac mac = Mac.getInstance("HmacSHA256");
  76.         mac.init(signingKey);
  77.         byte[] rawHmac = mac.doFinal(message.getBytes("UTF-8"));
  78.         encodeBase64String = Base64.getEncoder().encodeToString(rawHmac);
  79.     } catch (UnsupportedEncodingException e) {
  80.         // TODO Auto-generated catch block
  81.         encodeBase64String = e.toString();
  82.     }
  83.    
  84.  
  85.   return encodeBase64String;
  86. }
  87.  
  88. private void sendSMS() {
  89.    
  90.     String ACCECSS_KEY = "네이버 API 키";
  91.     String SMS_SERVICEID = "SMS SERVICE ID 넣으셈";
  92.     String API_SECRECT_KEY = "네이버 API 키의 SECRECT KEY";
  93.     String hostNameUrl = "https://sens.apigw.ntruss.com";           // 호스트 URL
  94.     String requestUrl= "/sms/v2/services/";                         // 요청 URL
  95.     String requestUrlType = "/messages";                            // 요청 URL
  96.     String accessKey = ACCECSS_KEY;                         // 네이버 클라우드 플랫폼 회원에게 발급되는 개인 인증키          // Access Key : https://www.ncloud.com/mypage/manage/info > 인증키 관리 > Access Key ID
  97.     String secretKey = API_SECRECT_KEY;  // API 개인 인증키의 secret key  // Service Key : https://www.ncloud.com/mypage/manage/info > 인증키 관리 > Access Key ID  
  98.     String serviceId = SMS_SERVICEID;       // 프로젝트에 할당된 SMS 서비스 ID                           // service ID : https://console.ncloud.com/sens/project > Simple & ... > Project > 서비스 ID
  99.     String method = "POST";                                         // 요청 method
  100.     String timestamp = Long.toString(System.currentTimeMillis());   // current timestamp (epoch)
  101.     requestUrl += serviceId + requestUrlType;
  102.     String apiUrl = hostNameUrl + requestUrl;
  103.     System.out.println(apiUrl);
  104.     // JSON 을 활용한 body data 생성
  105.     JSONObject bodyJson = new JSONObject();
  106.     JSONObject toJson = new JSONObject();
  107.     JSONArray  toArr = new JSONArray();
  108.  
  109.     toJson.put("subject",title);                            // Optional, messages.subject   개별 메시지 제목, LMS, MMS에서만 사용 가능
  110.     //toJson.put("content","sms test in spring 111");   // Optional, messages.content   개별 메시지 내용, SMS: 최대 80byte, LMS, MMS: 최대 2000byte
  111.     toJson.put("to",tgt);                       // Mandatory(필수), messages.to   수신번호, -를 제외한 숫자만 입력 가능
  112.     toArr.put(toJson);
  113.    
  114.     bodyJson.put("type","LMS");                         // Madantory, 메시지 Type (SMS | LMS | MMS), (소문자 가능)
  115.     //bodyJson.put("contentType","");                   // Optional, 메시지 내용 Type (AD | COMM) * AD: 광고용, COMM: 일반용 (default: COMM) * 광고용 메시지 발송 시 불법 스팸 방지를 위한 정보통신망법 (제 50조)가 적용됩니다.
  116.     //bodyJson.put("countryCode","82");                 // Optional, 국가 전화번호, (default: 82)
  117.     bodyJson.put("from","보내는 번호");                    // Mandatory, 발신번호, 사전 등록된 발신번호만 사용 가능     
  118.     //bodyJson.put("subject","");                       // Optional, 기본 메시지 제목, LMS, MMS에서만 사용 가능
  119.     bodyJson.put("content",msgbody + "\n" + host + msgImgPath)// Mandatory(필수), 기본 메시지 내용, SMS: 최대 80byte, LMS, MMS: 최대 2000byte
  120.     bodyJson.put("messages", toArr);                    // Mandatory(필수), 아래 항목들 참조 (messages.XXX), 최대 1,000개
  121.    
  122.     //String body = bodyJson.toJSONString();
  123.     String body = bodyJson.toString();
  124.    
  125.     //System.out.println(body);
  126.     try {
  127.         URL url = new URL(apiUrl);
  128.  
  129.         HttpURLConnection con = (HttpURLConnection)url.openConnection();
  130.         con.setUseCaches(false);
  131.         con.setDoOutput(true);
  132.         con.setDoInput(true);
  133.         con.setRequestProperty("content-type""application/json");
  134.         con.setRequestProperty("x-ncp-apigw-timestamp", timestamp);
  135.         con.setRequestProperty("x-ncp-iam-access-key", accessKey);
  136.         con.setRequestProperty("x-ncp-apigw-signature-v2", makeSignature(requestUrl, timestamp, method, accessKey, secretKey));
  137.         con.setRequestMethod(method);
  138.         con.setDoOutput(true);
  139.         DataOutputStream wr = new DataOutputStream(con.getOutputStream());
  140.        
  141.         wr.write(body.getBytes());
  142.         wr.flush();
  143.         wr.close();
  144.  
  145.         int responseCode = con.getResponseCode();
  146.         BufferedReader br;
  147.         System.out.println("responseCode" +" " + responseCode);
  148.         if(responseCode == 202) { // 정상 호출
  149.             br = new BufferedReader(new InputStreamReader(con.getInputStream()));
  150.         } else { // 에러 발생
  151.             br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
  152.         }
  153.  
  154.         String inputLine;
  155.         StringBuffer response = new StringBuffer();
  156.         while ((inputLine = br.readLine()) != null) {
  157.             response.append(inputLine);
  158.         }
  159.         br.close();
  160.        
  161.         //System.out.println(response.toString());
  162.         //out.println(tgt);
  163.         //out.println(response.toString());
  164.  
  165.     } catch (Exception e) {
  166.         System.out.println(e);
  167.         //out.print(e.getMessage());
  168.         e.printStackTrace();
  169.     }
  170. }
  171. %>

개발한 것은.. 뭐 입력 폼에서 POST로 제목, 내용 등을 POST로 넘겨서

처리한 것으로 jsp 는 final static 이 선언이 안되서 

<%! %> 이 선언부에 일단 변수를 선언하고

값을 받아서 할당하는 식으로 처리했음..

JAVA랑 미묘하게 다른 부분이 있어서 헷갈리는 삐약이들을 위해 소스 공개함..

다시 한번 말하지만... 남에게 뭔가를 공개하려면 

그 공개하면서 시간들이는 노고는 알지만.. 그래도 좀 확인은 하고 공개합시다..

잘못된 정보로 그걸 보고 하는 사람은 수많은 시행착오를 겪게 된다오..

자... 그럼.. 끗!!



댓글 없음:

댓글 쓰기

BE Band (비밴드) - 2024년 03월 02일 잠실새내 락앤롤욱스 공연

나의 10~20대를 보낸 잠실에서의 공연.. 오랜만에 가보니.. 여기가.. 마눌님과 자주 가던 영화관이었는데... 여긴 뭐가 있었는데... 란 추억도 떠올리며 기분좋게 감.​ 공연장은 좀 협소한 편이었고, 인천의 쥐똥나무 보다는 약간 크고... 인천 ...