커스텀 축하 카드 쇼핑몰 [축하해요]

네이버 단축 url api 사용하기

yebin0322 2025. 1. 6. 19:02
반응형

https://developers.naver.com/docs/utils/shortenurl/

우선 애플리케이션 등록을 해 주어야 한다. 나는 이전에 등록해 둔 것이 있어서 그 Client Secret값을 사용했었는데, 이 값을 그대로 사용하면 안된다. shortenURL과 관련된 값이 아니기 때문이다ㅠㅠ 꼭 'Naver-OpenAPI-shortenURL-TEST'로 발급받아서 사용해 주어야 한다.

사용법

get 요청 : https://openapi.naver.com/v1/util/shorturl
post 요청(json type) : https://openapi.naver.com/v1/util/shorturl.json

위의 주소로 각각 일치하는 요청을 보내주면 된다. 단, 헤더에 Client-Id값과 Client-Secret값을 넣어 주어야 한다.

그럼 응답 값이 JSON으로 받아져서 온다.

포스트맨으로 테스트 해 보면 다음과 같다. 나는 GET요청을 사용해 주었다.

  1. Header 설정
    기본적으로 hidden값으로 들어가 있기 때문에 그 설정을 그대로 유지해 주면 되고, key값에 client-id값과 client-secret값을 아래 이름대로 넣어주고 value값에는 위에서 발급받은 값을 넣어준다.
  1. Query Params 설정
    key값에 url을 넣고, value값에 단축하고 싶은 url을 넣어주면 응답이 json으로 온다.

구현 코드

ShortUrlController

package com.choikang.chukahaeyo.card.url;

import com.choikang.chukahaeyo.exception.ErrorCode;
import com.choikang.chukahaeyo.exception.model.CustomException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequiredArgsConstructor
@RequestMapping("/url")
public class ShortUrlController {
    private final ShortUrlService shortUrlService;

    @GetMapping("/origin")
    @ResponseBody
    public String url() {
        return "http://3.36.97.132:9090/payments/success"; // test용으로 URL을 미리 넣어둔 것. 추후 사용자별 카드 URL로 변경 예정
    }

    @GetMapping("/shorts")
    @ResponseBody
    public String shortUrl(@RequestParam int cardID) {
        try {
            return shortUrlService.shortUrl(cardID);
        } catch (Exception e) {
            throw new CustomException(ErrorCode.INTERNAL_SERVER_ERROR, "short URL 응답 생성 실패");
        }
    }
}

ShortUrlDTO

package com.choikang.chukahaeyo.card.url;

import com.choikang.chukahaeyo.card.model.CardVO;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class ShortUrlDTO {
    private String cardUrl; //단축 url
    private String cardQR;

    public static CardVO of(ShortUrlDTO shortUrlDTO) {
        CardVO cardVO = new CardVO();
        cardVO.setCardURL(shortUrlDTO.getCardUrl());
        cardVO.setCardQR(shortUrlDTO.getCardQR());
        return cardVO;
    }
}

ShortUrlService

package com.choikang.chukahaeyo.card.url;

import com.choikang.chukahaeyo.card.CardMapper;
import com.choikang.chukahaeyo.card.model.CardVO;
import com.choikang.chukahaeyo.exception.ErrorCode;
import com.choikang.chukahaeyo.exception.model.CustomException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
@Slf4j
@RequiredArgsConstructor
public class ShortUrlService {
    @Value("${my.naver.client-id}")
    private String clientId;

    @Value("${my.naver.client-secret}")
    private String clientSecret;

    private final RestTemplate restTemplate;
    private final CardMapper cardMapper;

    public String shortUrl(int cardID) { // originUrl을 네이버 API로 보내는 메소드
        try {

            String url = "http://3.36.97.132:9090/card/completedCard/" + cardID; //카드 url
            String apiUrl = "https://openapi.naver.com/v1/util/shorturl?url=" + url; // API url

            // 헤더 설정
            HttpHeaders headers = new HttpHeaders();
            headers.set("X-Naver-Client-Id", clientId);
            headers.set("X-Naver-Client-Secret", clientSecret);

            // HttpEntity 객체 생성 (본문 없이 헤더만 포함)
            HttpEntity<String> entity = new HttpEntity<>(headers);

            // GET 요청 보내기
            ResponseEntity<String> responseEntity = restTemplate.exchange(apiUrl, HttpMethod.GET, entity, String.class);

            if (responseEntity.getStatusCode() == HttpStatus.OK) { // 응답이 성공적으로 반환되었으면
                // 응답 본문을 JSON 형태로 변환하여 필요한 데이터 추출
                String responseBody = responseEntity.getBody();
                JSONParser jsonParser = new JSONParser();
                JSONObject jsonObject = (JSONObject) jsonParser.parse(responseBody);
                JSONObject resultObject = (JSONObject) jsonObject.get("result");
                String shortUrl = (String) resultObject.get("url");

                //DB 저장
                ShortUrlDTO shortUrlDTO = new ShortUrlDTO();
                shortUrlDTO.setCardUrl(shortUrl);
                shortUrlDTO.setCardQR(shortUrl + ".qr");

                CardVO cardVO = ShortUrlDTO.of(shortUrlDTO);
                cardMapper.insertUrl(cardVO);
                return shortUrl;
            } else {
                throw new CustomException(ErrorCode.INTERNAL_SERVER_ERROR, "URL 단축에 실패했습니다.");
            }
        } catch (ParseException e) {
            throw new CustomException(ErrorCode.INTERNAL_SERVER_ERROR, "JSON 응답 파싱에 실패했습니다.");
        } catch (Exception e) {
            throw new CustomException(ErrorCode.INTERNAL_SERVER_ERROR, ErrorCode.INTERNAL_SERVER_ERROR.getMessage());
        }
    }
}
 

 

반응형