도토링 프로젝트의 프로필 이미지 수정 기능을 개발하다가 아래와 같은 문제상황을 만나 의미있는 문제 상황이어서 포스팅하려 합니다.
문제 상황
현재 상황은 아래와 같습니다.
resources/static/files 안에 default_profile~~ 이미지가 저장되어 있습니다.
빌드후 애플리케이션을 실행한 후 해당 이미지가 저장된 경로로 조회하면, 위와 같이 이미지가 잘 조회되는 것을 확인할 수 있습니다.
하지만, 아래와 같이 새로운 이미지를 아까와 동일한 경로에 업로드하면 해당 이미지는 조회가 되지 않습니다.
아래와 같이 이미지는 잘 저장이 된 상태입니다.
그렇다면, 실행 중인 애플리케이션을 빌드 -> 실행한 후 조회를 해보면 어떨까?
놀랍게도 조회가 잘 되는 것을 확인할 수 있습니다.
문제 분석
눈치 채신 분들도 있겠지만, resources/static 하위에 있는 이미지들은 build된 폴더 아래에 있어야 조회가 가능합니다.
위 사진을 보면, src/main/resources 폴더 하위에 파일들이 생성된 것을 확인할 수 있습니다.
하지만, build/resources/main/static/files 폴더 아래에는 파일들이 생성되지 않은 것을 확인할 수 있습니다.
결론
빌드 결과물(JAR 또는 WAR 파일)에는 src/main/resources/static 디렉토리의 이미지 파일이 포함됩니다. 애플리케이션 실행 중에는 이 파일들만 내장 웹 서버를 통해 제공됩니다.
따라서, 런타임 중에 src/main/resources/static에 새로운 이미지 파일을 추가하거나 기존 파일을 변경해도, 이러한 변경 사항은 자동으로 빌드 폴더에 반영되지 않습니다.
여기서 "빌드"란, 소스 코드를 컴파일하고 필요한 라이브러리를 포함하여 실행 가능한 형태로 패키징하는 과정을 의미합니다. 이 과정에서 src/main/resources/static 디렉토리에 있는 파일들이 JAR 또는 WAR 파일에 포함됩니다. 따라서, 애플리케이션이 실행될 때는 이 빌드된 패키지 내의 파일들만 사용할 수 있습니다.
핵심은 JAR 파일로 실행되는 애플리케이션이 빌드된 패키지 내의 파일들만 조회할 수 있다는 점입니다. 런타임 중에 소스 디렉토리에 변경된 파일은 자동으로 반영되지 않기 때문에, 변경사항을 적용하려면 다시 빌드해야 합니다.
하지만, 매번 빌드를 하는 것은 말이 되지 않습니다.
해결방법 - 외부 경로 이용
해결방법은 간단합니다.
즉, src/main/resources/static 경로 내에 해당 이미지를 저장시키는 것이 아니라 src 외부 경로에 저장을 시키는 것입니다.
위 사진은 정적 리소스에 대한 경로를 정의하고 있습니다.
- classpath는 빌드한 결과의 resources 디렉토리(ex. build/resources)를 의미
- file 은 말 그대로 파일 시스템 아래에 위치한 디렉토리를 의미
기본으로 정의된 정적 리소스 경로들은 모두 build된 결과들에 접근하고 있습니다.
따라서, 이미지 파일의 변경사항을 조회하려면, 파일 시스템 즉 file로 된 경로를 추가해줘야합니다.
따라서, 이미지를 조회할 때 사용되는 경로를 정의하는 FileUtils라는 클래스의 fileDir을 아래와 같이 수정해줍니다.
public class FileUtils {
private static final String fileDir = rootPath + "/src/main/resources/image/";
...
}
다음으로, addResourceHandlers 메서드를 오버라이드 하여 이미지를 조회하는 URL 경로에 매핑되는 파일 시스템의 경로를 지정해줍니다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/image/**")
.addResourceLocations("file:src/main/resources/image/")
;
}
}
이제 image/** URL을 사용하여 특정 이미지를 조회하면, 애플리케이션 실행 도중에 이미지가 잘 조회되는 것을 확인할 수 있습니다.
감사합니다!
'Project Trouble Shooting > [Dotoring] 멘토링 어플리케이션' 카테고리의 다른 글
Fetch Join을 여러번 했더니 MultipleBagFetchException이??? (0) | 2023.08.16 |
---|---|
QueryDSL을 사용해 통계(Count)쿼리의 결과를 사용해서 정렬하기 (0) | 2023.08.15 |
데이터 무결성 지켜야지, 안 지킬거야?? (0) | 2023.08.07 |
식별자, 비식별자 관계는 뭐고 언제 사용해야하는 걸까?? (0) | 2023.08.04 |
엔티티의 통합과 분리의 기준이 뭐야?? (0) | 2023.08.04 |