유틸리티 가이드
유틸리티 패키지 위치
com.scraping.agent.global.util/
com.scraping.agent.global.constant/
현재 유틸리티 클래스
FingerprintUtils
뉴스 아이템의 중복 수집 방지를 위한 SHA-256 해시 생성 유틸리티.
// com.scraping.agent.global.util.FingerprintUtils
public final class FingerprintUtils {
private FingerprintUtils() {} // 인스턴스 생성 방지
public static String sha256(String value) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashed = digest.digest(value.getBytes(StandardCharsets.UTF_8));
return HexFormat.of().formatHex(hashed);
} catch (Exception e) {
throw new IllegalStateException("fingerprint 생성 실패", e);
}
}
}
사용 예:
// 뉴스 URL을 해시로 변환하여 중복 저장 방지
String fingerprint = FingerprintUtils.sha256(newsUrl);
if (collectedItemRepository.existsByFingerprint(fingerprint)) {
return; // 이미 수집된 항목
}
현재 상수 클래스
CategoryConstant
뉴스/컨텐츠 카테고리 관련 상수.
// com.scraping.agent.global.constant.CategoryConstant
public class CategoryConstant {
private CategoryConstant() {}
public static final String AI = "AI";
public static final String BACKEND = "BACKEND";
public static final String DEVOPS = "DEVOPS";
public static final String JOB = "JOB";
// ...
}
CodeConstant
공통 코드 관련 상수.
CollectConstant
뉴스 수집 관련 상수 (수집 URL, 수집 주기 등).
PagingConstant
페이징 관련 상수.
// com.scraping.agent.global.constant.PagingConstant
public class PagingConstant {
private PagingConstant() {}
public static final int DEFAULT_SIZE = 10;
public static final int MAX_SIZE = 100;
}
상수 관리 규칙
상수 클래스 작성 규칙
// 패키지: com.scraping.agent.global.constant
// 파일: {도메인명}Constant.java
public class PostConstant {
private PostConstant() {} // 인스턴스 생성 방지
public static final String STATUS_PUBLISHED = "PUBLISHED";
public static final String STATUS_DRAFT = "DRAFT";
public static final int MAX_TITLE_LENGTH = 200;
}
하드코딩 금지 대상
| 항목 | 올바른 처리 |
|---|---|
상태값 ("A", "I") | Constant 또는 Enum |
| 메시지 문자열 | Constant |
| 페이지 크기, 재시도 횟수 | Constant |
| API URL | application.yml 환경변수 |
| 파일 경로 | Constant 또는 환경변수 |
새 유틸리티 추가 가이드
global/util/아래에{기능}Utils.java파일 생성final클래스,private생성자 사용- 모든 메서드를
static으로 선언 - 단일 책임 원칙: 하나의 유틸 클래스는 하나의 목적만 담당
public final class DateUtils {
private DateUtils() {}
public static String format(LocalDateTime dt) {
return dt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
}
public static LocalDateTime parseOrNull(String value) {
try {
return LocalDateTime.parse(value, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
} catch (Exception e) {
return null;
}
}
}
SlackService (global/slack/)
에러 및 배치 결과 알림 서비스. 직접 호출하지 않고 GlobalExceptionHandler를 통해 자동 발송된다.
// 직접 호출 패턴 (배치 실패 시)
slackService.sendBatchFail("DigestScheduler", exception);
// 서버 시작/종료는 SlackEventListener가 자동 처리
제공 메서드:
| 메서드 | 용도 |
|---|---|
sendError(uri, ex) | 500 에러 발생 시 |
sendBatchFail(jobName, ex) | 배치 실패 시 |
sendServerStart() | 서버 시작 시 (자동) |
sendServerStop() | 서버 종료 시 (자동) |
유틸리티 체크리스트
- [ ] 유틸 클래스:
final클래스 +private생성자 - [ ] 모든 메서드
static - [ ] 하드코딩 값 →
global/constant/상수로 분리 - [ ] 상수 클래스: 인스턴스 생성 방지 (
private생성자) - [ ] 상수 클래스명:
{도메인}Constant.java