티스토리 뷰
보통 많은 운영 환경에서 Web Server(정적인 파일 서비스)와 WAS 을 연동해서 서비스하는 경우가 많습니다. Tomcat 으로 서비스되고 있는 환경에서조차 내부에 경량 Apache HTTPd 가 내장되어 있기 때문에 별도의 Web Server 없이도 괜찮은 속도로 정적인 파일을 서비스 할 수 있지만, 몇 가지 이유(납득되는 것도 있고, 그렇지 않은 것들도 있지만) 때문에 여전히 기존 방식을 이용하는 곳도 많습니다.
개인적으로 생각할 때 가장 납득이 가는 경우는 "파일 업로드" 기능 때문입니다. 업로드된 파일을 다시 사용자가 내려받아야 할 경우라면 파일 원본 그 자체를 잘 보관하고 있다가 다른 영향 없이 다시 다운로드가 가능해야 합니다. 물론 파일 다운로드 시 권한 체크를 정교하게 한다거나 다운로드 횟수를 제한한다는 등의 제약이 붙으면 여전히 WAS 에서 이를 관리해야 하지만, 일반적인 파일 업로드 시 무조건 다운로드 하면 된다는 정책이 있다면 굳이 WAS 에서 이를 처리할 필요는 없습니다.
또한, 업로드된 파일을 Java 의 배포 디렉토리 혹은 classpath 하위에 저장할 경우 새로운 배포 시 기존 파일이 모두 지워질 수도 있습니다. 배포 전에 미리 업로드 디렉토리를 이동 시킨 뒤 배포 후에 다시 원상복구 하는 것은 위험천만한 생각입니다.
그래서 보통 OS 의 특정 경로에 업로드되는 파일을 저장해두고 Web Server 에서 그 디렉토리를 설정해서 파일을 URL 로 제공할 수 있도록 설정하곤 합니다.
하지만, 최근 들어 Spring Boot 로 외장 WAS 가 아닌 내장 WAS 로 서비스를 하면서 Web Server 조차 구성하지 않는 경우가 많이 생기고 있습니다. 특히 microservice 가 각광받고 있어서 더욱 두드러집니다. 이 때 Spring Boot 에서 main/resources/static/ 디렉토리에 파일을 올려서 사용하는 방법 외에 어떠한 식으로 처리하는지 몰라서 엉뚱한 방법으로 코딩하는 분들이 많습니다.
Spring Boot 에서는 WebMvcConfigurer#addResourceHandlers 을 이용해 다음과 같이 외부(로컬 뿐만 아니라 외부 URL 도 가능) 위치를 resource 로 사용할 수 있도록 할 수 있습니다.
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**") .addResourceLocations("file:///opt/upload/"); } }
위 예제에서 알 수 있듯이 URI 가 /upload/ 이하로 요청이 될 경우 로컬 Disk 의 /opt/upload/ 경로에 있는 파일을 사용자에게 제공하겠다는 의미입니다. /upload/ 경로 이하의 모든 경로와 파일명은 /opt/upload/ 에서 동일하게 찾아서 제공해줍니다.
주의할 것은 resourceLocation 지정 시 로컬 경로일 때 "file:///" 접두어를 빼먹으면 안된다는 것입니다.
당연히 파일 업로드를 구현할 때 저장될 위치에 대해서는 가변적으로 경로를 설정하거나 파일명을 수정하는 형태로 저장할텐데, File 객체를 통해서 저장될 위치를 지정해줘야 할 때 /opt/upload/ 을 여기저기 코드에 적어놓고 쓰는건 비효율적입니다. 그러므로 application.properties 혹은 yml 에 경로를 지정해두고 이를 불러다 쓰는 방법을 권장합니다. 이렇게 할 경우 Spring Profiles 을 이용해 상황에 맞는 가번적인 값을 설정하기에 편리합니다.
resources:
location: /opt/upload/
uri_path: /upload
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Value("${resources.location}") private String resourcesLocation; @Value("${resources.uri_path:}") private String resourcesUriPath; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(resourcesUriPath + "/**") .addResourceLocations("file://" + resourcesLocation); } }
'Programming > Spring Boot 시작하기' 카테고리의 다른 글
Spring Boot 에서 messages.properties 을 이용한 다국어 처리 (1) (0) | 2019.01.28 |
---|---|
Spring Boot 실행과 종료 시 특정 동작을 실행하도록 해보기 (2) | 2019.01.25 |
RestTemplate 설정 변경하기 (0) | 2019.01.23 |
Jackson MessageConverter 을 상속받아 수정하기 (0) | 2019.01.22 |
Spring Boot Java Config 으로 Jackson 설정하기 (0) | 2019.01.22 |
- Total
- Today
- Yesterday
- Spring Boot
- RestTemplate
- 클라우드플레어
- 도입기
- java config
- docker
- Spring
- jooq
- 내장 WAS
- 엘지
- NoSQL
- proxmox
- Phabricator
- 워드프레스
- Nas
- manjaro
- 페이징
- boot
- 프로젝트 규모
- KDE
- SI
- Redmine
- OracleJDK
- messages.properties
- couchbase
- git
- Spring MVC
- 시니어 프로그래머
- paging
- 외장 WAS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |