**************************  GCM 강좌 ****************************************

 

android GCM 클라이언트, 서버 완벽 구현 1 [ 사전 준비 ]

android GCM 클라이언트, 서버 완벽 구현 2 [ 클라이언트 셋팅, GCM 설정 ]

android GCM 클라이언트, 서버 완벽 구현 3 [ 클라이언트 셋팅, GCM 설정 ]

android GCM 클라이언트, 서버 완벽 구현 4 [ 서버 셋팅, GCM 설정 ]


******************************************************************************

 

 

 

이번에는 서버를 구성해 보겠습니다.

 

GCM 서버 구축에는 web project가 필요합니다. 이 강좌에서는 jsp 와 tomcat 을 사용합니다.

java jdk, eclipse, tomcat 은 설치되어있어야 합니다.

jdk, eclipse, tomcat 설치 방법은 검색해보면 아주 많이 나와있으니 참고하시기 바랍니다.

web 지식이 부족하신 분들은 jsp hello world 출력하기 강좌를 따라하시고 오셔도 충분합니다.

 

* web project 생성 방법은 생략합니다

 

 


2016.09.26 내용추가


web project 생성에 관련한 포스팅이 추가되어서 여기에도 명시해 드립니다 ^^


Mac 에 Tomcat 설치 / 톰캣 설치 (윈도우에서의 설치는 구글링 : 클릭)

eclipse에서 tomcat 생성 / 서버생성

eclipse에서 webproject 생성 / dynamic web project / jsp



 

 

순서 요약입니다.

 

1. jar 파일 준비

2. GCMUtil.java, GCMVo.java 생성

3.  앱에서 보낸 regId 받기

4. PUSH 호출

 

 

 

 

 



 

선행작업으로 web project 를 생성합니다.

기본적인 Dynamic Web Project 여도 상관없고 spring 프레임이거나 아무거나 상관없습니다.

필자는 기본적인 Dynamic 구조로 설명하겠습니다.

 

 

1. jar 파일 준비

다음 jar 파일을 다운받습니다.

 

gcm-server.jar

 

json-simple-1.1.1.jar

 

 

그리고 WebContent > WEB-INF > lib 폴더 아래로 복사합니다.

 

 

 

 

 

 

2. GCMUtil.java, GCMVo.java 생성

 

GCMUtil.java 를 생성합니다. GCMUtil 이 하는 일은 실제 GCM PUSH 를 보내는 역할을 합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
 
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Message.Builder;
import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
 
/**
 * GCM UTIL
 * 
 * gcm-server.jar, json-simple-1.1.1.jar 필요
 * 
 * @author 
 *
 */
public class GCMUtil {
    static final String API_KEY = "서버 API KEY"// server api key
    private static final int MAX_SEND_CNT = 999// 1회 최대 전송 가능 수
    
    // android 에서 받을 extra key (android app 과 동일해야 함)
    static final String TITLE_EXTRA_KEY = "TITLE";
    static final String MSG_EXTRA_KEY = "MSG";
    static final String TYPE_EXTRA_CODE = "TYPE_CODE";
    // android 에서 받을 extras key 
 
    List<String> resList = null;
    private Sender sender;
    private Message message;
    
    public ArrayList<GCMVo> rtnList;
 
    /**
     * GCM Util 생성자
     * RegistrationId 셋팅, sender 셋팅, message 셋팅
     * 
     * @param reslist : RegistrationId
     * @param gcmVo : msg 정보
     */
    public GCMUtil(List<String> reslist, GCMVo gcmVo) {
        sender = new Sender(API_KEY);
        this.resList = reslist;
        setMessage(gcmVo);
        rtnList = new ArrayList<GCMVo>();
        sendGCM();
    }
 
    /**
     * 메시지 셋팅
     * @param gcmVo
     */
    private void setMessage(GCMVo gcmVo) {
        Builder builder = new Message.Builder();
        builder.addData(TITLE_EXTRA_KEY, gcmVo.getTitle());
        builder.addData(MSG_EXTRA_KEY, gcmVo.getMsg());
        builder.addData(TYPE_EXTRA_CODE, gcmVo.getTypeCode());
        message = builder.build();
    }
 
    /**
     * 메시지 전송
     */
    private void sendGCM() {
        if (resList.size() > 0) {
            if (resList.size() <= MAX_SEND_CNT) { // 한번에 1000건만 보낼 수 있음
                sendMultivastResult(resList);
            } else {
                List<String> resListTemp = new ArrayList<String>();
                for (int i = 0; i < resList.size(); i++) {
                    if ((i + 1) % MAX_SEND_CNT == 0) {
                        sendMultivastResult(resListTemp);
                        resListTemp.clear();
                    }
                    resListTemp.add(resList.get(i));
                }
 
                // 1000건씩 보내고 남은 것 보내기
                if(resListTemp.size() != 0){
                        sendMultivastResult(resListTemp);
                }
            }
        }
 
    }
 
    /**
     * 실제 멀티 메시지 전송
     * 
     * @param list
     */
    private void sendMultivastResult(List<String> list) {
        try {
            
            MulticastResult multiResult = sender.send(message, list, 5); // 발송할 메시지, 발송할 타깃(RegistrationId), Retry 횟수
            List<Result> resultList = multiResult.getResults();
            
            
            for (int i=0; i<resultList.size(); i++){
                Result result = resultList.get(i);
 
                // 결과 셋팅
                GCMVo rtnGcmVo = new GCMVo();
                rtnGcmVo.setRegId(list.get(i));
                rtnGcmVo.setMsgId(result.getMessageId());
                rtnGcmVo.setErrorMsg(result.getErrorCodeName());
            
                if (result.getMessageId() != null) { // 전송 성공
                    rtnGcmVo.setPushSuccessOrFailure(true);
                } else { // 전송 실패
                    rtnGcmVo.setPushSuccessOrFailure(false);
                }
                
                rtnList.add(rtnGcmVo);
            }
 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
 
cs

20# : 메모한 서버 API-KEY 를 넣습니다.

24# ~ 26# : 3번 강좌에 설명해 놓았습니다. android project의 GCMIntentService.java 클래스에 19# ~ 21# 과 동일해야 합니다.

67# : 메시지를 한번에 보낼수 있는 최대 갯수는 1000개입니다. 안전성을 위해 999개씩 보내도록 분기합니다.

 

 

GCMVo.java 생성합니다. GCMVo 는 PUSH를 보낼 때 정보를 담는 역할을 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
 
public class GCMVo {
    // android 로 보낼 정보
    private String title = "제목입니다.";
    private String msg = "내용입니다.";
    private String typeCode = "코드입니다.";
    
    // push 결과 정보
    private String regId; // regId
    private boolean pushSuccessOrFailure; // 성공 여부
    private String msgId = ""// 메시지 ID
    private String errorMsg = ""// 에러메시지
 
    public String getTitle() {
        return title;
    }
 
    public void setTitle(String title) throws UnsupportedEncodingException {
        this.title = URLEncoder.encode(title, "UTF-8");
    }
 
    public String getMsg() {
        return msg;
    }
 
    public void setMsg(String msg) throws UnsupportedEncodingException {
        this.msg = URLEncoder.encode(msg, "UTF-8");
    }
 
    public String getTypeCode() {
        return typeCode;
    }
 
    public void setTypeCode(String typeCode) {
        this.typeCode = typeCode;
    }
 
    public boolean getPushSuccessOrFailure() {
        return pushSuccessOrFailure;
    }
 
    public void setPushSuccessOrFailure(boolean pushSuccessOrFailure) {
        this.pushSuccessOrFailure = pushSuccessOrFailure;
    }
 
    public String getErrorMsg() {
        return errorMsg;
    }
 
    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }
 
    public void setRegId(String regId) {
        this.regId = regId;
    }
 
    public String getMsgId() {
        return msgId;
    }
 
    public void setMsgId(String msgId) {
        this.msgId = msgId;
    }
 
    public String getRegId() {
        return regId;
    }
    
    
    
}
 
cs

 

 

 

 

 

 

3.  앱에서 보낸 regId 받기

 

PUSH를 보내려면 디바이스의 regId 가 있어야 합니다.

android project 에서 로그로 regId 를 출력하고 있어서 복사해서 호출할 때 그냥 사용해도 무방합니다.

하지만 앱실행 > 앱에서 서버로 regId 전송 > 서버에서 regId 수집 및 저장 > 수집된 regId로 PUSH 호출 > 앱에서 PUSH 수신 과 같은 로직이 있어야 사용하기 편하기 때문에 받는 부분을 꼭 구현하시기 바랍니다.

 

 

 

WebContent 폴더 아래에 sendGCMReg.jsp 파일을 생성합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%@page import="java.net.URLEncoder"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/json; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%
 
    System.out.println("*********************************************************");
    System.out.println("REG 획득");
    System.out.println("KEY : " + request.getParameter("KEY"));
    System.out.println("REG : " + request.getParameter("REG"));
    System.out.println("*********************************************************");
    
    Map rtnMap = new HashMap();
    
    rtnMap.put("DATA", URLEncoder.encode("등록되었습니다.""UTF-8"));
    rtnMap.put("DATA1""END1");
    out.print(rtnMap.toString());
 
%>
cs

 

 

그리고 sendGCMReg.jsp 를 호출하는 주소를 andorid project 의 MainActivity.java 의 SERVER_URL 변수에 셋팅합니다.

대략 http://111.111.111.111:8080/sendGCMReg.jsp 이런 모양이 되겠네요.

 

이제 앱을 실행합니다. 에뮬레이터 말고 인터넷이 가능한 스마트폰에서 꼭 실행하도록 합니다.

여기서 실행하면 더이상 앱에서는 오류가 발생하지 않습니다.

 

 

버튼을 클릭해 봅니다.

 

그럼 서버의 eclipse 의 console 에 REG 정보가 찍혀있을 것입니다.

 

여기서 획득한 regId 정보를 메모합니다.

 

regId 정보를 db에 넣어서 관리할 수 도 있겠죠 ???

 

 

 



 

4. PUSH 호출

 

regId 도 획득했으니 이제 regId 를 이용하여 PUSH 를 직접 보내봅시다.

 

WebContent 폴더 아래에 sendGCM.jsp 파일을 생성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<%@page import="esaving.module.common.pushmobile.GCMUtil"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@page import="esaving.module.common.pushmobile.GCMVo"%>
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%
 
    //전달할 PUSH 내용
    String title = "PUSH 제목 입니다.";
    String msg = "PUSH 내용입니다 ^^ !!!!";
    
    // GCM 정보 셋팅
    GCMVo gcmVo = new GCMVo();
    gcmVo.setTitle(title);
    gcmVo.setMsg(msg);
    gcmVo.setTypeCode("");
    
    // GCM reg id 셋팅
    List<String> reslist = new ArrayList<String>();
    reslist.add("입력받은 regId를 입력합니다.");
    
    GCMUtil gcmUtil = new GCMUtil(reslist, gcmVo);
    
   for(int i=0; i<gcmUtil.rtnList.size(); i++){
      GCMVo rtnGcmVo = gcmUtil.rtnList.get(i); 
 
      out.println("regId : " + rtnGcmVo.getRegId());
      out.println("성공 여부 : " + rtnGcmVo.getPushSuccessOrFailure());
      out.println("메시지ID : " + rtnGcmVo.getMsgId());
      out.println("에러메시지 : " + rtnGcmVo.getErrorMsg());
   } 
 %>
cs

10# ~ 17# : PUSH 보낼 내용을 셋팅합니다.

21# : 입력받은 regId 를 입력합니다.

30# : 에러메시지가 NotRegistered 이면 앱이 삭제됬다고 판단하면 된다. 비교할 수 있는 상수는 Constants.ERROR_NOT_REGISTERED 입니다.

실제로 앱이 삭제되고 google gcm 서버로 regId 가 삭제하는 메시지를 보내고 적용되는 시간이 조금 걸리니 앱 삭제 후 바로 테스트하는 것은 의미없습니다.

 

 

sendGCM.jsp 를 호출 해 주면 PUSH 가 도착하는 것을 볼 수 있습니다.

 

대략 http://111.111.111.111:8080/sendGCM.jsp 과 같은 주소이겠죠 ?

 

 

 

이상으로 GCM 클라이언트(어플리케이션)와 서버를 완벽하게 구현하는 강좌를 마칩니다.

 

 

 

 

by 개발자 CofS 2016.04.07 14:41
  • 이전 댓글 더보기
  • phj 2016.10.04 09:45 ADDR EDIT/DEL REPLY

    안녕하세요. 정말 많이 도움이 되었습니다. 한가지 안되는 부분이 있어서 질문드려요 ㅠㅠ
    제가 카카오택시같은 앱을 공부중인데 fcm으로 구현중에 있습니다.
    핸드폰이 화면이 꺼져있을때 문자를 송신하면 문자는 제대로 와있는데 진동이나 소리가 오질 않습니다.
    wake 를 통해서 처리를 했는데도 되질 않네요. 어플이 활성화상태에서는 진동 및 소리는 정상적으로 됩니다.

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.04 11:41 신고 EDIT/DEL

      FCM 에 대해선 아직 보지 못해서 정확한 답변을 드리기가 어렵네요 ㅠㅠ

      메시지를 받는 부분에서 NotificationCompat.Builder 를 사용하는 것은 같을텐데 IntentService 때문인가... FCM 은 해보질 않아서 잘모르겠네요 ㅠㅠ

  • khj 2016.10.04 11:25 ADDR EDIT/DEL REPLY

    안녕하세요? 선생님 GCM 예제샘플로 구현하고 있는 사람입니다.
    웹만 하다가 안드로이드를 접하게되었는데요, 예제 구현 중에 여쭤볼게 있어서요.
    3번예제에 센드노티피케이션 메소드 안에 .setSmallIcon(R.mipmap.ic_launcher) 이런 부분이 있는데,
    예제 그대로 복붙해서 했는데 "mipmap" 이부분에 빨간색 줄이 그어져서 "mipmap cannot be resolved or is not a field" 요런 에러메시지를 뱉어냅니다. 혹시 제가 버튼을 구현을 안했는데 그 부분 때문에 이런 메시지가 나오는지, 아니면 제가 놓친부분이 있는건지 답변좀 부탁드리겠습니다... 감사합니다.

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.04 11:34 신고 EDIT/DEL

      반갑습니다 ^^
      R.mipmap.ic_launcher 상수는 아이콘 파일(이미지)을 가리키는 상수에요 ㅎㅎ
      다른 이미지나 아이콘명을 사용하신다면 그 이미지의 상수를 적어주시면 됩니다 ^^

  • 네모 2016.10.06 15:21 ADDR EDIT/DEL REPLY

    푸시 메세지가 오고 나서 터치하고 아무런 동작도 실행이 안 되면 어느 부분이 잘 못 된 건가요?

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.06 15:26 신고 EDIT/DEL

      sendNotification 이부분이 푸쉬를 받아오고 클릭하면 다음동작을 하는 부분입니다.

      여기를 살펴보시는게...

  • 김석운 2016.10.08 15:25 ADDR EDIT/DEL REPLY

    하나 여쭤봐도 될까요?
    gcm 설정하는 부분에서, 프로젝트 생성하고 gcm을 누르면 firebase로 넘어가버리더라구요
    gcm이 없어졌다는소리도 있던데 어떻게 해야하나요?ㅠㅠ

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.10 10:05 신고 EDIT/DEL

      GCM 사이트의 FAQ 발췌문입니다.

      Is GCM going to be deprecated?

      We will continue to support the current version of GCM Android and iOS SDKs because we know a lot of developers are using GCM SDKs today to handle notifications, and client app upgrade takes time.

      But all new client-side features will be added to FCM SDKs only moving forward. You are strongly encouraged to upgrade to FCM SDKs.

      FCM은 GCM의 새로운 버전으로 firebase 플랫폼을 사용해야 하는것같이 보이네요
      GCM > FCM으로 마이그레이션 하는 방법도 제공하고 있네요
      FCM으로 마이그레이션 하는것을 권장하지만 GCM 이 당분간은 서비스종료 되지는 않는듯 합니다.
      잠깐 둘러봤는데 기존 GCM 페이지로 이동하는 방법은 보이지 않습니다 ㅠ

  • 대바기귀여워 2016.10.10 14:52 ADDR EDIT/DEL REPLY

    푸시메세지를 받아야 할 때마다 일일이 sendGCM.jsp 를 서버로 돌려야 하나요?
    버튼을 누르면 중간과정 없이 푸시 메세지를 받도록 하고 싶은데, 어떻게 해야 하나요?

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.10 16:37 신고 EDIT/DEL

      버튼이 어떤 버튼을 말씀하시는건지 ...

      푸시메시지는 웹 서버를 통해 호출하지 않으면 디바이스에서 받아보실 수 없습니다.

  • jhjh 2016.10.14 20:44 ADDR EDIT/DEL REPLY

    마지막에 sendGCM 호출하라고 하셨는데요 이것도 sendGCMReg처럼 SURVER_URL에 셋팅하여 주면 되는건가요??

    • dev 2016.10.17 15:15 EDIT/DEL

      push 보내려면 sendGCM 호출하면되요
      어디에 셋팅하는게 아니에요

    • jhjh 2016.10.17 17:07 EDIT/DEL

      그러면 sendGCM은 이클립스에서 호출하나요 안드로이드에서 호출하나요??

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.19 17:43 신고 EDIT/DEL

      브라우저에서 호출합니다 ^^

    • kkkk 2016.10.21 16:59 EDIT/DEL

      안녕하세요! 저도 이부분이 궁금해서 여쭤보고 싶습니다!
      글 잘써주셔서 정말 감사해요! ㅜㅠ사랑합니다
      무튼 나머지는 제가 정말 잘 따라갔는데요,
      마지막에 reslist.add("regid를 입력")하는거 자체가 제가 console창에서 받아온 reg를 수동으로 넣어주고
      크롬창에서 xxx.xxx.xxx.xxx:8080/sendGCM.jsp를 쳐서 들어가는거라고 생각했는데 맞나요?
      그리고 그렇게 들어가면 자꾸 false가 뜨고 에러메세지가 InvalidRegistration입니다ㅜㅜ

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.24 09:17 신고 EDIT/DEL

      Check the format of the registration token you pass to the server. Make sure it matches the registration token the client app receives from registering with GCM. Do not truncate or add additional characters.

      해당 에러의 내용입니다

  • eeee 2016.10.24 16:07 ADDR EDIT/DEL REPLY

    안녕하세요!
    java.net.HttpRetryException: cannot retry due to server authentication, in streaming mode
    이런에러가 나서 찾아보니 api key 값이 서버가아닌 클라이언트 설정을 하면 이런 에러가 날수있다고 하는데
    콘솔에서 key 값을 받아오는데 서버키 값이아닌 그냥 key 생성만 되어있고 서버 key 값을 따로 받아오는방법이 없는데 혹시 해결방안을 알수있을까요..

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.24 16:36 신고 EDIT/DEL

      http://cofs.tistory.com/176

      위 포스팅의 3번 보시면 서버 API-KEY 생성 하는 방법이 있습니다 ㅎㅎ

      물론 GCM일 경우만 해당됩니다...

    • eeee 2016.10.24 17:04 EDIT/DEL

      포스팅 3번하고 다르게 키설정을 누르면 바로생성이 되어버리는 현상이나와서 다른방법으로 할수있는 방법을 찾고있는데.. 힘드네요... 대부분 분들이 지금 GCM / FCM 때문에 안되는거같은데 하다보니 꼼수일진 몰라도 라이브러리 검색 하는곳에 google cloud messaging 치시면 접속가능합니다~

    • eeee 2016.10.24 17:08 EDIT/DEL

      아그리고 혹시 compile (group: 'org.apache.httpcomponents' , name: 'httpmime' , version: '4.3.5') { excludemodule: 'org.apache.httpcomponents:httpclient'} 부분 이 compile이 안되는데 다른식으로 compile 할수있는 방법이있을까요... 툴은 23버젼 쓰고있습니다

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.24 17:16 신고 EDIT/DEL

      다른방식의 컴파일이라 하면 터미널에서 강제로 올리는 방법을 말씀하시는건가 ...
      근데 Gradle 에서 컴파일 부분에서 에러가 난다는 것은 버전이 맞지 않는 경우가 많아요
      빌드 버전이라던가 appcompat 버전 등 각 호환이 되는 버전들로 엮어주어야 해요

    • eeee 2016.10.24 17:19 EDIT/DEL

      한번 시도 해보겠습니다. 답변 정말 감사합니다~

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.25 10:58 신고 EDIT/DEL

      화이팅 입니다 ^^

  • 윗분 보세용! 2016.10.25 19:42 ADDR EDIT/DEL REPLY

    https://console.firebase.google.com/ => 설정 => 클라우드메시징 => 서버키를 만들수있습니다!

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.25 19:45 신고 EDIT/DEL

      https://console.firebase.google.com/ => 설정 => 클라우드메시징 => 서버키

      여기에서 발급받은 서버키로 GCM을 구동시킬 수 있나요 ???

    • 윗분 보세용! 2016.10.26 09:29 EDIT/DEL

      네 저기서 받은 서버키로 했더니 푸시까지됐습니다! 프로젝트id도 나와있는데 동일해요

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.10.26 12:59 신고 EDIT/DEL

      오 좋은정보 감사합니다 ^^

  • 초보 2016.11.05 23:05 ADDR EDIT/DEL REPLY

    안녕하세요. 글잘봤습니다!
    Regid 버튼을 누루면,
    서버 호출 결과 코드 : 404
     서버 호출 실패 code : 404

    java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
    이뜨는데, 어디가 문제인걸까요 ㅠ

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.11.06 09:46 신고 EDIT/DEL

      404 에러는 호출하는 주소가 잘못되었을 경우 나타납니다.

      찾을수 없는 주소일때 404에러가 나거든요

      NullPointerException 은 비어있는 객체를 사용하려고 할 때 나타납니다.
      에러 로그를 보시면 해당 에러가 난 곳 위치가 있을 거에요 그부분을 살펴보시면 됩니다 ^^

    • 초보 2016.11.06 15:19 EDIT/DEL

      감사합니다. 해결했어요.
      근데 GCMSend.jsp 에서 패키지명은 이클립스에 패키지명인가요?

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.11.06 17:06 신고 EDIT/DEL

      GCMSend.jsp 에서 패키지가 어디있죠 ?

  • 초보 2016.11.06 17:26 ADDR EDIT/DEL REPLY

    <%@page import="esaving.module.common.pushmobile.GCMUtil"%>
    저도 저부분에서 빨간줄 떠서,
    import GCMUtil.java;
    import GCMVo.java;
    저렇게 써줫는데, 오류가 나는거 같아서요... ㅠㅠ 패키지를 만들어서 그안에 GCMVo.java랑 GCMUtil.java를 넣어줘야되는건가요??

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.11.06 17:29 신고 EDIT/DEL

      GCMUtil 사용하신다면 GCMUtil 패키지 써주시면 되고 안쓰시면 지우세요 ㅎㅎ

  • 초보 2016.11.06 17:31 ADDR EDIT/DEL REPLY

    Servlet.service() for servlet [jsp] in context with path [/webserver] threw exception [Unable to compile class for JSP:

    An error occurred at line: 12 in the jsp file: /sendGCM.jsp
    GCMVo cannot be resolved to a type
    이런에러가 뜨는데, 원인이 뭔지 알수있을까요???ㅠ

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.11.06 17:33 신고 EDIT/DEL

      예제를 그대로 따라하면 오류가 날 이유가 전혀 없는 포스팅입니다
      GCMVo 가 없거나 오타이거나 import가 잘못되었거나 등등 여러 이유가 있을수 있어요
      기본적인 지식 없이는 따라하기 힘듭니다.
      포스팅 최 상단에도 나타나 있듯이 web project 지식이 부족하면 미리 선행학습하시고 오는게 필수적입니다.

  • 미생 2016.11.11 16:32 ADDR EDIT/DEL REPLY

    궁금한데요 이 방법으로 적용시키고 다른폰에서 앱을 킨후 푸시를 받을수있는건가요??

    그리고 jsp서버를 구현해서 한다고 하셨는데 이 부분도 약간 이해가 안가네요..
    호스팅주소에 php같이 돌리는건가요?

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.11.11 16:47 신고 EDIT/DEL

      다른폰의 reg_id 를 수집하면 푸쉬 보낼수 있겠죠 ?
      jsp는 php와 비슷한 스트립트 언어에요

  • 미생 2016.11.11 16:33 ADDR EDIT/DEL REPLY

    로컬에서만 사용하면 다른 사용자가 이용을 못하는거 아닌가해서요..

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.11.11 16:47 신고 EDIT/DEL

      다른 사용자가 push를 받아보는 것과 로컬은 관계가 없네요

  • 흐접 2016.12.01 14:33 ADDR EDIT/DEL REPLY

    server부분에서 sendGCM.jsp파일에서

    <%@page import="esaving.module.common.pushmobile.GCMUtil"%>

    <%@page import="esaving.module.common.pushmobile.GCMVo"%>

    이부분에서 esaving부분 에러가 나는데 무슨 이유인지 아시나요??ㅜㅜ

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.12.01 16:28 신고 EDIT/DEL

      서버는 이클립스에서 진행하는것이 맞습니다.

      어떤 폴더에 생성한다기 보다는 webProject를 생성하셔서 진행하셔야 합니다.

      webProject는 본문 상단에 나와있으니 참고하시기 바랍니다 ^^

    • 흐접 2016.12.01 19:48 EDIT/DEL

      <%@page import="esaving.module.common.pushmobile.GCMUtil"%>

      이부분에서 esaving부분이 에러나면서 cannot be resolved라고 나오는데 왜그런건가요?ㅠㅠ 딱 저 부분만 에러가 나네요ㅠㅠ

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.12.01 19:49 신고 EDIT/DEL

      GCMUtil 을 본인 패키지 구조로 import 시키세요 ㅎㅎ

    • 흐접 2016.12.01 20:13 EDIT/DEL

      제가 지금 Webproject/src/default package/GCMUtil.java랑 GCMVo.java 생성했고 WebContent/WEB-INF/sendGCM.jsp 랑 sendGCMReg.jsp 생성했는데 sendGCM.jsp에서 위와같은 import부분에서 에러가 납니다. 파일생성은 제가 한게 맞는건가요? 에러가 왜나는지 모르겠습니다ㅠㅠ

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.12.02 09:16 신고 EDIT/DEL

      GCMUtil.java 최 상단에 패키지 주소가있습니다.

      import 할 때 그 주소가 일치해야 합니다.

      패키지란 path 와 같다고 생각하면 쉽습니다. 일종의 파일의 경로입니다.

      왜냐하면 import 는 해당 파일을 사용하겠다는 선언입니다.
      사용하려는 파일이 어디에 있는지 알아야 하고 때문에 import 할 때 파일의 경로를 정확히 작성해야합니다.

    • 흐접 2016.12.02 16:14 EDIT/DEL

      빠른 답변 감사합니다. 그러면 지금 친구가 웹서버를 구축하고 있는데 저는 예제에 나온 3번 (클라이언트)부분 까지만 구성하고 나머지 서버부분은 친구가 구축한 웹서버에 API ID값이랑 KEY값 등록한 후에 맞춰서 하면 되는 건가요???ㅠㅠ

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.12.02 17:41 신고 EDIT/DEL

      맞아요 ㅎㅎ
      잘이해하고 계신것 같네요

    • 흐접 2016.12.05 11:16 EDIT/DEL

      제가 따로 App서버 구성 안해도 되는거 맞죠??

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.12.05 16:20 신고 EDIT/DEL

      App서버라는게 어떤걸 말씀하시는지...

    • 흐접 2016.12.05 17:02 EDIT/DEL

      따로 제가 서버구성할 필요없는거죠??

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.12.05 18:18 신고 EDIT/DEL

      친구가 웹서버 즉 웹프로젝트를 구축중에 있다면 다른 서버는 없어도 관계없습니다 ^^

    • 흐접 2016.12.06 16:33 EDIT/DEL

      server부분에서 sendGCM.jsp파일에서

      제가 만든 패키지로 import시켰는데

      <%@page import="esaving.module.common.pushmobile.GCMUtil"%>

      <%@page import="esaving.module.common.pushmobile.GCMVo"%>

      이부분에서 esaving부분 에러가 계속나는데..

      말씀하신대로 맨위에 제 패키지로 import시켰는데도 계속 저부분만 에러가 나네요ㅠㅠ

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2016.12.06 17:11 신고 EDIT/DEL

      흠...
      이글을 보시면 좀 이해가 되시려나...
      http://kcizzang.tistory.com/entry/JSP-import-%EC%86%8D%EC%84%B1%EC%97%90-%EB%8C%80%ED%95%9C-%EC%84%A4%EB%AA%85

    • 2016.12.06 17:13 EDIT/DEL

      비밀댓글입니다

  • 왕초보입니다 2017.01.12 20:18 ADDR EDIT/DEL REPLY

    안녕하세요 ~ 이글을 보면서 하이브리드 앱을 만들고 있는 안드로이드 초심자입니다..
    그런데 이글을 따라서 했는데.. 여전히 null값만 넘겨주더라고요..
    하나씩 로그캣 찍어보면서 봤는데...
    HttpURLConnection conn = (HttpURLConnection) obj.openConnection();
    이부분에서 D/NetworkSecurityConfig: No Network Security Config specified, using platform default
    이런 오류가 뜨더군요...
    참고로 안드로이드 버전을 7.0 쓰고있습니다. Manifest 파일에 퍼미션까지 주고 권한까지 얻은 상태인데..
    계속해서 오류가 뜨네요...ㅠㅠㅠㅠ
    인터넷 검색으로 해봐도 나오질 않던데.. 도움을 주실수 있을까요 ?

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2017.01.13 09:15 신고 EDIT/DEL

      ssl 을 이용하면 위 오류를 만날 경우도 있다고 하네요.

      네트워크 보안에 관한 오류인듯 보이네요.

      https://developer.android.com/training/articles/security-config.html#manifest

      이쪽이 도움이 되실지도...

  • 하늘느낌 2017.02.28 18:39 ADDR EDIT/DEL REPLY

    안녕하세요. push 구현 중 궁금한것이 있어 이렇게 문의드립니다. 블로그를 보고 열심히 따라하여 기기정보도 정상적으로 받았고 웹에서 push를 하면 화면에 regId : APA91bGGgBP7M9G5MMjzLzjNmtsTUou5eelLK0IptJuIIoDmu29N0pW4n9E_DymCcGbFpWcUdyRxeNZQsFMaFTKZUJjSFDoVi2PIshmjThWYSu_Bqvoc_7E 성공 여부 : true 메시지ID : 0:1488274495063520%29448c2cf9fd7ecd 에러메시지 : null
    이렇게 뜨는데 핸드폰에는 아무 반응이 없네요. 성공여부를 보면 true로 되어 있는데...
    혹시 어느부분을 확인해야 하는지 조언 주시면 감사하겠습니다.
    그리고 궁금한것이 GCMVo에 typeCode가 이 놈은 어디다 쓰는 놈인지도 궁금하구요..
    거의 다 되었다고 생각했는데.. 마지막에서 정상적으로 되지 않으니...
    많은 조언 부탁드립니다. 즐거운 하루 보내시기 바랍니다. 감사합니다.

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2017.02.28 18:48 신고 EDIT/DEL

      정상적으로 처리가 된 것으로 보이는데 push 가 오지않는 모양인것 같네요 ㅠ
      흠......
      일단 프로젝트ID 나 regId 가 맞는지부터 확인할 필요가 있어요 ㅎ
      간혹 regId 같은 경우는 짤리거나 문자가 누락되는 경우가 생길 수 있어요.
      android 콘솔에서 획득하는 regId 와 web 에서 사용하는 regId가 같은지 볼 필요가 있어요.
      그거말고는 조금 기다려 보거나 네트워크 확인정도 ????
      그랬었던 경우가 없어서 제가 비슷한 상황이라면 이정도 확인해볼것 같아요 ㅎㅎ

      typeCode 는 사실 예제에는 쓰임세가 없어요
      제가 사용하려고 넣어둔 것인데 추후에 한 디바이스에 여러번 push 전송할 때 사용한답니다 ㅎㅎ;;

  • 하늘느끼 2017.03.01 12:25 ADDR EDIT/DEL REPLY

    감사합니다 다시 한번 확인 해 봐야겠네요^*

  • 2017.03.02 10:20 ADDR EDIT/DEL REPLY

    비밀댓글입니다

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2017.03.02 10:57 신고 EDIT/DEL

      깃 주소알려주시면 같이 한번 고민해봐요 ㅎㅎ
      하지만 오류가 나지않는것으로 보아 소스상에서 문제가 있을 확률은 적어보이고 project 번호나 api-key 등 사전준비에서 발급받는 정보들이 의심스러운데 이부분은 제가 확인할 수 있는 부분이 아니기 때문에 다시한번 확인해주시면 감사하겠습니다 ^^;
      저도 이전에 project Id 와 project 번호를 혼동한 적이 있었던 기억이 나네요 ㅎㅎ

  • 2017.05.22 13:13 ADDR EDIT/DEL REPLY

    비밀댓글입니다

    • Favicon of https://cofs.tistory.com BlogIcon 개발자 CofS 2017.05.22 13:21 신고 EDIT/DEL

      일정시간마다 메세지가 수신되는것은 아니고 push 를 호출할때마다 스마트폰에 메시지가 수신됩니다.

      해당 애러에 대한 정보를 찾아보았는데 여러 이유가 있을수 있다고 하네요.
      그중에서 가장 많았던 내용이 gcm을 구성하는데 있어서 설정값들 그러니까 api key 등의 정보를 다시한번 살펴보는게 방법이 될 수 있을것 같습니다.

      실제 오류코드들을 가지고 검색해보시면 더 많은 정보를 얻을 수 있을듯 합니다 ㅎㅎ

  • 안드로이드 하수 2017.05.26 11:16 ADDR EDIT/DEL REPLY

    와 .. 이거에 대한 자세한 정보가 많이 없던데.. 상세하게 잘 해주신것 같아요 덕분에 많이 배워갑니다!
    감사합니다.