(급해요!) 날씨어플을 만들고 있는데 두 가지 질문 드립니다.

이미지 보통 공공데이터포털 동네예보조회 오픈api에 요청을 보내면 응답이 저렇게 옵니다. 응답에 들어있는 각각의 아이템들을 담을 array를 만드는 데까지는 성공했는데, 저 자료들을 다 쓰지 않고 오늘날짜의 06시, 12시, 18시 24시(다음날 00시)의 자료만 출력할 예정이라 그것만 파싱하고 싶습니다.

즉 아이템 항목중 06시 ~ 18시는 if를 걸어서 fcstDate는 baseDate(GrergorianCalendar와 SimpleDateFormat를이용해서 구합니다.) 와 같은 것만, 다시 그중에서 fcstDate가 0600, 1200, ..., 의 값을 가지는 아이템들만 파싱하도록 하고 24시의 fcstDate는 오늘날짜보다 1보다 큰 값을 가지고 fcstTime이 "0000"인 아이템의 항목들을 파싱하도록 하고 싶습니다.

그런 식으로 코드를 짜 보았는데 null값이 뜨는 에러가 생기네요. 인터넷에 찾아봐도 날씨 오픈 api관련 예제에는 fcstDate와 fcstTime을 이용해서 특정 아이템들만 파싱하는 구문이 없길래 직접 만들었는데 뭐가 맞지 않는 것 같습니다.

json type으로 받은 후 jsonarray를 이용해서 저장합니다. 주석은 무시해주세요.(인터넷 예제를 바탕으로 하였기에 주석과 안맞을수도 있어요. // 이하 코드부분

dail_listJson.java

public class daily_list {

String baseDate;
String baseTime;

String fcstDate0;
String fcstDate1;

String fcstTime_06;
String pop_06;
String pty_06;
String r06_06;
String sky_06;
String t3h_06;

String fcstTime_12;
String pop_12;
String pty_12;
String r06_12;
String sky_12;
String t3h_12;

String fcstTime_18;
String pop_18;
String pty_18;
String r06_18;
String sky_18;
String t3h_18;

String fcstTime_24;
String pop_24;
String pty_24;
String r06_24;
String sky_24;
String t3h_24;

public String getBaseDate() {
    return baseDate;
}

public void setBaseDate(String baseDate) {
    this.baseDate = baseDate;
}
public String getBaseTime() {
    return baseTime;
}
public void setBaseTime(String baseTime) {
    this.baseTime = baseTime;
}
public String getFcstDate0() {
    return fcstDate0;
}
public void setFcstDate0(String fcstDate0) {
    this.fcstDate0 = fcstDate0;
}
public String getFcstDate1() {
    return fcstDate1;
}
public void setFcstDate1(String fcstDate1) {
    this.fcstDate1 = fcstDate1;
}
public String getFcstTime_06() {
    return fcstTime_06;
}

public void setFcstTime_06(String fcstTime_06) {
    this.fcstTime_06 = fcstTime_06;
}

public String getPop_06() {
    return pop_06;

}

public void setPop_06(String pop_06) {
    this.pop_06 = pop_06;    }

public String getPty_06() {
    return pty_06;
}

public void setPty_06(String pty_06) {
    this.pty_06 = pty_06;
}

public String getR06_06() {
    return r06_06;
}

public void setR06_06(String r06_06) {
    this.r06_06 = r06_06;

}
public String getSky_06() {
    return sky_06;

}
public void setSky_06(String sky_06) {
    this.sky_06 = sky_06;
}
public String getT3h_06() {
    return t3h_06;
}

public void setT3h_06(String t3h_06) {
    this.t3h_06 = t3h_06;
}
public String getFcstTime_12() {
    return fcstTime_12;
}
public void setFcstTime_12(String fcstTime_12) {
    this.fcstTime_12 = fcstTime_12;
}
public String getPop_12() {
    return pop_12;
}
public void setPop_12(String pop_12) {
    this.pop_12 = pop_12;
}
public String getPty_12() {
    return pty_12;
}
public void setPty_12(String pty_12) {
    this.pty_12 = pty_12;
}
public String getR06_12() {
    return r06_12;
}
public void setR06_12(String r06_06) {
    this.r06_12 = r06_12;
}
public String getSky_12() {
    return sky_12;
}
public void setSky_12(String sky_12) {
    this.sky_12 = sky_12;
}
public String getT3h_12() {
    return t3h_12;
}
public void setT3h_12(String t3h_12) {
    this.t3h_12 = t3h_12;
}

public String getFcstTime_18() {
    return fcstTime_18;
}
public void setFcstTime_18(String fcstTime_18) {
    this.fcstTime_18 = fcstTime_18;
}
public String getPop_18() {
    return pop_18;
}
public void setPop_18(String pop_18) {
    this.pop_18 = pop_18;
}
public String getPty_18() {
    return pty_18;
}
public void setPty_18(String pty_18) {
    this.pty_18 = pty_18;
}
public String getR06_18() {
    return r06_18;
}
public void setR06_18(String r06_18) {
    this.r06_18 = r06_18;
}
public String getSky_18() {
    return sky_18;
}
public void setSky_18(String sky_18) {
    this.sky_18 = sky_18;
}
public String getT3h_18() {
    return t3h_06;
}
public void setT3h_18(String t3h_18) {
    this.t3h_18 = t3h_18;
}

public String getFcstTime_24() {
    return fcstTime_24;
}
public void setFcstTime_24(String fcstTime_24) {
    this.fcstTime_24 = fcstTime_24;
}
public String getPop_24() {
    return pop_24;
}
public void setPop_24(String pop_24) {
    this.pop_24 = pop_24;
}
public String getPty_24() {
    return pty_24;
}
public void setPty_24(String pty_24) {
    this.pty_24 = pty_24;
}
public String getR06_24() {
    return r06_24;
}
public void setR06_24(String r06_24) {
    this.r06_24 = r06_24;
}
public String getSky_24() {
    return sky_24;
}
public void setSky_24(String sky_24) {
    this.sky_24 = sky_24;
}
public String getT3h_24() {
    return t3h_24;
}
public void setT3h_24(String t3h_24) {
    this.t3h_24 = t3h_24;
}
}

daily_listJSON.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class daily_listJSON {
    final static String serviceKey = "KmuN74waxVR22ZA96tDJj8VOl0r5SD3YD8MntKdvnmJ3CA1oWXciQgyFgC4yL0QWNkj2WnUiRJydu2Iwv0DzQw%3D%3D";

    public daily_list getdaily_list(String baseDate_daily, String baseTime_daily, int x, int y) {
        // JSON데이터를 요청하는 URLstr을 만듭니다.
        String urlStr = "http://newsky2.kma.go.kr/service/SecndSrtpdFrcstInfoService2/ForecastSpaceData?"
                + "serviceKey=" + serviceKey + "&base_date=" + baseDate_daily + "&base_time=" + baseTime_daily
                + "&nx=" + x + "&ny=" + y + "&_type=json";
        OkHttpClient client = new OkHttpClient();


        Request request = new Request.Builder()
                .url(urlStr)
                .build();

        Response response = null;
        try {
            response = client.newCall(request).execute();
        } catch (Exception e) {
            e.printStackTrace();
        }

        daily_list dl = new daily_list(); // 결과 데이터를 저장할 동내기상객체를 만듭니다.
        try {
            URL url = new URL(urlStr); // 완성된 urlStr을 사용해서 URL 만들어 해당 데이터를 가져옵니다.
            BufferedReader bf = new BufferedReader(new InputStreamReader(url.openStream()));
            String line = "";
            String result = "";
            //버퍼에 있는 정보를 문자열로 변환.
            while ((line = bf.readLine()) != null) { //bf 에 있는값을 읽어와서 하나의 문자열로 만듭니다.
                result = result.concat(line);
            }
            //System.out.println(result);

            //문자열을 JSON으로 파싱합니다. 마지막 배열형태로 저장된 데이터까지 파싱해냅니다.
            JSONParser jsonParser = new JSONParser();
            JSONObject jsonObj = (JSONObject) jsonParser.parse(result);
            JSONObject parse_response = (JSONObject) jsonObj.get("response");
            JSONObject parse_body = (JSONObject) parse_response.get("body");
            JSONObject parse_items = (JSONObject) parse_body.get("items");
            for (int j = 0; j < parse_items.size(); j++) {
                JSONArray parse_item = (JSONArray) parse_items.get("item");
                JSONObject obj;
                String category;
                String fcstDate;
                String fcstTime;

                dl.baseDate = baseDate_daily;
                dl.baseTime = baseTime_daily;
                for (int i = 0; i < parse_item.size(); i++) {
                    obj = (JSONObject) parse_item.get(i);
                    category = (String) obj.get("category");
                    //먼저 모든 itmes에 대해 fcstDate와 fcstTime부터 구하기
                    fcstDate = obj.get("fcstDate").toString();
                    fcstTime = obj.get("fcstTime").toString();

                    Date date = new Date(System.currentTimeMillis());
                    Calendar calfcst = new GregorianCalendar();
                    calfcst.setTime(date);
                    calfcst.add(Calendar.DAY_OF_MONTH, +1);
                    SimpleDateFormat tommrrow = new SimpleDateFormat("yyyyMMdd");
                    String fcst_tommrrow = tommrrow.format(calfcst.getTime());

                    if (fcstDate.equals(dl.baseDate)) {
                        dl.fcstDate0 = fcstDate;
                        switch (fcstTime) {
                            case "0600":
                                dl.fcstTime_06 = fcstTime;
                                switch (category) {
                                    case "POP":
                                        dl.pop_06 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "PTY":
                                        dl.pty_06 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "R06":
                                        dl.r06_06 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "SKY":
                                        dl.sky_06 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "T3H":
                                        dl.t3h_06 = (obj.get("fcstValue")).toString();
                                        break;
                                }
                                break;
                            case "1200":
                                dl.fcstTime_12 = fcstTime;
                                switch (category) {
                                    case "POP":
                                        dl.pop_12 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "PTY":
                                        dl.pty_12 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "R06":
                                        dl.r06_12 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "SKY":
                                        dl.sky_12 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "T3H":
                                        dl.t3h_12 = (obj.get("fcstValue")).toString();
                                        break;
                                }
                                break;
                            case "1800":
                                dl.fcstTime_18 = fcstTime;
                                switch (category) {
                                    case "POP":
                                        dl.pop_18 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "PTY":
                                        dl.pty_18 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "R06":
                                        dl.r06_18 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "SKY":
                                        dl.sky_18 = (obj.get("fcstValue")).toString();
                                        break;
                                    case "T3H":
                                        dl.t3h_18 = (obj.get("fcstValue")).toString();
                                        break;
                                }
                                break;
                        }
                    } else if (fcstDate.equals(fcst_tommrrow) && fcstTime.equals("0000")) {
                        dl.fcstDate1 = baseDate_daily;
                        dl.fcstTime_24 = "2400";
                        switch (category) {
                            case "POP":
                                dl.pop_24 = (obj.get("fcstValue")).toString();
                                break;
                            case "PTY":
                                dl.pty_24 = (obj.get("fcstValue")).toString();
                                break;
                            case "R06":
                                dl.r06_24 = (obj.get("fcstValue")).toString();
                                break;
                            case "SKY":
                                dl.sky_24 = (obj.get("fcstValue")).toString();
                                break;
                            case "T3H":
                                dl.t3h_24 = (obj.get("fcstValue")).toString();
                                break;
                        }
                    }
                }
            }
        }
        catch(MalformedURLException e){
            System.out.println("MalformedURLException : " + e.getMessage());
        } catch(IOException e){
            System.out.println("IOException : " + e.getMessage());
        } catch(ParseException e){
            System.out.println("ParseException : " + e.getMessage());
        }
        return dl;
    }
}

다시 말하지만 조건에 맞는(fcstDate와 fcstTime이 주어진 연산에 맞는가) 데이터만 있으면 됩니다.

  • 결과가 xml이에요? json이에요? 정영훈 2018.6.9 08:52

1답변

  • 음...groovy 를 추천드리고 싶네요.

    bean 코딩한 것(set/get) 보고 있으니까 현기증이 다 납니다.

    groovy 는 jvm에서 동작하므로 컴파일하면 class 가 생성됩니다.

    구체적인 학습은 시간내서 해보시고요,

    groovy가 설치되어 있다면...

    groovysh 명령어로 groovy shell 을 실행합니다.

    groovy:000> import groovy.json.*
    ===> groovy.json.*
    groovy:000> url = "http://newsky2.kma.go.kr/service/SecndSrtpdFrcstInfoService2/ForecastSpaceData?serviceKey=KmuN74waxVR22ZA96tDJj8VOl0r5SD3YD8MntKdvnmJ3CA1oWXciQgyFgC4yL0QWNkj2WnUiRJydu2Iwv0DzQw%3D%3D&base_date=20180610&base_time=0200&nx=98&ny=77&_type=json"
    ===> http://newsky2.kma.go.kr/service/SecndSrtpdFrcstInfoService2/ForecastSpaceData?serviceKey=KmuN74waxVR22ZA96tDJj8VOl0r5SD3YD8MntKdvnmJ3CA1oWXciQgyFgC4yL0QWNkj2WnUiRJydu2Iwv0DzQw%3D%3D&base_date=20180610&base_time=0200&nx=98&ny=77&_type=json
    groovy:000> json = new JsonSlurper().parseText(url.toURL().text)
    ===> [response:[body:[items:[item:[[baseDate:20180610, baseTime:0200, category:R06, fcstDate:20180610, fcstTime:0600, fcstValue:0, nx:98, ny:77], [baseDate:20180610, baseTime:0200, category:REH, fcstDate:20180610, fcstTime:0600, fcstValue:-, nx:98, ny:77], [baseDate:20180610, baseTime:0200, category:S06, fcstDate:20180610, fcstTime:0600, fcstValue:0, nx:98, ny:77], [baseDate:20180610, baseTime:0200, category:REH, fcstDate:20180610, fcstTime:0900, fcstValue:-, nx:98, ny:77], [baseDate:20180610, baseTime:0200, category:R06, fcstDate:20180610, fcstTime:1200, fcstValue:0, nx:98, ny:77], [baseDate:20180610, baseTime:0200, category:REH, fcstDate:20180610, fcstTime:1200, fcstValue:-, nx:98, ny:77], [baseDate:20180610, baseTime:0200, category:S06, fcstDate:20180610, fcstTime:1200, fcstValue:0, nx:98, ny:77], [baseDate:20180610, baseTime:0200, category:REH, fcstDate:20180610, fcstTime:1500, fcstValue:-, nx:98, ny:77], [baseDate:20180610, baseTime:0200, category:R06, fcstDate:20180610, fcstTime:1800, fcstValue:0, nx:98, ny:77], [baseDate:20180610, baseTime:0200, category:REH, fcstDate:20180610, fcstTime:1800, fcstValue:-, nx:98, ny:77]]], numOfRows:10, pageNo:1, totalCount:31], header:[resultCode:0000, resultMsg:OK]]]
    groovy:000> json.response.body.items.item.find {i -> i.fcstTime == 1200 }
    ===> [baseDate:20180610, baseTime:0200, category:R06, fcstDate:20180610, fcstTime:1200, fcstValue:0, nx:98, ny:77]
    groovy:000> json.response.body.items.item.find {i -> i.fcstTime == 1200 }.baseDate
    ===> 20180610
    groovy:000> item = json.response.body.items.item.find {i -> i.fcstTime == 1200 }
    ===> [baseDate:20180610, baseTime:0200, category:R06, fcstDate:20180610, fcstTime:1200, fcstValue:0, nx:98, ny:77]
    groovy:000> item.fcstTime
    ===> 1200
    

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

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