개인프로젝트/기능프로그램_오늘뭐입지

20240519_퍼센트 인코딩

일일일코_장민기 2024. 5. 19. 15:58
728x90

 

 

 

이전 미세먼지 API를 사용했을 때 URL을 생성하기 위해서는 지역 이름을 퍼센트 인코딩해야 하는 경우가 발생했다.

 

왜 이런 작업이 발생하는지 확인하고 기능을 구현하는 시간을 가졌다.

 

 

1. 퍼센트 인코딩

- 글자를 url에서 인식할 수 있는 아스키코드로 변환하는 것

- %OO이라는 형태를 가진다.

 

2. 퍼센트 인코딩을 하는 이유

- 인터넷을 통해 전송할 수 있는 문자는 오직 ASCII 문자이기 때문

--> 안 그러면 수만 개의 언어를 대응하는 비효율성이 발생한다

- 한글을 변환하는 규칙은 UTF-8을 따른다.

- 한글은 문자 1개 당 3바이트로 인코딩 

 

3. 예시

https://it-eldorado.tistory.com/143

 

4. 퍼센트 인코딩 하기

자바에서 자체적으로 기능을 지원해준다.

 

A. js

console.log(`[경기] 글자의 퍼센트 인코딩: ${encodeURIComponent('경기')}`)

똑같이 출력되고 있다.

B. java

String encodeResult = URLEncoder.encode(바꿀 String, "utf-8");

역시 똑같이 출력되고 있다.

 

 

그럼 실제 코드에 제대로 적용을 해보자

 

url 인코딩에 필요한 country 들은 Weatherareavo의 country 컬럼에 들어있다.

이걸 부르고 인코딩된 데이터만 리스트에 넣은 다음 차례로 url을 넘기는 기능을 구현할 것이다.

 

더보기

Weatherareavo

//퍼센트 인코딩
public String getEncodedCountry(){
    return URLEncoder.encode(country, StandardCharsets.UTF_8);
}

 

 WeatherApiService

public List<String> findAllCountry() {
        List<Weatherareavo> list = weatherApiRepository.findAll();
        return list.stream().map(Weatherareavo::getEncodedCountry).distinct().toList();
    }

 

 DustApiController

@PostConstruct
public void init()  throws IOException, JSONException {

        List<String> encodedCounties = weatherApiService.findAllCountry();

        for(String country : encodedCounties){

            //Url 생성
            String stringUrl =
                    "http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getCtprvnRltmMesureDnsty" +
                            "?sidoName=" + country +
                            "&pageNo=" + "1" +
                            "&numOfRows=" + "100" +
                            "&returnType=" + "json" +
                            "&serviceKey=" + apiKey +
                            "&ver=" + "1.0";

            //HTTP Request
            URL url = new URL(stringUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");

            //응답코드 확인
            //log.info("Response Code: {}", connection.getResponseCode());

            //응답 처리
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String response = String.join("/n", bufferedReader.lines().toList());
            bufferedReader.close();
            connection.disconnect();

            //JSON 데이터 출력
            //log.info("Response: {}", response);

            //JSON 데이터에서 필요한 데이터 추출
            JSONObject jsonObject = new JSONObject(response);
            JSONObject items = jsonObject.getJSONObject("response").getJSONObject("body");
            JSONArray itemsArray = items.getJSONArray("items");

            List<PaticulatemattervoDto> paticulateMatterList = new ArrayList<>();
            for (int i = 0; i < itemsArray.length(); i++) {
                JSONObject item = itemsArray.getJSONObject(i);
                PaticulatemattervoDto paticulatemattervoDto = new PaticulatemattervoDto(
                        item.getString("sidoName"), item.getString("dataTime"), item.getString("stationName"),
                        item.getString("pm25Grade"), item.getString("pm25Flag"), item.getString("pm25Value"),
                        item.getString("pm10Grade"), item.getString("pm10Flag"), item.getString("pm10Value")
                );
                paticulateMatterList.add(paticulatemattervoDto);
            }

            //List에 들어간 데이터 확인
            //log.info("particulateMatterList: {}", paticulateMatterList.toString());

            dustApiService.dustRequest(paticulateMatterList);

        }

 

 

 

 

데이터가 인코딩되어 리스트에 저장된 모습
기존의 125개 뿐이었던 경기 지역의 미세먼지 데이터 뿐만 아니라 다른 지역의 데이터도 잘 불러왔다.