기본 콘텐츠로 건너뛰기

Java JCodec으로 동영상 썸네일(Thumbnail) 추출하기

Java JCodec으로 동영상 썸네일(Thumbnail) 추출하기 AI 생성 이미지: Java JCodec으로 동영상 썸네일(Thumbnail) 추출하기 순수 Java로 작동하는 경량 코덱 라이브러리 JCodec을 이용해 .mp4, .mov 같은 동영상 파일에서 특정 프레임을 이미지로 뽑아내는 실무용 코드를 정리합니다. Java JCodec으로 동영상 썸네일(Thumbnail) 추출하기는 파일 목록 서비스나 업로드 파이프라인에서 썸네일 생성 자동화에 특히 유용합니다. 아래 예제는 서버 부하를 줄이도록 조건부로 동작하며, 실제 운영 환경에 바로 적용할 수 있게 구성했습니다. 1. 💡 JCodec 소개 및 Maven 설정 썸네일 생성은 JCodec의 코덱 처리 모듈과 AWT 기반 이미지 처리를 제공하는 javase 모듈을 조합해 구현합니다. 안정적인 의존성 버전을 사용하면 호환성 문제를 줄일 수 있습니다. Maven pom.xml 의존성 <dependencies> <!-- JCodec Core Library (코덱 처리) --> <dependency> <groupId>org.jcodec</groupId> <artifactId>jcodec</artifactId> <version>0.2.5</version> <!-- 최신 안정화 버전 사용 권장 --> </dependency> <!-- JCodec JavaSE (AWT 유틸리티 및 이미지 처리) --> <dependency> <groupId>org.jcodec</groupId> <artifactI...

Spring MVC: 동적 요청 경로 추출하기 (PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)

Spring MVC: 동적 요청 경로 추출하기 (PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE) AI 생성 이미지: Spring MVC: 동적 요청 경로 추출하기 (PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE) 대규모 애플리케이션에서 요청 흐름을 명확히 관리하려면 예외 처리와 요청 전후 가로채기가 필수입니다. 이 글에서는 글로벌 예외 처리와 인터셉터를 실무 관점에서 정리하며, Spring MVC: 동적 요청 경로 추출하기 (PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE) 같은 핵심 개념을 함께 설명합니다. 1. 🚨 글로벌 예외 처리: `@ControllerAdvice` 컨트롤러별로 흩어진 예외 처리는 유지보수를 어렵게 만듭니다. `@ControllerAdvice`는 애플리케이션 전역에서 발생하는 예외를 한곳에서 관리해 일관된 에러 응답 형식을 만들고, 비즈니스 로직을 깔끔하게 분리합니다. 또한 Spring MVC: 동적 요청 경로 추출하기 (PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)와 같은 요청 관련 정보를 활용해 더 세밀한 예외 로깅을 구현할 수 있습니다. `try-catch`를 각 핸들러에 반복하는 대신, `@ExceptionHandler`와 함께 사용하면 공통 응답 규격, 상태 코드 매핑, 그리고 로깅 전략을 중앙에서 통제할 수 있습니다. Java GlobalExceptionHandler.java import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; import ...

BitMEX WebSocket: JS로 실시간 데이터 구독 및 인증하기

BitMEX WebSocket: JS로 실시간 데이터 구독 및 인증하기 AI 생성 이미지: BitMEX WebSocket: JS로 실시간 데이터 구독 및 인증하기 이 문서는 BitMEX WebSocket: JS로 실시간 데이터 구독 및 인증하기 구현을 실전 중심으로 정리합니다. 핵심은 HMAC 기반의 인증 절차와 인증 후 개인 토픽을 안정적으로 구독하는 흐름입니다. 실무에 바로 적용할 수 있도록 필수 단계와 주의점을 간결하게 설명합니다. 1. 🔑 필수 라이브러리 설정 (CryptoJS) BitMEX WebSocket에 인증 요청을 보내려면 HMAC-SHA256 서명이 필요합니다. 브라우저 환경에서는 CryptoJS 라이브러리를 사용해 서명을 생성하는 것이 가장 간단합니다. 아래 스크립트는 서명을 위해 필요한 최소 구성입니다. HTML <script> 태그 추가 <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha256.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script> 2. 🛠️ WebSocket 연결 및 인증/구독 JavaScript 코드 아래 예제는 API 키와 시크릿으로 서명을 만든 뒤 인증 메시지를 전송하고, 인증이 완료되면 개인 토픽을 구독하는 흐름을 보여줍니다. BitMEX WebSocket: JS로 실시간 데이터 구독 및 인증하기 구현 시 핵심 패턴입니다. J...

Tomcat Server (cookie)

Tomcat Server (cookie) — Tomcat 9+ SSO 쿠키 파싱 오류 긴급 대응 AI 생성 이미지: Tomcat Server (cookie) Tomcat 9.0.x 이상으로 이전하거나 SSO(Single Sign-On)와 연동할 때 쿠키가 서버에서 읽히지 않는 사례가 자주 발생합니다. 대부분은 Tomcat의 엄격해진 쿠키 유효성 검사 때문이며, 이로 인해 Tomcat Server (cookie) 처리에서 기대한 값이 전달되지 않습니다. 1. 🚨 발생 원인: 엄격해진 쿠키 처리 기준 Tomcat 9부터는 기본적으로 RFC 6265를 따르는 Rfc6265CookieProcessor 가 사용됩니다. 이 처리기는 Domain, Path, 이름 형식 등 쿠키 속성에 대해 예전보다 더 엄격하게 검사합니다. 문제 상황: 레거시 SSO나 타 시스템이 생성한 쿠키의 Domain 속성이 현재 서버 환경의 규칙과 맞지 않으면 Tomcat은 해당 쿠키를 유효하지 않다고 판단하고 파싱을 건너뜁니다. 결과적으로 애플리케이션에서 읽어야 할 값이 사라져, Tomcat Server (cookie) 관련 에러가 발생합니다. 2. 🛠️ 해결 방법: Legacy Cookie Processor 사용 문제를 빠르게 해결하려면 쿠키 검증이 덜 엄격한 이전 처리기인 LegacyCookieProcessor 로 전환하는 것이 가장 확실합니다. 운영 중단 없이 빠르게 적용할 수 있습니다. Tomcat `context.xml` 파일에 추가 해당 애플리케이션의 META-INF/context.xml 또는 Tomcat의 conf/context.xml 파일에서 <Context> 태그 내에 아래 설정을 추가하세요. ...

JPA @OneToOne: 참조 엔티티가 없을 때 Null 처리하는 방법 (@NotFound)

🧩 JPA @OneToOne: 참조 엔티티가 없을 때 Null 처리하는 방법 (@NotFound) AI 생성 이미지: JPA @OneToOne: 참조 엔티티가 없을 때 Null 처리하는 방법 (@NotFound) JPA 매핑 중 외래 키는 남아 있으나 실제로 참조하는 레코드가 삭제되어 관계가 깨지는 경우가 있습니다. 특히 1:1 매핑에서는 이런 상황이 런타임 예외로 이어지기 쉽습니다. 이 글에서는 JPA @OneToOne: 참조 엔티티가 없을 때 Null 처리하는 방법 (@NotFound)을 중심으로, Hibernate의 @NotFound 어노테이션을 활용해 안전하게 처리하는 실무 기법을 소개합니다. 1. 🚨 @OneToOne 관계에서 발생하는 문제 예를 들어 Member와 Profile이 1:1로 연결되어 있고, Member 테이블에 profile_id 외래 키가 존재한다고 가정합니다. 정상적인 상황: profile_id가 유효한 Profile 레코드를 가리킵니다. 문제 상황: profile_id가 DB에 남아 있으나, 실제 Profile 엔티티는 삭제된 경우(ORPHAN 데이터 발생). 기본 JPA/Hibernate는 외래 키가 null이 아니면 참조 대상이 존재한다고 전제합니다. 따라서 참조 대상이 없을 때 엔티티에 접근하면 EntityNotFoundException 또는 지연로딩 시 LazyInitializationException 같은 예외가 발생하여 서비스가 중단될 수 있습니다. 2. ✨ 해결책: `@NotFound(action=NotFoundAction.IGNORE)` Hibernate는 @NotFound 어노테이션을 제공해 이런 결손 데이터를 우아하게 다룰 수 있게 해줍니다. @...

Java 5~14 주요 변화 총정리 | AI 개발·LLM 통합 시대의 핵심 언어

Java 5~14 주요 변화 총정리 | AI 개발·LLM 통합 시대의 핵심 언어 AI 생성 이미지: Java 5~14 주요 변화 총정리 | AI 개발·LLM 통합 시대의 핵심 언어 🚀 Java 버전별 변화 (Java 5 ~ Java 14) 자바는 꾸준한 진화를 통해 언어 기능과 런타임 성능을 개선해왔습니다. 이 글, "Java 5~14 주요 변화 총정리 | AI 개발·LLM 통합 시대의 핵심 언어"는 Java 5부터 Java 14까지 도입된 핵심 기능을 실용적 관점에서 정리합니다. int java5 = 5 ; int java6 = 6 ; int java7 = 7 ; int java8 = 8 ; int java9 = 9 ; int java10 = 10 ; int java11 = 11 ; int java12 = 12 ; int java13 = 13 ; int java14 = 14 ; 🧠 각 버전의 주요 변화 Java 5: 제네릭스와 열거형(Enum), 애노테이션을 도입해 타입 안정성과 메타데이터 활용이 쉬워졌습니다. Java 6: JVM과 라이브러리의 최적화로 실행 성능이 개선되었고, JSR 223을 통한 스크립팅 연동이 가능해졌습니다. Java 7: try-with-resources로 자원 관리를 간소화하고, switch에서 문자열 사용을 지원합니다. Java 8: 람다 표현식과 스트림 API가 추가되어 컬렉션 처리와 병렬 처리가 훨씬 직관적입니다. Java 9: 모듈 시스템(Project Jigsaw)이 도입되어 대규모 애플리케이션의 모듈화와 보안 경계 설정이 가능해졌습니다. Java 10: 지역 변수의 타입 추론(var)이 추가되어 코드 가독성과 간결성이 향상됩니다. Java 11: LTS로서 장기 지원을 제공하며, 새로운 HTTP Client와 문자열 API ...

JPA @OneToMany/@ManyToOne에서 mappedBy reference an unknown target entity 에러 해결하기

JPA mappedBy reference an unknown target entity 오류 원인과 해결 방법 JPA로 @OneToMany / @ManyToOne 양방향 매핑 을 구현하다 보면 다음과 같은 오류를 한 번쯤은 만나게 됩니다. mappedBy reference an unknown target entity property 특히 아래와 같이 mappedBy="parentVO" 와 같이 지정한 경우, 필드명 / 매핑 관계 / 엔티티 설정 에 조금만 틀어져도 이 오류가 바로 발생합니다. 1. 예제 코드 구조 (Parent & Child) 질문에서 사용한 구조를 먼저 정리해보면 다음과 같습니다. A Class (Parent) @Entity public class Parent { @Id @GeneratedValue private Long parentSeq; @OneToMany(mappedBy = "parentVO") private List<Child> rsrcGuildsList; // getter / setter ... } B Class (Child) @Entity public class Child { @Id @GeneratedValue private Long childSeq; @ManyToOne(optional = false) @JoinColumn(name = "parent_seq", updatable = false, insertable = false) private Parent parentVO; // getter / setter ... } Parent에서는 @OneToMany(mappedBy="parentVO") 를...