네이버 클라우드 OCR 사용법

JAVA 네이버 클라우드 OCR 사용법

네이버 클라우드 OCR 정보 추가

Globals.NaverOCR.Url = https://console.ncloud.com/ocr/domain
Globals.NaverOCR.SecretKey = RWVaQUtWcWpOQlZnamZNRml5bG9H~시크릿키~
Globals.NaverOCR.InvokeUrl = https://5gip3zw***.apigw.ntruss.com/custom/v1/34037/6848b40e402f1330f37ae98b6538faa00a95b091eaa50f116515df8ccdf~~~~/general

globals.properties 파일에 네이버 클라우드 OCR 정보를 추가합니다.
시크릿키는 네이버 클라우드 계정으로 발급받아야 합니다.

OCR API 유틸 예시

public class 유틸명 {
  protected static final Logger logger = LoggerFactory.getLogger(ApiService.class);

  static final String ocrSecretKey = EgovProperties.getProperty("Globals.NaverOCR.SecretKey");
  static final String ocrInvokeUrl = EgovProperties.getProperty("Globals.NaverOCR.InvokeUrl");

  public static String callOcrApi(String imagePath) throws Exception {
    // HTTP 요청 타임아웃 설정
    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
    factory.setConnectTimeout(10000); // 10초
    factory.setReadTimeout(60000); // 60초
    RestTemplate restTemplate = new RestTemplate(factory);

    // 헤더 설정
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.set("X-OCR-SECRET", ocrSecretKey);

    // 이미지 형식 및 Base64 변환
    int index = imagePath.lastIndexOf('.');
    String format = (index > -1 && index + 1 < imagePath.length())
            ? imagePath.substring(index + 1).toLowerCase() : "png";
    String uuid = UUID.randomUUID().toString();
    String base64String = encodeImageToBase64(imagePath);

    // 요청 본문 생성
    Map<String, Object> imageInfo = new HashMap<>();
    imageInfo.put("format", format);
    imageInfo.put("name", "ai-book-review-edit-image");
    imageInfo.put("data", base64String);

    Map<String, Object> body = new HashMap<>();
    body.put("images", new Map[]{imageInfo});
    body.put("lang", "ko");
    body.put("requestId", uuid);
    body.put("timestamp", System.currentTimeMillis());
    body.put("version", "V2");

    try {
      // JSON 문자열 변환
      String jsonBody = new ObjectMapper().writeValueAsString(body);
      HttpEntity<String> requestEntity = new HttpEntity<>(jsonBody, headers);

      // 요청 정보 로깅
      logger.debug("OCR API 호출 시작");
      logger.debug("요청 URL: {}", ocrInvokeUrl);
      logger.debug("요청 헤더: {}", headers);
      logger.debug("요청 body: {}", jsonBody);

      // API 호출
      ResponseEntity<String> response = restTemplate.exchange(ocrInvokeUrl, HttpMethod.POST, requestEntity, String.class);

      if (!response.getStatusCode().is2xxSuccessful()) {
        logger.error("OCR API 호출 실패: 상태 코드 = {}, 응답 본문 = {}", response.getStatusCode(), response.getBody());
        throw new IllegalStateException("OCR API 호출 실패: " + response.getStatusCode());
      }

      return response.getBody();

    } catch (HttpClientErrorException | HttpServerErrorException e) {
      // HTTP 응답 오류 로깅
      logger.error("HTTP 오류 발생: 상태 코드 = {}, 응답 본문 = {}", e.getStatusCode(), e.getResponseBodyAsString());
      throw e;
        
    } catch (ResourceAccessException e) {
      // 네트워크 오류 로깅
      logger.error("요청 URL: {}", ocrInvokeUrl);
      logger.error("요청 헤더: {}", headers);
      logger.error("네트워크 오류 유형: {}", e.getCause() != null ? e.getCause().getClass().getName() : "알 수 없음");
      logger.error("OS 정보: {}, 버전: {}", System.getProperty("os.name"), System.getProperty("os.version"));
      logger.error("예외 스택 트레이스:", e);
      throw e;

    } catch (JsonProcessingException e) {
      throw new IllegalArgumentException("요청 본문 생성 중 오류가 발생했습니다.", e);

    } catch (Exception e) {
      // 기타 예외 로깅
      logger.error("요청 URL: {}", ocrInvokeUrl);
      logger.error("요청 헤더: {}", headers);
      throw e;

    }
  }
}

네이버 클라우드 OCR API를 호출하는 유틸 함수 예시입니다.

OCR API 유틸 함수 호출

String resultOCR = 유틸명.callOcrApi(imgPath);
LOGGER.debug("OCR API 결과: {}", resultOCR);

imgPath는 서버의 이미지 경로 문자열입니다.


네이버 클라우드 OCR 에러 해결

연결 거부 오류

org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://5gip3zw***.apigw.ntruss.com/custom/v1/34037/6848b40e402f1330f37ae98b6538faa00a95b091eaa50f116515df8ccdf19ec9/general": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)

5gip3zw**.apigw.ntruss.com 도메인에 대해서 nslookup 시 4개의 IP가 나오는데,
그 중 일부 IP에 대해서 사내 아웃바운드 방화벽이 허용되어 있지 않아 간헐적으로 발생하는 연결 실패 오류였습니다.
방화벽 허용 정책 목적지를 네이버 OCR API 서버 IP가 아니라, 도메인 (
.apigw.ntruss.com)으로 신청하면 해결됩니다.

Leave a comment