/image/default/default.PNG
server/thn/Config/WebConfig.java
// 웹 애플리케이션의 Spring Web MVC 설정을 활성화
@EnableWebMvc
// 이 클래스는 Spring의 설정 클래스로 사용
@Configuration
public class WebConfig implements WebMvcConfigurer {
// application.properties 파일에서 읽어온 이미지 업로드 위치를 저장할 변수
@Value("${upload.image.location}")
private String location;
// 정적 리소스 핸들러를 추가하는 메서드
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// "/image/**" 경로로 들어오는 모든 요청을 처리하기 위한 리소스 핸들러 등록
registry.addResourceHandler("/image/**")
// 파일 시스템에서 실제 이미지 리소스를 찾을 경로 설정
.addResourceLocations("file:" + location);
}
}
💡 **웹 애플리케이션의 "/image/" 경로로 들어오는 요청을 서버의 파일 시스템에서 `location` 변수에 지정된 디렉토리에서 이미지 파일을 찾아서 반환하도록 설정하는 과정**
.addResourceLocations("file:" + location)
location
은 @Value("${upload.image.location}")
로 주입받은 이미지 업로드 위치를 나타내는 변수location
변수를 이어서 실제 디렉토리 경로로 연결하여 해당 디렉토리에서 이미지 리소스를 찾을 수 있도록 설정 server/thn/Config/security/SecurityConfig.java
.antMatchers(HttpMethod.GET, "/image/**").permitAll()
component-scan
을 통해 전체를 스캔하여 빈으로 등록한다.WebConfigure
이 빈으로 등록되지 않은 이유는 무엇이었을까?? SwaggerConfig
,@EnableSwagger2
@Configuration
public class SwaggerConfig extends WebMvcConfigurationSupport{
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("server.thn"))
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("THN API DOC")
.version("1.0")
.description("")
.license("THN")
.licenseUrl("")
.build();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
super.addResourceHandlers(registry);
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add( new PageableHandlerMethodArgumentResolver());
}
}
SwaggerConfig
파일은 WebMvcConfigurationSupport
라는 클래스를 상속WebConfigure
파일은 WebMvcConfigurer
클래스를 상속한다,WebMvcConfigurer
vs WebMvcConfigurationSupport
스프링 MVC 자동구성은 WebMvcAutoConfiguration이 담당한다.
이 구성이 활성화되는 조건 중에 WebMvcConfigurationSupport 타입의 빈을 찾을 수 없을 때 라는 조건이 있다.@Configuration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }) @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class }) public class WebMvcAutoConfiguration { }
=> @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
그런데 위에서 거론했던 @EnableWebMvc를 스프링 MVC 구성을 위한 클래스에 선언하면 WebMvcConfigurationSupport을 불러와 스프링 MVC를 구성한다.
이 과정에서 WebMvcConfigurationSupport가 컴포넌트로 등록되어 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) 조건을 만족시키지 못하게 되어 WebMvcAutoConfiguration은 비활성화 된다.
이와 유사하게 WebMvcConfigurationSupport를 확장한 클래스에 @Configuration를 선언하면 동일하게 적용된다.
출처
WebMvcConfigurationSupport
를 extends 받은 클래스 생성 이후 WebConfig
가 제대로 작동하지 않게 되었다.WebMvcAutoConfiguration
이 담당한다.@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
부분에서 WebMvcConfigurationSupport
가 없을 때 이 구성이 활성화 된다고 한다.⇒ 나의 프로젝트에는 WebMvcConfigurationSupport
가 있었기에, 이미지 경로를 핸들링한 WebConfigure
파일이 작동하지 않은 것이다.
⇒ 따라서 두 Config 파일을 분리하지 않고, 한 파일로 통합해서 Mvc 자동구성을 설정해야 한다.
@EnableSwagger2
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Value("${upload.image.location}")
private String location;
.........
@Override
public void **addResourceHandlers**(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/image/**")
.addResourceLocations("file:" + location)
.setCacheControl(CacheControl.maxAge(Duration.ofHours(1L)).cachePublic());
super.addResourceHandlers(registry);
}