KyungHwan's etc.

Java로 카카오 REST API 호출 샘플 코드 본문

Java

Java로 카카오 REST API 호출 샘플 코드

KyungHwan_0 2018. 10. 2. 21:38

Java로 카카오 REST API 호출 샘플 코드

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
//import com.google.gson.Gson;

public class KakaoRestApiHelper {

   public enum HttpMethodType { POST, GET, DELETE }

   private static final String API_SERVER_HOST  = "https://kapi.kakao.com";

   private static final String USER_SIGNUP_PATH = "/v1/user/signup";
   private static final String USER_UNLINK_PATH = "/v1/user/unlink";
   private static final String USER_LOGOUT_PATH = "/v1/user/logout";
   private static final String USER_ME_PATH = "/v1/user/me";
   private static final String USER_UPDATE_PROFILE_PATH = "/v1/user/update_profile";
   private static final String USER_IDS_PATH = "/v1/user/ids";

   private static final String STORY_PROFILE_PATH = "/v1/api/story/profile";
   private static final String STORY_ISSTORYUSER_PATH = "/v1/api/story/isstoryuser";
   private static final String STORY_MYSTORIES_PATH = "/v1/api/story/mystories";
   private static final String STORY_MYSTORY_PATH = "/v1/api/story/mystory";
   private static final String STORY_DELETE_MYSTORY_PATH = "/v1/api/story/delete/mystory";
   private static final String STORY_POST_NOTE_PATH = "/v1/api/story/post/note";
   private static final String STORY_UPLOAD_MULTI_PATH = "/v1/api/story/upload/multi";
   private static final String STORY_POST_PHOTO_PATH = "/v1/api/story/post/photo";
   private static final String STORY_LINKINFO_PATH = "/v1/api/story/linkinfo";
   private static final String STORY_POST_LINK_PATH = "/v1/api/story/post/link";

   private static final String TALK_PROFILE_PATH = "/v1/api/talk/profile";

   private static final String PUSH_REGISTER_PATH = "/v1/push/register";
   private static final String PUSH_TOKENS_PATH = "/v1/push/tokens";
   private static final String PUSH_DEREGISTER_PATH = "/v1/push/deregister";
   private static final String PUSH_SEND_PATH = "/v1/push/send";

   private static final ObjectMapper JACKSON_OBJECT_MAPPER = new ObjectMapper();
   //private static final Gson GSON = new Gson();
   private static final String PROPERTIES_PARAM_NAME = "properties";

   private static final List<String> adminApiPaths = new ArrayList<String>();

   static {
       adminApiPaths.add(USER_IDS_PATH);
       adminApiPaths.add(PUSH_REGISTER_PATH);
       adminApiPaths.add(PUSH_TOKENS_PATH);
       adminApiPaths.add(PUSH_DEREGISTER_PATH);
       adminApiPaths.add(PUSH_SEND_PATH);
  }

   private String accessToken;
   private String adminKey;

   public void setAccessToken(final String accessToken) {
       this.accessToken = accessToken;
  }

   public void setAdminKey(final String adminKey) {
       this.adminKey = adminKey;
  }

   ///////////////////////////////////////////////////////////////
   // User Management
   ///////////////////////////////////////////////////////////////

   public String signup() {
       return request(HttpMethodType.POST, USER_SIGNUP_PATH);
  }

   public String signup(final Map<String, String> params) {
       return request(HttpMethodType.POST, USER_SIGNUP_PATH, PROPERTIES_PARAM_NAME + "=" + mapToJsonStr(params));
  }

   public String unlink() {
       return request(HttpMethodType.POST, USER_UNLINK_PATH);
  }

   public String logout() {
       return request(HttpMethodType.POST, USER_LOGOUT_PATH);
  }

   public String me() {
       return request(USER_ME_PATH);
  }

   public String updatProfile(final Map<String, String> params) {
       return request(HttpMethodType.POST, USER_UPDATE_PROFILE_PATH, PROPERTIES_PARAM_NAME + "=" + mapToJsonStr(params));
  }

   public String getUserIds() {
       return request(USER_IDS_PATH);
  }

   public String getUserIds(final Map<String, String> params) {
       return request(HttpMethodType.GET, USER_IDS_PATH, mapToParams(params));
  }

   ///////////////////////////////////////////////////////////////
   // Kakao Story
   ///////////////////////////////////////////////////////////////

   public String isStoryUser() {
       return request(STORY_ISSTORYUSER_PATH);
  }

   public String storyProfile() {
       return request(STORY_PROFILE_PATH);
  }

   public String postNote(final Map<String, String> params) {
       return request(HttpMethodType.POST, STORY_POST_NOTE_PATH, mapToParams(params));
  }

   public String postLink(final Map<String, String> params) {
       return request(HttpMethodType.POST, STORY_POST_LINK_PATH, mapToParams(params));
  }

   public String postPhoto(final Map<String, String> params) {
       return request(HttpMethodType.POST, STORY_POST_PHOTO_PATH, mapToParams(params));
  }

   public String getMyStory(final Map<String, String> params) {
       return request(HttpMethodType.GET, STORY_MYSTORY_PATH, mapToParams(params));
  }

   public String getMyStories() {
       return request(STORY_MYSTORIES_PATH);
  }

   public String getMyStories(final Map<String, String> params) {
       return request(HttpMethodType.GET, STORY_MYSTORIES_PATH, mapToParams(params));
  }

   public String deleteMyStory(final String id) {
       return request(HttpMethodType.DELETE, STORY_DELETE_MYSTORY_PATH, "?id=" + id);
  }

   public String deleteMyStory(final Map<String, String> params) {
       return request(HttpMethodType.DELETE, STORY_DELETE_MYSTORY_PATH, mapToParams(params));
  }

   public String getLinkInfo(String url) {
       return request(HttpMethodType.GET, STORY_LINKINFO_PATH, "?url=" + url);
  }

   public String uploadMulti(File[] files) {

       if (files.length == 0)
           return null;

       String CRLF = "\r\n";
       String TWO_HYPHENS = "--";
       String BOUNDARY = "---------------------------012345678901234567890123456";
       HttpsURLConnection conn = null;
       DataOutputStream dos = null;
       FileInputStream fis = null;

       int bytesRead, bytesAvailable, bufferSize;
       byte[] buffer;
       int maxBufferSize = 1 * 1024 * 1024;

       // Request
       try {
           URL url = new URL(API_SERVER_HOST + STORY_UPLOAD_MULTI_PATH);
           conn = (HttpsURLConnection) url.openConnection();
           conn.setDoInput(true);
           conn.setDoOutput(true);
           conn.setUseCaches(false);
           conn.setRequestMethod("POST");
           conn.setRequestProperty("Connection", "Keep-Alive");
           conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + BOUNDARY);
           conn.setRequestProperty("Authorization", "Bearer " + accessToken);
           conn.setRequestProperty("Cache-Control", "no-cache");

           dos = new DataOutputStream(conn.getOutputStream());

           for (File f : files) {
               dos.writeBytes(TWO_HYPHENS + BOUNDARY + CRLF);
               dos.writeBytes("Content-Disposition: form-data; name=\"file\";" + " filename=\"" + f.getName() + "\"" + CRLF);
               dos.writeBytes(CRLF);
               fis = new FileInputStream(f);
               bytesAvailable = fis.available();
               bufferSize = Math.min(bytesAvailable, maxBufferSize);
               buffer = new byte[bufferSize];
               bytesRead = fis.read(buffer, 0, bufferSize);
               while (bytesRead > 0) {
                   dos.write(buffer, 0, bufferSize);
                   bytesAvailable = fis.available();
                   bufferSize = Math.min(bytesAvailable, maxBufferSize);
                   bytesRead = fis.read(buffer, 0, bufferSize);
              }
               dos.writeBytes(CRLF);
          }

           // finish delimiter
           dos.writeBytes(TWO_HYPHENS + BOUNDARY + TWO_HYPHENS + CRLF);

           fis.close();
           dos.flush();
           dos.close();

      } catch (MalformedURLException ex) {
           ex.printStackTrace();
      } catch (IOException ioe) {
           ioe.printStackTrace();
      } finally {
           if (dos != null) try { dos.close(); } catch (IOException ignore) {}
           if (fis != null) try { fis.close(); } catch (IOException ignore) {} }

       // Response
       InputStream inputStream = null;
       BufferedReader reader = null;
       try {
           inputStream = new BufferedInputStream(conn.getInputStream());
           reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
           String line;
           StringBuilder builder = new StringBuilder();
           while ((line = reader.readLine()) != null) {
               builder.append(line).append("\n");
          }
           reader.close();
           return builder.toString();
      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           if (reader != null) {
               try { reader.close(); } catch (IOException ignore) {}
          }
           if (inputStream != null) {
               try { inputStream.close(); } catch (IOException ignore) {}
          }
           conn.disconnect();
      }

       return null;
  }

   ///////////////////////////////////////////////////////////////
   // Kakao Talk
   ///////////////////////////////////////////////////////////////

   public String talkProfile() {
       return request(TALK_PROFILE_PATH);
  }

   ///////////////////////////////////////////////////////////////
   // Push Notification
   ///////////////////////////////////////////////////////////////

   public String registerPush(final Map<String, String> params) {
       return request(HttpMethodType.POST, PUSH_REGISTER_PATH, mapToParams(params));
  }

   public String getPushTokens(final Map<String, String> params) {
       return request(HttpMethodType.GET, PUSH_TOKENS_PATH, mapToParams(params));
  }

   public String deregisterPush(final Map<String, String> params) {
       return request(HttpMethodType.POST, PUSH_DEREGISTER_PATH, mapToParams(params));
  }

   public String sendPush(final Map<String, String> params) {
       return request(HttpMethodType.POST, PUSH_SEND_PATH, mapToParams(params));
  }

   public String request(final String apiPath) {
       return request(HttpMethodType.GET, apiPath, null);
  }

   public String request(final HttpMethodType httpMethod, final String apiPath) {
       return request(httpMethod, apiPath, null);
  }

   public String request(HttpMethodType httpMethod, final String apiPath, final String params) {

       String requestUrl = API_SERVER_HOST + apiPath;
       if (httpMethod == null) {
           httpMethod = HttpMethodType.GET;
      }
       if (params != null && params.length() > 0
               && (httpMethod == HttpMethodType.GET || httpMethod == HttpMethodType.DELETE)) {
           requestUrl += params;
      }

       HttpsURLConnection conn;
       OutputStreamWriter writer = null;
       BufferedReader reader = null;
       InputStreamReader isr = null;

       try {
           final URL url = new URL(requestUrl);
           conn = (HttpsURLConnection) url.openConnection();
           conn.setRequestMethod(httpMethod.toString());

           if (adminApiPaths.contains(apiPath)) {
               conn.setRequestProperty("Authorization", "KakaoAK " + this.adminKey);
          } else {
               conn.setRequestProperty("Authorization", "Bearer " + this.accessToken);
          }

           conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
           conn.setRequestProperty("charset", "utf-8");

           if (params != null && params.length() > 0 && httpMethod == HttpMethodType.POST) {
               conn.setDoOutput(true);
               writer = new OutputStreamWriter(conn.getOutputStream());
               writer.write(params);
               writer.flush();
          }

           final int responseCode = conn.getResponseCode();
           System.out.println(String.format("\nSending '%s' request to URL : %s", httpMethod, requestUrl));
           System.out.println("Response Code : " + responseCode);
           if (responseCode == 200)
               isr = new InputStreamReader(conn.getInputStream());
           else
               isr = new InputStreamReader(conn.getErrorStream());

           reader = new BufferedReader(isr);
           final StringBuffer buffer = new StringBuffer();
           String line;
           while ((line = reader.readLine()) != null) {
               buffer.append(line);
          }
           System.out.println(buffer.toString());
           return buffer.toString();

      } catch (IOException e) {
           e.printStackTrace();
      } finally {
           if (writer != null) try { writer.close(); } catch (Exception ignore) { }
           if (reader != null) try { reader.close(); } catch (Exception ignore) { }
           if (isr != null) try { isr.close(); } catch (Exception ignore) { }
      }

       return null;
  }

   public String urlEncodeUTF8(String s) {
       try {
           return URLEncoder.encode(s, "UTF-8");
      } catch (UnsupportedEncodingException e) {
           throw new UnsupportedOperationException(e);
      }
  }

   public String mapToParams(Map<String, String > map) {
       StringBuilder paramBuilder = new StringBuilder();
       for (String key : map.keySet()) {
           paramBuilder.append(paramBuilder.length() > 0 ? "&" : "");
           paramBuilder.append(String.format("%s=%s", urlEncodeUTF8(key),
                   urlEncodeUTF8(map.get(key).toString())));
      }
       return paramBuilder.toString();
  }

   public String mapToJsonStr(Map<String, String > map) {
       return JACKSON_OBJECT_MAPPER.writeValueAsString(map);
       // return GSON.toJson(map);
  }
}

위의 Helper Class에 대한 Test Code

import java.io.File;
import java.util.HashMap;
import java.util.Map;



/**
* SDK를 통해 받은 access token을 지정하시면
* REST API를 테스트해 보실 수 있는 샘플입니다.
* 푸시 알림 관련 API를 테스트하시려면 admin key 지정해야 합니다.
*/

public class Main {

   private static KakaoRestApiHelper apiHelper = new KakaoRestApiHelper();

   public static void main(String[] args) throws InterruptedException {
       new Main().test();
  }

   /**
    * 테스트가 필요한 api 블럭만 주석을 풀고 테스트하세요.
    */
   public void test() {
       // access token 지정
       apiHelper.setAccessToken("[YOUR APP KEY]");

       // 푸시 알림이나 유저 아이디 리스트가 필요할 때 설정 합니다.
       // (디벨로퍼스 내에 앱설정 메뉴를 가시면 있습니다)
       apiHelper.setAdminKey("[YOUR ADMIN KEY]");

       testUserManagement();
       testKakaoStory();
       testKakaoTalk();
       testPush();
  }

   public void testUserManagement() {

       Map<String, String> paramMap;

       /*
       // 앱 사용자 정보 요청 (signup 후에 사용 가능)
       apiHelper.me();
       */

       // 앱 연결
       // apiHelper.signup();

       /*
       // 앱 연결(파라미터)
       paramMap = new HashMap<String, String>();
       paramMap.put("properties", "{\"nickname\":\"test\"}");
       apiHelper.signup(paramMap);
       */

       // 앱 탈퇴
       //apiHelper.unlink();

       // 앱 로그아웃
       //apiHelper.logout();

       /*
       // 앱 사용자 정보 업데이트
       paramMap = new HashMap<String, String>();
       paramMap.put("properties", "{\"nickname\":\"test\"}");
       apiHelper.updatProfile(paramMap);
       */

       // 앱 사용자 리스트 요청
       //apiHelper.getUserIds();

       /*
       // 앱 사용자 리스트 요청 (파라미터)
       paramMap = new HashMap<String, String>();
       paramMap.put("limit", "100");
       paramMap.put("fromId", "1");
       paramMap.put("order", "asc");
       apiHelper.getUserIds(paramMap);
       */
  }

   public void testKakaoStory() {

       final String TEST_MYSTORY_ID = "[TEST MY STORY ID]";
       final String TEST_SCRAP_URL = "https://developers.kakao.com";

       // on Linux or Mac
       final File TEST_UPLOAD_FILE1 = new File("/xxx/sample1.png");
       final File TEST_UPLOAD_FILE2 = new File("/xxx/sample2.png");

       // on windows
       // final File TEST_UPLOAD_FILE = new File("C:\\~~/sample.png");

       Map<String, String> paramMap;

       /*
       // 스토리 프로파일 요청
       apiHelper.storyProfile();
       */

       /*
       // 스토리 유저인지 확인
       apiHelper.isStoryUser();
       */

       /*
       // 복수개의 내스토리 정보 요청
       // https://dev.kakao.com/docs/restapi#복수개의-내스토리-정보-요청
       apiHelper.getMyStories();
       */

       /*
       // 복수개의 내스토리 정보 요청 (특정 아이디 부터)
       paramMap = new HashMap<String, String>();
       paramMap.put("last_id", TEST_MYSTORY_ID);
       apiHelper.getMyStories(paramMap);
       */

       /*
       // 내스토리 정보 요청
       // https://dev.kakao.com/docs/restapi#카카오스토리-내스토리-정보-요청
       paramMap = new HashMap<String, String>();
       paramMap.put("id", TEST_MYSTORY_ID);
       apiHelper.getMyStory(paramMap);
       */

       // 내스토리 삭제
       // paramMap = new HashMap<String, String>();
       // paramMap.put("id", TEST_MYSTORY_ID);
       // apiHelper.deleteMyStory(paramMap);

       // 스토리 포스팅 공통 파라미터. 필요한 것만 선택하여 사용.
       paramMap = new HashMap<String, String>();
       paramMap.put("permission", "A"); // A : 전체공개, F: 친구에게만 공개, M: 나만보기
       paramMap.put("enable_share", "false"); // 공개 기능 허용 여부
       paramMap.put("android_exec_param", "cafe_id=1234"); // 앱 이동시 추가 파라미터
       paramMap.put("ios_exec_param", "cafe_id=1234");
       paramMap.put("android_market_param", "cafe_id=1234");
       paramMap.put("ios_market_param", "cafe_id=1234");

       // 글 포스팅일 경우에는 content는 필수지만 링크/사진 포스팅일 때는 옵션.
       paramMap.put("content", "더 나은 세상을 꿈꾸고 그것을 현실로 만드는 이를 위하여 카카오에서 앱 개발 플랫폼 서비스를 시작합니다.");

       String result;

       /*
       // 글 포스팅
       result = apiHelper.postNote(paramMap);
       if (result != null && result.indexOf("code\":-") == -1) {
           String postedId = result.split("\"")[3];
           System.out.println("postedId:" + postedId);
           if (apiHelper.deleteMyStory(postedId).equals(""))
               System.out.println("deleted test my story " + postedId);
       }
       */

       /*
       // 사진 포스팅 (최대 10개까지 가능)
       String uploadedImageObj = apiHelper.uploadMulti(
               new File[]{
                       TEST_UPLOAD_FILE1,
                       TEST_UPLOAD_FILE2
               });
       if (uploadedImageObj != null) {
           System.out.println("uploaded file(s) successfully.");
           System.out.println(uploadedImageObj);
           paramMap.put("image_url_list", uploadedImageObj);
           result = apiHelper.postPhoto(paramMap);
           if (result != null && result.indexOf("code\":-") == -1) {
               String postedId = result.split("\"")[3];
               System.out.println("postedId:" + postedId);
               if (apiHelper.deleteMyStory(postedId).equals(""))
                   System.out.println("deleted test my story " + postedId);
           }

       } else {
           System.out.println("failed to upload");
       }
       */

       /*
       // 링크 포스팅
       final String linkInfoObj = apiHelper.getLinkInfo(TEST_SCRAP_URL);
       if (linkInfoObj != null) {
           paramMap.put("link_info", linkInfoObj);
           result = apiHelper.postLink(paramMap);
           if (result != null && result.indexOf("code\":-") == -1) {
               String postedId = result.split("\"")[3];
               System.out.println("postedId:" + postedId);
               if (apiHelper.deleteMyStory(postedId).equals(""))
                   System.out.println("deleted test my story " + postedId);
           }
       }
       */

  }

   public void testKakaoTalk() {

       // 카카오톡 프로필 요청
       apiHelper.talkProfile();
  }

   public void testPush() {

       Map<String, String> paramMap;

       // 파라미터 설명
       // @param uuid 사용자의 고유 ID. 1~(2^63 -1), 숫자가만 가능
       // @param push_type gcm or apns
       // @param push_token apns(64자) or GCM으로부터 발급받은 push token
       // @param uuids 기기의 고유한 ID 리스트 (최대 100개까지 가능)

       // 푸시 알림 관련 API를 테스트하시려면 admin key 지정해야 합니다.

       /*
       // 푸시 등록
       paramMap = new HashMap<String, String>();
       paramMap.put("uuid", "10000");
       paramMap.put("push_type", "gcm");
       paramMap.put("push_token", "xxxxxxxxxx");
       paramMap.put("device_id", "");
       apiHelper.registerPush(paramMap);
       */

       /*
       // 푸시 토큰 조회
       paramMap = new HashMap<String, String>();
       paramMap.put("uuid", "10000");
       apiHelper.getPushTokens(paramMap);
       */

       /*
       // 푸시 해제
       paramMap = new HashMap<String, String>();
       paramMap.put("uuid", "10000");
       paramMap.put("push_type", "gcm");
       paramMap.put("push_token", "xxxxxxxxxx");
       apiHelper.deregisterPush(paramMap);
       */

       /*
       // 푸시 보내기
       paramMap = new HashMap<String, String>();
       paramMap.put("uuids", "[\"1\",\"2\", \"3\"]");
       apiHelper.sendPush(paramMap);
       */
  }
}


'Java' 카테고리의 다른 글

자바(JAVA) Iterator 인터페이스  (0) 2018.06.22
자바(JAVA) Sokect 통신  (0) 2018.06.22
자바(JAVA) 파일 입출력(I/O)  (0) 2018.06.22
자바 Map 컬렉션 클래스  (0) 2018.06.21
자바 List 컬렉션 클래스 (ArrayList)  (0) 2018.06.20
Comments