국비교육(22-23)

60일차(2)/Spring Boot(9) : 파일 저장경로 수정 / Boot 기능 활용

서리/Seori 2023. 1. 3. 01:30

60일차(2)/Spring Boot(9) : 파일 저장경로 변경 / Boot에서 war파일 생성(3)

 

 

- SmartEditor 기능(jsp파일)을 사용하기 위해 webapp, upload 폴더 등을 생성하여 기존 spring을 복사해왔다.

- 편하게 이식하기 위해서!

 

- 하지만 어떤 프로젝트에서는 이런 구조가 맞지 않을 수도 있다.

 

- 우리는 이 구조를 사용해 war파일을 만들어낼 것이다.

- 외부 tomcat을 사용해서 돌릴 예정이다.

 

- 하지만 이런 구조는 약간 이슈가 있다.

 

- 파일 업로드, 이미지 업로드 경로를 바꿀 예정

- upload 폴더를 지금은 사용하고 있지만,

 

- git 브랜치 분리

- feature/file_upload_download 브랜치 생성

 

- c: 에 data 폴더 만들기

 

 

- 이것은 서버와는 상관없는 폴더이다.

- 업로드되는 프로필 이미지는 여기에 저장하려고 한다.

 

- 이제는 이렇게 사용할 수 없다.

- webapp 을 통해서 접근할 수 있는 곳에 넣어놓으면

 이제 외부 컴퓨터에서 사용하므로 읽어들일 수 없다.

 

- 지금 profile의 경로는 이런 형태로 저장되어 있다.

 

 

 

- 현재 이 이미지를 볼 수 있는 이유는 이렇게 경로가 저장되어 있기 때문이다.

 그런데 이것을 서버의 웹앱과는 상관없는 절대경로로 표시할 것이다.

- 하지만 외부 컴퓨터(ServerComputer)를 사용한다고 생각하면,

 저 경로로는 서버컴퓨터의 C:\\ 에 접근하기때문에 말이 안 된다.

 

 

- Client 브라우저에서 서버 컴퓨터 측으로 요청을 보낸다.

- 서버에 톰캣이 있는데, 서비스하고 있는 webapp/resources/upload/ 폴더에 어떤 파일이 있다고 가정하면

 클라이언트는 요청을 통해 이것을 받아갈 수 있다.

- 이 폴더안쪽은 controller를 통해 접근하지 않으므로!

 

- boot07 까지만 입력하면 resources/ 를 말하는 것이 된다.

 

- 클라이언트가 요청 가능한 경로에 있는

서버가 서비스하는 webapp과 상관없이 다른곳에 있는 2.jsp 라고 하면

이것은 단순히 요청으로 받아갈 수는 없다.

 

- resources 안에 들어가있어야 한다.

 

/boot07/profile

- 이런 형태의 요청을 하면 컨트롤러를 거쳐서 읽어내서 이미지 자체를 응답하게 할 수 있다.

 

- 다른 공간에 있으면 컨트롤러를 통해서 받아가야 한다.

- 컨트롤러가 이미지 데이터를 읽어서 이미지 자체를 응답한다.

 

- 이미지 저장경로 저장-응답

 

GalleryServiceImpl

- 이 지정해놓은 경로를 고쳐야 한다.

 

- "C:\\data" 를 realPath로 사용하도록 한다.

- \ 기호는 특별한 의미를 갖기때문에, \\로 두개 표시해주어야 한다.

 

- 클래스 안에 하드코딩하는 것은 좋지 않다.

- 나중에 외부파일에서 읽어들이는 방식으로 바꿀것이기 때문에.

 

- 파일명을 구성하는 파일 저장경로 바꾸기

- 파일을 저장할 서버에서의 절대 경로를 적어준다.

 

- DB에 저장할때는 그냥 파일명만 저장하도록 한다.

 

gallery/list 수정

- 이전에는 이렇게 작성했는데, (webapp 안에 프로필이미지가 있었기 때문에 이렇게 작성해도 나왔다)

 

- 경로에 /users/profile/ 를 추가해준다.

- 이제는 컨트롤러가 저 이미지의 출력을 처리해준다.

 

@GetMapping("/users/profile/?")

- 컨트롤러 작성방식은 이렇다고 할 수 있다. ? 에 들어갈 내용은 그때그때 다르다.(파일명이므로)

- GetMapping() 을 사용하지만, ? 부분은 동적으로 작성되어야 한다.

 

- 프로필 이미지 요청에 대한 응답을 할 메소드를 따로 만들어야 하고, 이미지 데이터가 응답되어야 한다.

- 웹브라우저에게 이미지 데이터를 응답한다고 알려야 한다.

 

@GetMapping("/users/profile/{imageName}")
@ResponseBody
    public Stirng profileImage(@PathVariable("imageName) String imageName){
		return imageName
	}

 

- 이런 동적인 내용을 mapping할 때는 위와 같이 작성한다. 경로에 { } 중괄호를 넣는다.

- 이것을 PathValiable 이라고 한다. 경로 변수!

 

 

- @ResponseBody 를 붙여주고, 경로변수에 { } 안의 내용을 넣어준다.

 

 

- 이렇게 경로에 있는 값 중 어떤 값(파일명)을 1.jpg만 따로 읽어올 수 있다.

- 저 이름(imageName)을 일치시켜주면 사용할 수 있다.(분홍색)

 

 

- WebConfig에서 수정

- profile 페이지도 예외할 페이지로 넣어준다.

 

 

- 저 경로를 직접 입력해보면 경로에서 파일명만 추출하는 기능이 사용되었다는 것을 알 수 있다.

 

 

- 파일에서 읽어들이려면 inputStream이 필요. 이렇게 작성하기

 

- inputStream에서 저 경로를 읽어서 byte 배열을 만들어낸다.

 

 

- 이것을 더 편하게 사용하려면 어떤 유틸리티를 사용하면 좋다.

<!-- IOUtils 클래스를 사용하기 위한 라이브러리 -->
<dependency>
     <groupId>commons-io</groupId>
     <artifactId>commons-io</artifactId>
     <version>2.4</version>
  </dependency>

 

- pom.xml에 넣어주기!

 

 

- 톰캣이 아닌 commons를 import해준다.

- inputStream을 인자로 받아서 byte 배열을 출력하는 toByteArray 메소드를 사용.

 

- produces : 이 메소드가 무엇을 생산하는지! 출력하고자 하는 데이터 포맷을 정의한다.

- 뒤에 이미지를 출력할 것이라고 알려주어야 한다.

 

- 바이트배열이 이미지이니까, 이미지로 받으라는 뜻!

 

- data에 넣었다가 1.jpg 을 입력하면 서버의 파일 시스템에 있는 이미지가 응답한다.

 

- 원격지의 클라이언트가 파일 요청을 통해서 원격지의 파일시스템 안의 내용을 받아갈 수 있는 구조가 되었다.

- 이전에는 웹앱 폴더에 넣었으므로 굳이 이런 것을 하지 않았다.

 

- imageName 이름은 마음대로 설정 가능

이것을 읽어와서 String으로 바꾼다는 의미이다.

 

- 이제 파일을 업로드하면 이 경로로 올라간다.

 

- DB에서 확인해보면, 이렇게 파일명만 저장하게 할 수 있다.

 

- 확장자는 JPEG로 지정했지만, 브라우저가 png로 전달해도 이해한다.

 하지만 자세하게 전달하려면 배열로 전달하면 된다.

 

- jpeg, png, gif를 읽어들이도록 작성하면 더 좋다.

 

 


- 이것을 외부로 빼려면?

- application.properties 에 수정

 

 

file.location=c:\\data

- 위와 같이 나만의 properties를 만들어서 읽어낼 수 있다. (Custom properties)

-이것을 만든 다음에 필요한 곳에 @Value 어노테이션을 붙여서 가져다가 사용한다.

 

usersController에 추가

@Value("${file.location}")

- 어노테이션을 넣고 ${} 안에 커스텀 property의 경로 표시

 

- 아래 absolutePath에 fileLocation+imageName 이 되도록 수정한다.

 

- file seperator도 들어가도록 수정해주기

 

 

- properties에서 정의한 설정값을 @value로 읽어올 수 있다.

- custom properties를 만들어서 읽어낼 수 있다.

 

GalleryService 에도 추가!

 

- fileLocation을 아까 C:\\로 작성했던 경로에 담아주기

 

 

- 이렇게 하면 파일 업로드도 되고, 지정한 곳(data 폴더)에 이렇게 하나씩 파일이 들어오는 것을 볼 수 있다.

- 컨트롤러에서 이 파일들을 이 폴더에 업로드할 수 있도록 컨트롤한다는 것을 알 수 있다.