증상상품 이미지 업로드 시 POST/PUT 요청이 403으로 실패. S3 에러 바디에는 SignatureDoesNotMatch 표기.원인presign 시 >(캐시 제어)을 포함해 서명했지만, 실제 PUT 업로드 요청 헤더에 동일 헤더를 넣지 않아 서명에 사용한 헤더와 실제 요청 헤더가 불일치.해결 방법presigned PUT URL을 내려줄 때 클라이언트가 반드시 포함해야 하는 모든 헤더(예: >, >, 필요한 헤더)를 함께 반환하고, 프론트는 해당 헤더를 그대로 넣어 업로드 수행.결과동일 키/파일에서도 403 재발 없음. 업로드 후 객체 조회 정상.
오늘 한 일 요약상품 등록: ⟨⟨name, price, categoryId, imageKey, status(on_sale|stop), initialQuantity⟩⟩를 받아 ⟨⟨Product⟩⟩·⟨⟨Inventory⟩⟩·⟨⟨InventoryLog(INIT, delta=+initialQuantity)⟩⟩를 한 트랜잭션으로 생성했다.이미지 등록: 프론트가 ⟨⟨GET /api/images/presign?contentType={MIME}⟩⟩으로 presigned PUT URL을 받아 S3에 직접 업로드하며, 키는 ⟨⟨{prefix}/{yyyy}/{MM}/{uuidNoHyphen}.{ext}⟩⟩ 규칙·만료 5분·헤더(Content-Type/Cache-Control) 일치로 운영한다. 상품 등록개요관리자 전용 상품..
서비스 계층에서 create · update · delete가 끝날 때마다 “” 로그를 남기는 전략을 AOP와 MDC 두 가지만으로 구현한다.기술핵심 역할Spring AOP (AspectJ)메서드 실행을 가로채 로깅 로직 주입MDC (Mapped Diagnostic Context)로그마다 사용자 ID 등 컨텍스트 유지Spring AOP - 메서드 가로채기Pointcut> 같이 메서드 시그니처 패턴으로 타깃 지정 세 가지 메서드만 잡는다Advice> : 정상 리턴 시점에만 동작—예외가 터지면 실행하지 않는다핵심 코드@AfterReturning( pointcut = "execution(public * com.khmall..*Service.create*(..)) || " + "e..
오늘 한 일 요약 카테고리 생성 — > 구현, 상위 존재·이름 중복 검증 후 > 기본 0으로 저장.카테고리 수정 — > 구현, > 로 부분 업데이트 지원·깊이 / 중복 예외 처리.테스트 환경 분리 — > 베이스 + JUnit 확장으로 모든 테스트를 > 프로필로 강제. 카테고리 생성개요> 엔드포인트를 구현해 최상위·하위(1 단계) 카테고리를 등록할 수 있게 했다.입력 필드: >, > (nullable), > (nullable·기본값 0).고민한 점전달된 >가 실제로 존재하는지 서비스 레이어에서 검증할 방법.카테고리 이름 중복을 어떤 범위(전역 vs 동일 부모)에서 제한할지 기준 설정.검증 실패 시 예외를 어디서 던지고 어떤 HTTP 상태로 변환할지.>를 요청에 포함하지 않으면 어떤 값으로 저장할지(디폴트 ..
JsonNullable 이란?RESTful API에서 ⟨⟨PATCH⟩⟩ 요청을 사용할 때, 필드의 “명시적 null”과 “미입력”을 구분해야 할 때가 많다.⟨⟨JsonNullable⟩⟩은 바로 이 문제를 해결하는 Java용 제네릭 래퍼 클래스다.일반적인 DTO 필드는 null이면 “값을 비우는 것”과 “아예 값을 건드리지 않는 것”이 구분되지 않는다.⟨⟨JsonNullable⟩⟩을 사용하면입력 없음: ⟨⟨JsonNullable.undefined()⟩⟩입력값 있음: ⟨⟨JsonNullable.of(값)⟩⟩명시적 null: ⟨⟨JsonNullable.of(null)⟩⟩식으로 3가지 상태를 구분할 수 있다. 특징DTO 필드의 "입력 없음"과 "명시적 null"을 완전히 분리주요 메서드⟨⟨isPresent()..
증상카테고리 수정 시, 상위 카테고리(⟨⟨parentId⟩⟩)를 제거하고 싶었으나API 요청에서 해당 필드를 아예 누락하거나 null로 보내도 변경이 반영되지 않음.원인기존에는 DTO에서 ⟨⟨parentId⟩⟩를 일반 필드(Integer, Long 등)로 선언하여값을 아예 보내지 않으면 서비스 레이어에서 “미수정”으로 간주,null로 보내면 프론트/백엔드/컨버터 해석에 따라 "변경 없음" 또는 "오류"로 처리됨.결과적으로 상위 카테고리를 “없음(null)”으로 업데이트하는 방법이 없음.해결 방법카테고리 수정 DTO에서 ⟨⟨parentId⟩⟩ 타입을 ⟨⟨JsonNullable⟩⟩로 변경.서비스에서 ⟨⟨parentId⟩⟩의 ⟨⟨isPresent()⟩⟩ 여부를 체크:present이고 값이 null이면, 진짜로..