기본 콘텐츠로 건너뛰기

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") 를...

jQuery DateTimePicker: 시작일/종료일 연동 구현하기

jQuery DateTimePicker: 시작일/종료일 연동 구현하기 AI 생성 이미지: jQuery DateTimePicker: 시작일/종료일 연동 구현하기 기간을 선택하는 UI에서는 시작일이 종료일보다 늦을 수 없고, 종료일은 시작일보다 앞설 수 없습니다. 이 가이드는 jQuery DateTimePicker: 시작일/종료일 연동 구현하기를 목표로 onShow 콜백을 활용해 두 필드 간의 유효성 검사를 실시간으로 적용하는 방법을 단계별로 설명합니다. 1. 🌐 HTML 구조 및 라이브러리 준비 날짜/시간 입력용 input 요소를 준비하고, 페이지에 jQuery와 DateTimePicker 플러그인을 포함해야 합니다. 기본 마크업은 간단합니다. HTML <input> 태그 <!-- 시작일/시간 선택 필드 --> <input type="text" id="popupSdt" placeholder="시작일시 선택"> <!-- 종료일/시간 선택 필드 --> <input type="text" id="popupEnd" placeholder="종료일시 선택"> <!-- (참고: jQuery 및 DateTimePicker 플러그인 파일 로드가 필요합니다.) --> 2. 🛠️ JavaScript 시작일/종료일 연동 로직 여기서는 피커가 화면에 보일 때마다 상대 필드의 값을 확인해 자신의 minDate 또는 maxDate 를 업데이트합니다. 이렇게 하면 사용자가 유효하지 않은 기간을 선택하지 못하도록 즉시 차단할 수 있습니다. JavaScript 코드 // 로...