Java HttpURLConnection함수로 post방식인 페이지를 파싱하고 싶습니다.

어제 ajax로 구현된 페이지를 파싱하기 위해 이동 페이지 주소와 파라메터 입력방식에 대해 질문을 드렸습니다. 그리고 'GreppTod'님께서 좋은 답변을 해주셨습니다. 위 답변을 바탕으로 자바 코드를 수정하였는데 html 코드를 읽다가 java.io.IOException: Premature EOF 에러가 발생하여 동적인 부분을 가져오지 못하더라구요. 그래서 한번 더 고수님들의 도움을 얻기위해 이렇게 글을 쓰게 되었습니다. 이전 질문 페이지로 바로가기

우선 이전 답변에서 얻은 Payload에 들어가는 JSON 형태입니다.

{pName: ["YEAR", "TERM", "DEPTCD", "CULTCD", "GUBUN"], pValue: ["2016", "10", "", "11750", "3"]}

아래는 위 json 형태를 보고 새롭게 파라메터 부분을 수정한 코드입니다.


private static String getHttpHTML_POST() {
        String url="http://e-onestop.pusan.ac.kr/middleware/curriculum/college/CollegeAssignInfoSearch";
        String result="";  
          try {
           URL object=new URL(url);

           HttpURLConnection con = (HttpURLConnection) object.openConnection();

           con.setDoOutput(true);
           con.setDoInput(true);
           con.setRequestProperty("Cache-Control", "no-cache");
           con.setRequestProperty("Content-Type", "application/json");
           con.setRequestProperty("Accept", "application/json");

           con.setRequestProperty("Accept", "*/*");
           con.setRequestProperty("X-Requested-With", "XMLHttpRequest");
           con.setRequestMethod("POST");


           JSONObject json = new JSONObject();
           JSONArray data1 = new JSONArray();
           JSONArray data2 = new JSONArray();
           data1.add("YEAR");
           data1.add("TERM");
           data1.add("DEPTCD");
           data1.add("CULTCD");
           data1.add("GUBUN");
           json.put("pName",data1);
           data2.add("2016");
           data2.add("10");
           data2.add("");
           data2.add("11750");
           data2.add("1");
           json.put("pValue",data2);

           OutputStreamWriter wr= new OutputStreamWriter(con.getOutputStream());
           wr.write(json.toString());
           wr.flush();

           //display what returns the POST request

           int HttpResult =con.getResponseCode(); 
           if(HttpResult ==HttpURLConnection.HTTP_OK){
               BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(),"utf-8"));  
               String line = null;  
               line = br.readLine();

               while ((line = br.readLine())!= null) {  
                   result = result+line + "\n"; 
                   System.out.println(line+"\n");
               }  
               br.close();  
           }else{
               System.out.println(con.getResponseMessage());  
            }  
          }
          catch (Exception e) {
           e.printStackTrace();
          }
          finally {

          }

          return result;

    }
  • java.io.IOException: Premature EOF 가 올려주신 코드의 어느 부분에서 발생하나요? 정두식_미승인계정 2016.4.8 15:46
  • readLine함수에서 발생합니다 윤준상 2016.4.8 17:37
  • HTTP 전송 스킴때문에 문제가 발생할 수도 있습니다. 가령 서버에서 Content-Length를 알리지 않고 전송하는 경우인데, readLine말고 char[] 혹은 byte[]로 직접 데이터를 읽어서 캐쉬한 후에 처리해보세요. 허대영(Daeyoung Heo) 2016.4.11 10:35

1답변

  • Java로 post를 시뮬리에션 하고 싶으면 apache라이브러리를 쓰는게 좋을것 같습니다. 여기를 보니까 방법이 나오는데요. 코드를 조금 수정하니 잘 동작 하네요.

    apache에 가서 HttpClient와 HttpCore라이브러리를 다운로드 받은 다음에 실행하니 잘 동작합니다.

    import java.util.ArrayList;
    import java.util.List;
    import org.apache.http.Consts;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.util.EntityUtils;
    public class Main {
    
        public static void main(String[] args) {
            String url = "http://httpbin.org/post";
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);
    
            // set the parameters
            List <NameValuePair> nvps = new ArrayList<NameValuePair>();
            nvps.add(new BasicNameValuePair("username", "edwin"));
            nvps.add(new BasicNameValuePair("password", "dodol"));
    
            // set the encoding
            httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
    
            System.out.println("ABC");
    
            // send the http request and get the http response
            try {
                HttpResponse response = httpclient.execute(httpPost);
                HttpEntity resEntity = response.getEntity();
                System.out.println(EntityUtils.toString(resEntity));
            }catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    테스트는 http://httpbin.org 에서 했는데요. http://httpbin.org/post로 요청을 날리면 Post data를 return해 줍니다.


    추가 답변

    하나의 key에 value를 array로 넣고 싶으면 이렇게 하면 됩니다.

    nvps.add(new BasicNameValuePair("username", "edwin"));
    nvps.add(new BasicNameValuePair("username", "abc"));
    

    그러면 요청이 "username": [ "edwin", "abc" ] 이렇게 나가요.

    • 복수의 value는 어떻게 넣나요 윤준상 2016.4.8 17:37
    • 답변을 수정했습니다. 정두식_미승인계정 2016.4.8 17:50
    • 아래와 같이 입력했는데도 안되네요. 다른 페이지는 되는데 저가 파싱하는 페이지를 잘못보고 있는 걸까요? nvps.add(new BasicNameValuePair("pName","YEAR") ); nvps.add(new BasicNameValuePair("pValue","2016")); nvps.add(new BasicNameValuePair("pName", "TERM")); nvps.add(new BasicNameValuePair("pValue","10")); nvps.add(new BasicNameValuePair("pName","DEPTCD")); nvps.add(new BasicNameValuePair("pValue","")); nvps.add(new BasicNameValuePair("pName", "CULTCD")); nvps.add(new BasicNameValuePair("pValue","11750")); nvps.add(new BasicNameValuePair("pName", "GUBUN") ); nvps.add(new BasicNameValuePair("pValue","1")); 윤준상 2016.4.8 19:35
    • 자바 코드를 작성하기 전에 동작하는 Post 요청을 확인하는게 먼저입니다. 코드는 그 다음에 작성하세요.https://www.hurl.it/ 과 같은 사이트에서 post요청을 이렇게 저렇게 시도해서 동작하는 형식을 확인해 보세요. 그 다음에 그걸 자바 코드로 옮기는게 좋겠습니다. 어떻게 요청을 날려야 하는지도 모르고, Java코드도 익숙하지 않은 상태에서 두가지 문제를 풀려고 하니 더 어렵게 느껴지는것 같네요. 정두식_미승인계정 2016.4.11 11:18

ᕕ( ᐛ )ᕗ
로그인이 필요합니다

작성한 답변에 다른 개발자들이 댓글을 작성하거나 댓글에 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.