skj
20
2019-09-12 10:09:40 작성 2019-09-12 10:10:32 수정됨
4
976

안드로이드를 처음 해보는 사람인데 json array 파싱 부분에서 문제가 생겼습니다. 스택 오버플로우 깃허브 등지를 모두 찾아봤지만 답을 찾을 수가 없어서 질문 드립니다...




D/responseStatusCode: 200//코드 200이면 정상이라고 하더군요.

D/ResponseStringBuilder: {"response":[{"ID":"id2","ReplyIndex":"15","lost_ID_Foreign":"123","Password":"pw","Contents":"coco"},{"ID":"id","ReplyIndex":"13","lost_ID_Foreign":"123","Password":"pw","Contents":"co"}]}// 제가 파싱해야 하는 json array 입니다. php로 변수에 값 대입 후 json encoded로 echo 된 array입니다.

D/: HostConnection::get() New Host Connection established 0x90d77f40, tid 32536 D/EGL_emulation: eglMakeCurrent: 0xa45850c0: ver 3 0 (tinfo 0xa45832d0) D/EGL_emulation: eglCreateContext: 0x911f8de0: maj 1 min 0 rcv 1 D/EGL_emulation: eglMakeCurrent: 0x911f8de0: ver 1 0 (tinfo 0x8c77ce40) D/EGL_emulation: eglMakeCurrent: 0xa45850c0: ver 3 0 (tinfo 0xa45832d0)

W/System.err: org.json.JSONException: Value  of type java.lang.String cannot be converted to JSONObject//Value와 of 사이에 띄어쓰기가 두 번 되어있는 것을 보니 공백 문자가 어딘가에서 삽입 된 것 같은데 어디선 문제가 발생한 것인지 파악 할 수가 없습니다.

    at org.json.JSON.typeMismatch(JSON.java:111)
    at org.json.JSONObject.<init>(JSONObject.java:163)
    at org.json.JSONObject.<init>(JSONObject.java:176)
    at com.example.register.ListDetailActivity$replyBackgroundTask.onPostExecute(ListDetailActivity.java:212)
    at com.example.register.ListDetailActivity$replyBackgroundTask.onPostExecute(ListDetailActivity.java:127)
    at android.os.AsyncTask.finish(AsyncTask.java:695)
    at android.os.AsyncTask.-wrap1(Unknown Source:0)
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)

W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6541)

    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

D/response: response - {"response":[{"ID":"id2","ReplyIndex":"15","lost_ID_Foreign":"123","Password":"pw","Contents":"coco"},{"ID":"id","ReplyIndex":"13","lost_ID_Foreign":"123","Password":"pw","Contents":"co"}]}//응답이 json array로 나왔고, 혹시나 싶어서 http://jsonviewer.stack.hu/ 에서도 확인해 보았지만 문제가 있는 array는 아닌 것 같았습니다. 혹시 제가 잘못 알고 있는 건가요?

안드로이드 코드 부분입니다.

class replyBackgroundTask extends AsyncTask { String target;

    @Override
    protected void onPreExecute(){
        target =  "제 서버 주소";
    }



    @Override
    protected  String doInBackground(Void... voids){
        try {
            String searchKeyword1 = "123";//임시로 넣은 값입니다.
            String postParameters =  "lost_ID_Foreign="+searchKeyword1;


            URL url = new URL(target);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.connect();

            OutputStream outputStream = httpURLConnection.getOutputStream();
            OutputStreamWriter outputStreamWriter =
                    new OutputStreamWriter(outputStream, "EUC-KR");
            PrintWriter printWriter =
                    new PrintWriter(outputStreamWriter);
            printWriter.write(postParameters);
            printWriter.flush();
            outputStream.close();


            /*OutputStream os = httpURLConnection.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            writer.write(postParameters);
            writer.flush();
            writer.close();
            os.close();*/
            //코드 여러 개를 바꿔가며 적용 시켜보았지만 항상 같은 결과가 나왔습니다.

            int responseStatusCode = httpURLConnection.getResponseCode();
            Log.d("responseStatusCode", ""+responseStatusCode);//코드 로그 위치

            InputStream inputStream = httpURLConnection.getInputStream();


            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String temp;
            StringBuilder stringBuilder = new StringBuilder();
            while ((temp = bufferedReader.readLine()) != null)
            {
                stringBuilder.append(temp+'\n');
            }
            bufferedReader.close();
            inputStream.close();
            httpURLConnection.disconnect();
            Log.d("ResponseStringBuilder",stringBuilder.toString().trim());
            //on post execute에 result로 넘겨주기 전 log 위치
            return stringBuilder.toString().trim();

        }

        catch (Exception e){


            e.printStackTrace();

        }

        return null;
    }

    @Override
    public void onProgressUpdate(Void... values){
        super.onProgressUpdate(values);
    }
    @Override
    public void onPostExecute(String result) {
        try{
            String lost_ID, ReplyIndex ,ID,Password, Contents;


            JSONObject jsonObject = new JSONObject(result);

            JSONArray jsonArray = jsonObject.getJSONArray("response");
            int count = 0;



            while(count < jsonArray.length()){
                JSONObject object = jsonArray.getJSONObject(count);
                lost_ID = object.getString("lost_ID_Foreign");
                ReplyIndex = object.getString("ReplyIndex");
                ID = object.getString("ID");
                Password = object.getString("Password");
                Contents = object.getString("Contents");


                Reply reply = new Reply(lost_ID, ID, Password, ReplyIndex,Contents);

                replyList.add(reply);
                count++;
            }

        }catch (Exception e){
            e.printStackTrace();
        }

        Toast.makeText(getApplicationContext(),result,Toast.LENGTH_SHORT).show();
        Log.d("response", "response - " + result);//result로 넘겨받은 json array 로그 위치
        adapter = new ReplyListAdapter(getApplicationContext(), replyList, ListDetailActivity.this,replySaveList);
        ListView replyListView = (ListView)findViewById(R.id.replyListView) ;

        replyListView.setAdapter(adapter);
        setListViewHeightBasedOnChildren(replyListView);
    }
}
json array 형태가 제대로 나오는 것으로 보이는데 혹시 제가 잘못 생각하고 있는 건가 싶어서 여쭈어 보게 되었습니다. 오늘 18시부터 이 시간까지 이 문제와 씨름하고 있는데 해답이 나오질 않습니다. 에러코드를 전부 검색하여 정보를 얻어보려 노력했지만 제 실력이 부족하여 그런 것인지 답을 얻을 수 없었습니다. 도와주시길 간절히 부탁 드립니다!...

0
  • 답변 4

  • 리오레오
    1k
    2019-09-12 10:33:49

    값이 오지 않아서 컨버팅이 안된다는 에러같아 보입니다만.

    혹시 모르니 값을 가져오는 부분이외에는 전부 주석처리하시고, 값을 스트림으로 가져오는 부분에서 값이 오는지 하나씩 찍어보세요.

    최소한의 코드만 가지고 하나씩 풀어보세요.

  • skj
    20
    2019-09-12 11:16:52 작성 2019-09-12 11:36:21 수정됨

    말씀하신대로 값이 오는지 한번씩 찍어보고 값의 이동 외에 관여하는 부분은 전부 주석처리하여 확인 하였습니다. doinbackground 에서 onpostexecute 로 넘어가는 부분에서 값 전달은 제대로 되는 것으로 확인되었습니다.

    추가적인 edittext를 만들어 onpostexecute 메서드에서 변수명 result를 settext 해보니 

    {"response":[{"ID":"id2","ReplyIndex":"15","lost_ID_Foreign":"123","Password":"pw","Contents":"coco"},{"ID":"id","ReplyIndex":"13","lost_ID_Foreign":"123","Password":"pw","Contents":"co"}]}

    라는 결과가 나왔습니다.

    문제점을 찾기에 애로사항이 있어 그냥 string 형태 그대로 처리하는 것도 하나의 방편으로 염두에 두고 있는데 혹시 이렇게 처리하면 문제점은 없을 지 여쭈어 보고 싶습니다.



    한 줄 씩 settext 해보며 확인해보니 JSONObject jsonObject = new JSONObject(result); 부분에서 값 대입에 문제가 있던 것 같습니다. 

  • 리오레오
    1k
    2019-09-12 12:50:45

    제가 알려드린 것은 문제가 발생하였을 때 찾는 방법일 뿐입니다.

    처리하는 방법은 어떤 출력 결과를 원하느냐에 따라서 선택하면 됩니다.

    출력결과에 따라서 자료형을 선택하면 됩니다. 그전까지는 편한대로 하면 됩니다.

    로그로 출력하더라도 화면에서 원하는 결과에 따라서 다른 결과를 보여줄수도 있으니 그것을 염두에 두면 됩니다.

    자바는 php보다 자료형에 대한 주의가 많이 필요합니다.

  • skj
    20
    2019-09-12 21:54:01

    말씀을 듣고 해당 자료를 문자열로 다루었습니다. 결정에 도움 주셔서 감사합니다.

  • 로그인을 하시면 답변을 등록할 수 있습니다.