개주 훈련일지/🔥 히노카미 코구라(오류 수정)

오류내역) 샘플 데이터 이미지가 안 뜨는 이유: DB 경로와 정적 리소스 매핑 불일치

lshfood2 2026. 2. 19. 11:12

[ 샘플 데이터 로딩 실패 ]

좌 : 뉴스 전체보기 페이지 / 우 : 뉴스 상세보기 페이지

 

오류 상황

뉴스 페이지에서 새로 추가한

콘텐츠는 이미지가 정상 출력되는데,

DB 넣어둔 샘플 데이터는 이미지가

깨지면서 안 나오는 문제가 발생했다.

 

증상은 이런 형태였다.

  • 뉴스 리스트에서는 카드가 뜨는데,
    썸네일이 비거나 깨진 아이콘이 뜸
  • 뉴스 상세에서 본문 이미지 영역에
    이미지가 안 뜨고 alt만 보이거나 빈 공간이 생김
  • 개발자 도구(Network)로 보면
    이미지 요청이 404로 떨어짐

[ 가설 수립: '리소스 매핑/저장 경로 문제'다 ]

처음엔 페이지 이동 경로 문제를

(JSP 링크, 컨텍스트 경로) 의심할 수 있다.


하지만 이번 케이스는 페이지 라우팅이 아니라

이미지 리소스를 가져오는 단계에서 깨진다.

 

가능한 원인은 딱 두 가지로 좁혀졌다.

  1. DB에 저장된 이미지 URL이 실제 파일 위치와 다르다.
  2. '/uploads/**' 같은 URL이 정적 리소스로 서빙되도록
    스프링 설정이 돼 있지 않다(또는 물리 경로가 비어 있다)

샘플 데이터의 이미지 경로가

DB에는 이런 형태로 들어가 있었다.

news_image_url: '/upload/news/12.jpg'
news_thumbnail_url: '/upload/thumb/12.jpg'

 

그런데 실제 프로젝트 리소스 폴더를 확인해보니

이미지 파일은 '/uploads' 아래가 아니라

'/images' 아래에 들어가 있었다.

실제 파일 위치: '/images/news/12.jpg', '/images/thumb/12.jpg'
'/upload' 또는 '/uploads' 쪽에는 해당 샘플 이미지가 존재하지 않음

결과적으로 화면은

이미지 태그를 렌더링하긴 하는데,

브라우저가 요청하는 URL에

파일이 없어서 표시가 안 됐다.


[ 가설 검증: 원인 파악 ]

검증은 빠르게 끝났다.

개발자 도구(Network)에서 이미지 요청 URL을 확인
  • 요청: '/uploads/news/12.jpg'
  • 결과: 404(Not Found)
서버 프로젝트에서 실제 파일 위치 확인
  • '/images/news/12.jpg' 는 존재
  • '/uploads/news/12.jpg' 는 없음
DB 샘플 데이터의 경로를 정적으로 바꿔 테스트
  • 기존 INSERT의 URL을
    실제 존재하는 위치로 바꿔서 재확인했다.

 

예시(작동하게 바꾼 형태)

INSERT INTO NEWS (anime_id, news_title, news_content, news_image_url, news_thumbnail_url)
VALUES (
  (SELECT MIN(anime_id) FROM ANIME WHERE anime_title = '원피스'),
  '원피스: ‘모험’이 주는 순수한 재미의 힘',
  '<p>원피스는 세계관 확장과 떡밥 회수의 재미가 큰 작품입니다.</p>
<figure class="image"><img src="/images/news/12.jpg" alt="원피스 본문 이미지"></figure>
<p>동료 서사와 감정 연출이 강하고, 큰 줄기 목표가 명확해서 장기 연재임에도 몰입도가 유지됩니다.</p>',
  '/images/news/12.jpg',
  '/images/thumb/12.jpg'
);

 

결과: 이미지가 정상 출력됨

즉, 문제는 '페이지 경로'가 아니라

'DB에 저장된 URL(/uploads...)과

실제 정적 리소스 위치(/images...)의 불일치'였다.


[ 해결 방법 ]

이번 문제는 해결 방향이 2가지다.

어느 쪽이든 핵심은 DB에 저장되는 URL과

실제 파일이 서빙되는 위치를 일치시키는 것.

 

해결 1)
샘플 데이터는 정적 리소스 폴더(/images)를 기준으로 넣는다.

  • 샘플 이미지는 실제로
    '/images/news', '/images/thumb'에 있으니
  • DB에도 동일하게 '/images/...' 형태로 저장한다
  • 가장 빠르고 단순한 해결

해결 2)
업로드 정책을 유지하려면
'/uploads/**'를 진짜 업로드 폴더로 만든다.
업로드 파일을 '/uploads/...'로 저장하고 싶다면,
다음이 동시에 만족돼야 한다.

  • 실제 물리 폴더에 업로드 파일이
    존재해야 함 (예: D:/.../uploads/news/12.jpg)
  • 스프링이 '/uploads/**' 요청을
    그 물리 폴더로 매핑해서 서빙해야 함

현재 상황은 'DB에는 /uploads로 저장돼 있는데,
실제 파일은 /images에 있고, /uploads엔 없어서' 깨진 케이스였다.


[ 마무리 ]

  • 뉴스 페이지 자체 경로는 문제 없었다.
    (컨트롤러/JSP 라우팅)
  • 깨진 지점은 이미지 요청 단계였다.
  • DB에 저장된 이미지 URL 루트가
    '/uploads'로 되어 있었지만,
    실제 파일은 '/images' 아래에 있었다.
  • 그래서 브라우저가 '/uploads/...'로 요청했고
    404가 나면서 이미지가 안 떴다.
  • 해결은 DB URL과 정적 리소스/업로드 리소스
    매핑을 일치시키는 것으로 끝난다.