간단한 게시판 프로젝트에서 파일(이미지) 업로드를 구현하던 도중 파일은 정상적으로 저장이 됐지만 웹 브라우저 화면에서 해당 파일이 404에러로 인해 엑박으로 뜸.
이 문제를 해결하면서 공부한 걸 정리한 글.

addResourceHandlers(ResourceHandlerRegistry registry)
↑ 웹 애플리케이션 루트, 클래스 경로 등의 특정 위치에서 이미지, js, css 파일과 같은 정적 리소스를 제공하기 위한 핸들러를 추가.Spring MVC에서 이미지, CSS 파일 등과 같은 정적 리소스를 제공하기 위한 리소스 핸들러를 등록하고 웹 브라우저에서 효율적인 로딩을 위해 캐시 헤더 설정도 최적화할 수 있음.
리소스를 제공할 수 있는 위치.
리소스 핸들러 등록 방법.
addResourceHandler(String...) 메서드를 이용하여 정적 리소스를 처리할 URL 경로 패턴을 지정.Ex) "/resources/**" → /resources/ 경로 아래의 정적 파일을 처리이후, 반환된 ResourceHandlerRegistration 객체의 메서드를 사용하여 정적 리소스를 제공할 위치를 하나 이상 추가하거나 제공되는 리소스에 대한 캐시 기간을 지정.
Ex) addResourceLocations("/", "classpath:/META-INF/public-web-resources/")public class ResourceHandlerRegistry {
private final ServletContext servletContext;
private final ApplicationContext applicationContext;
@Nullable
private final ContentNegotiationManager contentNegotiationManager;
@Nullable
private final UrlPathHelper pathHelper;
private final List<ResourceHandlerRegistration> registrations = new ArrayList<>();
private int order = Ordered.LOWEST_PRECEDENCE - 1;
....
public ResourceHandlerRegistration addResourceHandler(String... pathPatterns) {
ResourceHandlerRegistration registration = new ResourceHandlerRegistration(pathPatterns);
this.registrations.add(registration);
return registration;
}
....
}
public ResourceHandlerRegistration addResourceHandler(String... pathPatterns)
↑ 정적 리소스를 제공하는 리소스 핸들러를 추가.public class ResourceHandlerRegistration {
private final String[] pathPatterns;
private final List<String> locationValues = new ArrayList<>();
private final List<Resource> locationsResources = new ArrayList<>();
@Nullable
private Integer cachePeriod;
@Nullable
private CacheControl cacheControl;
@Nullable
private ResourceChainRegistration resourceChainRegistration;
private boolean useLastModified = true;
@Nullable
private Function<Resource, String> etagGenerator;
private boolean optimizeLocations = false;
.....
public ResourceHandlerRegistration addResourceLocations(String... locations) {
this.locationValues.addAll(Arrays.asList(locations));
return this;
}
.....
}
public ResourceHandlerRegistration addResourceLocations(String... locations)
↑ 하나 이상의 리소스 위치를 추가하여 정적 콘텐츠를 제공할 수 있음.@Configuration
public class WebConfig implements WebMvcConfigurer {
@Value("${file.directory}")
private String fileDirectory;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/upload/**") // view에서 사용할 경로
.addResourceLocations("file:" + fileDirectory); // 실제 파일 저장 경로
}
}
/upload/** 로 시작하는 모든 요청을 처리하고, 요청된 파일을 fileDirectory폴더에서 찾도록 설정. <tr th:if="${board.fileAttached == 1}">
<th>이미지</th>
<td>
<div class="image-container" th:each="boardFile : ${boardFileList}">
<img th:src="@{|/upload/${boardFile.storedFileName}|}" alt="" width="200" height="200">
</div>
</td>
</tr>


