[Spring] Naver Clova API 사용하기

지니·2025년 6월 22일

Spring

목록 보기
9/13
post-thumbnail

이번에 인사 관리 시스템(HR)개발을 진행하게 됐다. 그 중에서 나는 결재 시스템을 담당하게 됐다. 결재 시스템 중에서 영수증 결재 관련된 부분에서 OCR API를 이용하기로 결정했다. 그래서 이 부분과 관련해서 개발한 과정을 포스팅 해보고자 한다.

OCR (Optical Character Recognition)은 광학 문자 인식의 약자로, 이미지나 스캔 문서에 있는 텍스트를 기계가 읽을 수 있는 텍스트 데이터로 변환하는 기술이다. 이러한 OCR 기술을 제공하는 api는 꽤 많은 종류가 있었다.

나는 그 많은 기술 중에서 Naver Clova Api를 사용했다. 내가 우선순위로 둔 것은 한글 인식률이 좋은가? 5초 이내로 영수증을 처리할 수 있는? 공식 문서가 잘 정리되어 있는가? 사용이 쉬운가? 이렇게 4가지다.

이 부분에 대해서는 https://devocean.sk.com/blog/techBoardDetail.do?ID=165524&boardType=techBlog 이 블로그를 참고 했다.

1. API 사용 전 준비 과정


1-1. 이용 신청하기

📢 Naver OCR API
OCR 기술을 사용할 수 있는 설명이 있는 링크이다. 여기를 클릭하면 밑에 사진과 같은 페이지로 넘어가게 되고, 여기에서 이용 신청을 클릭하면 된다.

1-2. key와 url 발급 바기

위의 링크에서 이용 신청을 클릭하면 밑에 그림과 같은 페이지로 이동하게 된다.

특화 모델 생성을 클릭하면 밑에와 같은 페이지로 이동하는데, 여기에서 나는 영수증 사진을 스캔하는 ocr을 사용하려고 했기 때문에 특화 모델 생성에서 영수증을 신청해서 사용했다.

신청을 하면 승인대기중으로 떠 있다가 승인이 되면 승인으로 바뀐다. 승인 받는데 까지 1시간 정도 걸린 것 같다.

이제 위의 사진에서 오른쪽 끝에 옵션에 있는 API Gateway 연동을 클릭하면 밑에와 같은 페이지가 뜰 것이다.
그리고 이 페이지에 Secret KeyAPIGW Invoke URL(나의 전용 API 주소) 이 나오게 된다. 이제 이 2가지를 이용해 OCR API를 사용해 볼 것이다.
(참고로 그냥 자동으로 연결할 수 있으니... 자동으로 연결하는 것을 사용하면 된다. 수동으로 연동하는 경우 설정이 조금 더 복잡하게 되어 있으니 이 부분은 API 문서를 확인하면 된다.)

2. OCR 기술 테스트 하기


우선 코드를 작성하기 전에 이 API가 잘 불러와지는지 Postman으로 확인해봤다. 이 때, headers와 body에 값을 실어서 보내야 하는데 이와 관련된 부분은 네이버 ocr 사용 공식 문서에서 볼 수 있다.

2-1. header에 넣는 정보

(1) url에는 APIGW Invoke URL(나의 전용 API 주소)를 넣어서 post 메서드를 이용해 요청을 보내야 한다.

(2) 헤더에는 어떤 타입으로 정보를 보낼지에 관한 정보와 위에서 발급 받았던 secret key를 넣어주면 된다.

이렇게 postman 사진을 보면 key와 value 부분에 값을 넣어서 보내면 되고, Content-Type에는 어떤 형식을 사용할지 여부를 넣어서 보내주면 된다.

  • json 형식인 경우 : aplication/json
  • multipart 형식인 경우 : multipart/form-data

2-2. body에 넣는 정보

(1) json인 경우

json인 경우 이렇게 실어서 보내주면 된다. 이때, requestId는 내가 임의로 정한 것이다. 그리고 images에서 data 부분에는 Base 64로 변환된 이미지로 보내야 한다!! (이 부분을 간과하고 요청을 보냈다가....자꾸 에러가 발생했다....!ㅎ)

(2) multipart/form-data인 경우

mutipart인 경우에는 message와 file을 위에 처럼 보내면 되고, message 부분에는
version, requestId, timestamp, images(format, name) 정보를 넣어서 보내면 된다.

3. Spring Boot와 연결하기


3-1. application.yml에 설정 정보 넣기

naver:
  service:
    url: ${NAVER_URL}
    secret-key: ${NAVER_SECRET_KEY}

이렇게 yml 파일에 설정한 다음에, 발급받았던 urlsecret_key 정보를 넣어주면 된다.

3-2. Naver OCR Api와 통신하는 코드

@Component
public class NaverOcrApi {

    @Value("${naver.service.url}")
    private String url;

    @Value("${naver.service.secret-key}")
    private String naverSecretKey;

    /* ocr api와 통신 후 결과 값을 반환하는 메서드 */
    public String requestOcrApi(File file, String fileName, String format) {
        try {
            // HTTP 통신을 위해 외부로 데이터를 전송할 때 사용되는 클래스
            RestTemplate restTemplate = new RestTemplate();

            /* message 구성 정보
            * (1) version : 버전 정보
            * (2) requestId : API 호출 UUID
            * (3) timestamp : API 호출 timestamp
            * (4) images
            *     (4-1) format : 파일 형식
            *     (4-2) name : 파일 이름
            * */
            String jsonMessage = new ObjectMapper().writeValueAsString(Map.of(
                    "version", "V2",
                    "requestId", UUID.randomUUID().toString(),
                    "timestamp", System.currentTimeMillis(),
                    "images", List.of(Map.of("format", format, "name", fileName))
            ));

            // 헤더에 실어서 보내줘야 하는 정보 : content-type, secret-key
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            headers.set("X-OCR-SECRET", naverSecretKey);


            // body에 실어서 보내줘야 하는 정보 : message, file
            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            body.add("message", new HttpEntity<>(jsonMessage, createJsonHeader()));
            body.add("file", new FileSystemResource(file));

            // 요청 보내기
            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);

            // 응답을 받아오는 객체
            ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);

            return response.getBody();
        } catch (OcrRequestFailedException | JsonProcessingException e) {
            throw new OcrRequestFailedException(ErrorCode.FAILED_OCR_CALL);
        }
    }

    // message는 json 형식으로 들어가기 때문에 만든 부분
    private HttpHeaders createJsonHeader() {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        return headers;
    }

}

이렇게 api와 통신하는 부분을 작성했다. 그리고 서비스 계층에서는 이렇게 api와 통신해서 가져오는 값을 가공하고, controller와 소통하는 코드를 작성했다.

나는 가게명, 가게주소, 비용, 승인날짜 이렇게 4가지의 정보가 필요했기 때문에 4가지 정보를 가져오는 코드를 작성했다. 이 부분은 각자가 원하는 정보에 맞춰서 데이터를 가공해서 작성하면 된다. 다음 포스팅에서는 이렇게 가져온 api를 바탕으로 어떤식으로 영수증 정보를 가져왔는지 작성해볼 예정이다.

오늘은 이렇게 Naver OCR API를 Spring Boot와 연결하는 과정을 작성했다. 네이버 클로바에는 다양한 유형의 문서를 스캔할 수 있는 api를 제공하고 있으니 ocr을 사용하는 경우 각자의 상황에 맞게 api를 사용하면 좋을 것 같다.

0개의 댓글