티스토리 뷰

728x90

spring boot 개인 프로젝트 진행 중에 google map api 를 사용하게 되었다.

rest templete 이라는 것을 처음에는 몰라서 google map api 를 하나하나씩 Json 파싱을 하였다.

이것을 rest templete 과 Object mapper 를 사용하여 코드를 작성 하니 코드가 훨씬 간결해졌다.

 

이것을 기록하기 위해서 한번 글을 작성하고자 한다.

 

1. RestTemplate 적용

 

RestTemplate 적용하기 위해서는 우선 config 파일을 만들어서 bean 으로 등록해주어야 한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Configuration
@Slf4j
@RequiredArgsConstructor
 
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
        return restTemplateBuilder
                .requestFactory(() -> new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()))
                .setConnectTimeout(Duration.ofMillis(5000)) // connection-timeout
                .setReadTimeout(Duration.ofMillis(5000)) // read-timeout
                .additionalMessageConverters(new StringHttpMessageConverter(Charset.forName("UTF-8")))
                .errorHandler(new RestTemplateResponseErrorHandler())
                .build();
    }
}
 
cs

 

또한 아래와 같이 새로운 class 인 ErrorHandler 를 만들어 준다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {
 
    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
        return response.getStatusCode() == HttpStatus.BAD_REQUEST
                || response.getStatusCode() == HttpStatus.INTERNAL_SERVER_ERROR;
    }
 
    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
 
    }
}
cs

 

위에 두 코드를 모두 작성했다면 RestTemplate 사용하기 위한 작업이 다 끝났다.

 

2. object mapper 를 통하여 json 값 파싱하기

 

UrlComponents 를 통하여 api url 를 만들어 준다. 이것을 rest template exchange 를 통하여 json 파싱을 한다.

exchange 를 할때 마지막 인자로 MapDataObject.class 를 넣어 주었는데, 이 값은 json 파싱을 할때 원하는 DTO 형태로 가져오기 위함이다.

작성한 DTO 는 아래 코드에서 볼수 있으며, 작성된 코드는 여기 에서 참고하여 작성하였다.

 
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
    private final RestTemplate restTemplate;
 
    @Value("${spring.googleMap.key}")
    private String secretKey;
 
    private final static String baseUrl = "https://maps.googleapis.com/maps/api/place/textsearch/json";
    
 
    public MapDataObject.address currentLocation(String address){
        address = address.replace(" ""+").trim();
 
        UriComponents builder = UriComponentsBuilder.fromHttpUrl(baseUrl)
                .queryParam("query", address)
                .queryParam("key", secretKey)
                .queryParam("language""ko").encode().build();
 
        log.info("current address : " + address);
        log.info("current url : " + builder);
 
        return getJsonFromApi(builder);
    }
 
    public MapDataObject.address getJsonFromApi(UriComponents builder) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        return restTemplate.exchange(builder.toUri(), HttpMethod.GET, new HttpEntity<>(headers), MapDataObject.address.class).getBody();
    }
cs

 

또한 api 링크에 language, ko 를 넣어 준 이유는 파싱할때 영문으로 데이터를 가져오는 것을 방지하고자 넣어 주었다.

크롬에서 url 를 통하여 api 테스트를 하면 한글로 나오는데 인텔리제이에서 코드를 실행하면 영문으로 가져오는 현생이 생겼다.

 

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
 
public class MapDataObject {
    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class address{
        private List<addressInfo> results;
        private String status;
    }
 
    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class addressInfo{
        private String formatted_address;
        private geometryInfo geometry;
        private String name;
    }
 
    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class geometryInfo{
        private locationInfo location;
    }
    @Data
    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class locationInfo{
        private double lat;
        private double lng;
    }
}
cs

 

위의 코드는 custom 한 dto 이다.

여기서 원하는 값 외에는 가져오는 것을 방지하고자 @JsonIgnoreProperties(ignoreUnknown = true)  를 넣어 주었다.

이것을 제외하고 코드를 실행하였더니 오류가 발생하였고, api 에 있는 모든 데이터를 넣어 주어야 오류가 해결되었다.

하지만 사용하지 않는 데이터라 가져올 필요성이 없없다. @JsonIgnoreProperties(ignoreUnknown = true)  통하여 원하는 값만 가져 올수 있었다.

 

 

728x90