스프링 프레임워크에서 webapp (웹 애플리케이션 루트) 디렉토리 아래의 리소스에 접근하는 방법은 크게 다음과 같다.
1. ServletContext를 이용하는 방법 (Low-Level)
- 가장 기본적인 방법으로, 서블릿 API의 ServletContext 객체를 직접 사용.
- ServletContext는 웹 애플리케이션의 컨텍스트 정보를 담고 있으며, 웹 애플리케이션 루트 디렉토리에 대한 접근을 제공.
Java
@Controller
public class MyController {
@Autowired
private ServletContext servletContext; // ServletContext 주입
@GetMapping("/getResource")
public String getResource(HttpServletRequest request) {
// 방법 1: @Autowired를 통해 주입받은 ServletContext 사용
InputStream is = servletContext.getResourceAsStream("/WEB-INF/data.txt");
// 방법 2: HttpServletRequest에서 ServletContext 가져오기
ServletContext context = request.getServletContext();
InputStream is2 = context.getResourceAsStream("/WEB-INF/data.txt");
// ... InputStream을 이용한 리소스 처리 ...
return "viewName";
}
}
- 장점:
- 가장 직접적이고 기본적인 방법.
- 서블릿 API에 대한 이해가 있으면 쉽게 사용할 수 있다.
- 단점:
- ServletContext를 직접 다루기 때문에, 스프링의 추상화된 리소스 관리 기능을 활용하지 못함.
- 코드가 상대적으로 장황해질 수 있다.
2. ResourceLoader (또는 ApplicationContext)를 이용하는 방법
- 스프링의 ResourceLoader 인터페이스를 사용하여 리소스에 접근.
- WebApplicationContext는 ResourceLoader 인터페이스를 구현하므로, ApplicationContext를 통해서도 리소스에 접근할 수 있다.
- webapp: 접두어를 사용하거나, 접두어 없이 웹 애플리케이션 루트를 기준으로 하는 상대 경로를 사용.
Java
@Controller
public class MyController {
@Autowired
private ResourceLoader resourceLoader; // ResourceLoader 주입
@GetMapping("/getResource")
public String getResource() {
// 방법 1: webapp: 접두어 사용
Resource resource1 = resourceLoader.getResource("webapp:/WEB-INF/data.txt");
// 방법 2: 접두어 없이 (WebApplicationContext에서는 웹 애플리케이션 루트 기준)
Resource resource2 = resourceLoader.getResource("/WEB-INF/data.txt");
// ... Resource를 이용한 리소스 처리 ...
return "viewName";
}
}
- 장점:
- 스프링의 Resource 추상화를 활용하여 리소스 접근 방식을 통일할 수 있다. (파일 시스템, 클래스패스, URL 등 다른 종류의 리소스도 동일한 방식으로 접근 가능)
- ServletContext를 직접 사용하는 것보다 코드가 간결.
- 단점:
- webapp: 접두어를 명시적으로 사용해야 하는 경우가 있다 (혼동 방지).
3. @Value 어노테이션을 이용하는 방법
- @Value 어노테이션을 사용하여 리소스 경로를 필드에 주입받을 수 있다.
- SpEL(Spring Expression Language)을 사용하여 동적으로 리소스 경로를 지정할 수도 있다.
Java
@Controller
public class MyController {
@Value("webapp:/WEB-INF/data.txt") // 또는 @Value("/WEB-INF/data.txt")
private Resource dataResource;
@GetMapping("/getResource")
public String getResource() {
// dataResource를 사용하여 리소스 처리
try (InputStream is = dataResource.getInputStream()) {
// ...
} catch (IOException e){
// ...
}
return "viewName";
}
}
- 장점:
- 간단하게 resource를 주입받을 수 있다.
- SpEL을 사용해서 동적으로 경로를 설정할 수 있다.
- 단점:
- 리소스 경로가 코드에 하드코딩되는 경향이 있다. (설정 파일 등을 통해 외부화하는 것이 더 좋은 경우가 많음)
4. 정적 리소스 처리 (Spring MVC)
- 웹 애플리케이션 루트 아래의 정적 리소스(CSS, JavaScript, 이미지 등)는 일반적으로 ServletContext나 ResourceLoader를 통해 직접 접근하지 않는다.
- 대신, Spring MVC의 정적 리소스 처리 기능을 사용하여 브라우저에서 직접 접근할 수 있도록 구성.
- <mvc:resources> 설정 (XML 방식) 또는 WebMvcConfigurer 인터페이스 구현 (Java Config 방식)을 통해 URL 패턴과 리소스 위치를 매핑.
XML
<mvc:resources mapping="/resources/**" location="/static/" />
Java
// Java Config
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/static/");
}
}
위 설정은 /resources/로 시작하는 URL 요청을 웹 애플리케이션 루트 디렉토리 아래의 /static/ 디렉토리로 매핑.
어떤 방법을 선택해야 할까요?
- ServletContext를 직접 사용하는 방법: 가장 low-level의 기본적인 방법이지만 스프링을 사용하는 경우 잘 사용하지 않는다.
- ResourceLoader를 사용하는 방법: 스프링의 리소스 추상화를 활용하는 가장 일반적인 방법. webapp:접두어를 사용하거나, WebApplicationContext환경에서는 생략하여 간결하게 사용할 수 있다.
- @Value를 사용하는 방법: 간단한 경우에 유용하지만, 리소스 경로가 코드에 하드코딩되는 단점.
- 정적 리소스: Spring MVC의 정적 리소스 처리 기능을 사용하는 것이 가장 적절.
'개발 > Spring' 카테고리의 다른 글
[Spring] 날짜 파라미터 처리하기 (0) | 2025.03.14 |
---|---|
[Spring] Spring MVC 요청의 흐름 (0) | 2025.03.14 |
[Spring] 리소스 접두어 (0) | 2025.03.14 |
[Spring] 스프링에서 리소스에 접근하는 방법 (0) | 2025.03.14 |
[Spring] 스프링 빈 주입 방법 (0) | 2025.03.13 |