API/실습

53. [ JAVA ] Spring Boot를 이용한 API 통신 : 뉴스 검색 예시

천재단미 2025. 1. 11. 13:58
728x90
반응형

 

 

 

 

 

지난 시간에 NAVER API 를 이용하여 세팅을 진행하였습니다. 

이번시간에는  NAVER API 로 Spring Boot를 이용한 API 통신의 예시를 보여드리겠습니다. 

 

세팅 

 

블로그 검색 API 레퍼런스 

  • 블로그 검색 결과 조회

블로그 검색 결과 조회 

설명 

네이버 검색의 블로그 검색 결과를 XML 형식 또는 JSON 형식으로 반환합니다.

 

 

intelliJ

 


application.yml를 하단과 같이 

 

요청 URL 

요청 URL결괏값 반환 형식

https://openapi.naver.com/v1/search/blog.xml XML
https://openapi.naver.com/v1/search/blog.json JSON


참고 사항 

API를 요청할 때 다음 예와 같이 HTTP 요청 헤더에 클라이언트 아이디와 클라이언트 시크릿을 추가해야 합니다.

> GET /v1/search/blog.xml?query=%EB%A6%AC%EB%B7%B0&display=10&start=1&sort=sim HTTP/1.1
> Host: openapi.naver.com
> User-Agent: curl/7.49.1
> Accept: */*
> X-Naver-Client-Id: {애플리케이션 등록 시 발급받은 클라이언트 아이디 값}
> X-Naver-Client-Secret: {애플리케이션 등록 시 발급받은 클라이언트 시크릿 값}
>

 

요청 예 

curl  "https://openapi.naver.com/v1/search/blog.xml?query=%EB%A6%AC%EB%B7%B0&display=10&start=1&sort=sim" \
    -H "X-Naver-Client-Id: {애플리케이션 등록 시 발급받은 클라이언트 아이디 값}" \
    -H "X-Naver-Client-Secret: {애플리케이션 등록 시 발급받은 클라이언트 시크릿 값}" -v

 

 

 



프로토콜 

HTTPS

HTTP 메서드 

GET

파라미터 

파라미터를 쿼리 스트링 형식으로 전달합니다.

파라미터타입필수 여부설명

query String Y 검색어. UTF-8로 인코딩되어야 합니다.
display Integer N 한 번에 표시할 검색 결과 개수(기본값: 10, 최댓값: 100)
start Integer N 검색 시작 위치(기본값: 1, 최댓값: 1000)
sort String N 검색 결과 정렬 방법
- sim: 정확도순으로 내림차순 정렬(기본값)
- date: 날짜순으로 내림차순 정렬

 

 

        URI uri = UriComponentsBuilder
                .fromUriString(naverApiConfig.newsUrl)
                .queryParam("query", keyword)
                .queryParam("display", 20)
                .queryParam("start", 1)
                .queryParam("sort", "date")
                .build()
                .encode()
                .toUri();

        HttpHeaders headers = new org.springframework.http.HttpHeaders();
        headers.set("X-Naver-Client-Id" , naverApiConfig.clientId);
        headers.set("X-Naver-Client-Secret", naverApiConfig.clientSecret);

 

 

Postman

 

 

응답 

응답에 성공하면 결괏값을 XML 형식 또는 JSON 형식으로 반환합니다. XML 형식의 결괏값은 다음과 같습니다.

요소타입설명

rss - RSS 컨테이너. RSS 리더기를 사용해 검색 결과를 확인할 수 있습니다.
rss/channel - 검색 결과를 포함하는 컨테이너. channel 요소의 하위 요소인 title, link, description은 RSS에서 사용하는 정보이며, 검색 결과와는 상관이 없습니다.
rss/channel/lastBuildDate dateTime 검색 결과를 생성한 시간
rss/channel/total Integer 총 검색 결과 개수
rss/channel/start Integer 검색 시작 위치
rss/channel/display Integer 한 번에 표시할 검색 결과 개수
rss/channel/item - 개별 검색 결과. JSON 형식의 결괏값에서는 items 속성의 JSON 배열로 개별 검색 결과를 반환합니다.
rss/channel/item/title String 블로그 포스트의 제목. 제목에서 검색어와 일치하는 부분은 <b> 태그로 감싸져 있습니다.
rss/channel/item/link String 블로그 포스트의 URL
rss/channel/item/description String 블로그 포스트의 내용을 요약한 패시지 정보. 패시지 정보에서 검색어와 일치하는 부분은 <b> 태그로 감싸져 있습니다.
rss/channel/item/bloggername String 블로그 포스트가 있는 블로그의 이름
rss/channel/item/bloggerlink String 블로그 포스트가 있는 블로그의 주소
rss/channel/item/postdate dateTime 블로그 포스트가 작성된 날짜

 

        NaverNewsResponse naverNewsResponse =
                restTemplate.exchange(uri, HttpMethod.GET,
                        new HttpEntity<>(headers),
                        NaverNewsResponse.class)
                        .getBody();

 

오류 코드 

검색 API 블로그 검색의 주요 오류 코드는 다음과 같습니다.

오류 코드HTTP 상태 코드오류 메시지설명

SE01 400 Incorrect query request (잘못된 쿼리요청입니다.) API 요청 URL의 프로토콜, 파라미터 등에 오류가 있는지 확인합니다.
SE02 400 Invalid display value (부적절한 display 값입니다.) display 파라미터의 값이 허용 범위의 값(1~100)인지 확인합니다.
SE03 400 Invalid start value (부적절한 start 값입니다.) start 파라미터의 값이 허용 범위의 값(1~1000)인지 확인합니다.
SE04 400 Invalid sort value (부적절한 sort 값입니다.) sort 파라미터의 값에 오타가 있는지 확인합니다.
SE06 400 Malformed encoding (잘못된 형식의 인코딩입니다.) 검색어를 UTF-8로 인코딩합니다.
SE05 404 Invalid search api (존재하지 않는 검색 api 입니다.) API 요청 URL에 오타가 있는지 확인합니다.
SE99 500 System Error (시스템 에러) 서버 내부에 오류가 발생했습니다. "개발자 포럼"에 오류를 신고해 주십시오.

 

 

403 오류
개발자 센터에 등록한 애플리케이션에서 검색 API를 사용하도록 설정하지 않았다면 'API 권한 없음'을 의미하는 403 오류가 발생할 수 있습니다. 403 오류가 발생했다면 네이버 개발자 센터의 Application > 내 애플리케이션 메뉴에서 오류가 발생한 애플리케이션의 API 설정 탭을 클릭한 다음 검색이 선택돼 있는지 확인해 보십시오.

 

 

intelliJ

 

 

    @GetMapping("/api/v1/news/search")
    public ResponseEntity<NewsSearchResponse>

    getNews(@RequestParam("keyword") String keyword ){
      NewsSearchResponse newsSearchResponse =
              newsService.getNews(keyword);

    //    NewsSearchResponse newsSearchResponse =
     //        newsService.getNews2(keyword);

        return ResponseEntity.status(200).body(newsSearchResponse);
    }

 

 

 

 

 

참고
네이버 오픈API 공통 오류 코드는 "API 공통 가이드"의 '오류 코드'를 참고하십시오.

 

 

검색 API 블로그 검색 구현 예제 

 

다음은 검색 API로 블로그 검색 결과를 조회하는 구현 예제입니다. 검색 API의 다른 작업을 구현하는 방법도 이 구현 예제와 유사하기 때문에 이 구현 예제를 참고하면 검색 API를 구현할 수 있습니다.

  • Java
  • PHP
  • Node.js
  • Python
  • C#

 

참고

샘플 코드에서 YOUR_CLIENT_ID 또는 YOUR-CLIENT-ID에는 애플리케이션을 등록하고 발급받은 클라이언트 아이디 값을 입력합니다.

샘플 코드에서 YOUR_CLIENT_SECRET 또는 YOUR-CLIENT-SECRET에는 애플리케이션을 등록하고 발급받은 클라이언트 시크릿 값을 입력합니다.

 

 

Postman

 

네트워크 API 통신 예시

위에서 언급하였듯이  네트워크 API 통신 두 가지에 대한 예시도 진행하겠습니다. 

 

1. RestTemplate

 

intelliJ

 

  • NewsController
  • NewsService
  • RestTemplateConfig

위 세가지 클래스가  변경이 되고  나머지 dto와 endtity 패키지의 내용은 변경 없이 진행됩니다.

 

 config 패키지  - > RestTemplateConfig 클래스 생성 

 

 

@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate(){

        return new RestTemplate();
    }
}

 

 

    @GetMapping("/api/v1/news/search")
    public ResponseEntity<NewsSearchResponse>

    getNews(@RequestParam("keyword") String keyword ){
      NewsSearchResponse newsSearchResponse =
              newsService.getNews(keyword);


        return ResponseEntity.status(200).body(newsSearchResponse);
    }

 

   public NewsSearchResponse getNews(String keyword){
        //네이버의 뉴스 API 를 호출

        URI uri = UriComponentsBuilder
                .fromUriString(naverApiConfig.newsUrl)
                .queryParam("query", keyword)
                .queryParam("display", 20)
                .queryParam("start", 1)
                .queryParam("sort", "date")
                .build()
                .encode()
                .toUri();

        HttpHeaders headers = new org.springframework.http.HttpHeaders();
        headers.set("X-Naver-Client-Id" , naverApiConfig.clientId);
        headers.set("X-Naver-Client-Secret", naverApiConfig.clientSecret);

        NaverNewsResponse naverNewsResponse =
                restTemplate.exchange(uri, HttpMethod.GET,
                        new HttpEntity<>(headers),
                        NaverNewsResponse.class)
                        .getBody();

        // 우리 서버에 맞는 DTO 로 변환해서 리턴

        NewsSearchResponse newsSearchResponse = new NewsSearchResponse();
        newsSearchResponse.totalCount = naverNewsResponse.total;
        newsSearchResponse.articles = naverNewsResponse.items;
        return newsSearchResponse;
    }

 

 

Postman

 

 

2. WebClient

 

 

intelliJ

 

config 패키지  - > WebClientConfig 클래스 생성 

 

 

@Configuration
public class WebClientConfig {

    @Autowired
    NaverApiConfig naverApiConfig;

    // 네이버 검색용 WebClient
    @Bean
    public WebClient naverWebClient(){
        return WebClient.builder()
                .baseUrl(naverApiConfig.newsUrl)
                .defaultHeader("X-Naver-Client-Id", naverApiConfig.clientId)
                .defaultHeader("X-Naver-Client-Secret", naverApiConfig.clientSecret)
                .build();
    }

 


참고 


카카오 로그인 API 용 WebClient
public WebClient cacaoWebClient(){
 return null;
}

유튜브 검색 API 용 WebClient
public WebClient youtubeWebClient(){
 return null;// 

변경하여 사용가능합니다. 

 

    @GetMapping("/api/v1/news/search")
    public ResponseEntity<NewsSearchResponse>

    getNews(@RequestParam("keyword") String keyword ){
      NewsSearchResponse newsSearchResponse =
              newsService.getNews2(keyword);


        return ResponseEntity.status(200).body(newsSearchResponse);
    }

}

    public NewsSearchResponse getNews2(String keyword){

        URI uri = UriComponentsBuilder
                .fromUriString(naverApiConfig.newsUrl)
                .queryParam("query", keyword)
                .queryParam("display", 20)
                .queryParam("start", 1)
                .queryParam("sort", "date")
                .build()
                .encode()
                .toUri();

        NaverNewsResponse naverNewResponse = naverWebClient
                .get()
                .uri(uri)
                .retrieve()
                .bodyToMono(NaverNewsResponse.class)
                .block();

        // 우리 서버에 맞는 DTO 로 변환
        NewsSearchResponse newsSearchResponse
                = new NewsSearchResponse();
        newsSearchResponse.totalCount = naverNewResponse.total;
        newsSearchResponse.articles = naverNewResponse.items;

        return newsSearchResponse;
    }

 

 

Postman

 

 

728x90
반응형
home top bottom
}