1. application.properties에 #multipart 추가하기
# port
server.port=8081
# JSP view
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
# oracle set
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:1521/xe
spring.datasource.username=hr
spring.datasource.password=hr
#encoding
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
#jpa
spring.jpa.generate-ddl=true
spring.jpa.database=oracle
spring.jpa.show-sql=true
#multipart
spring.servlet.multipart.location=/Users/~~~/Desktop/img/
spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.location = 본인이 정한 이미지 파일의 경로 (꼭 끝에 / 붙이기)
spring.servlet.multipart.max-file-size = 이미지 최대 용량. 초과하는 이미지를 올리게 되면 에러 뜸!!
2. Dto에 MultipartFile 멤벼번수 생성
private MultipartFile file;
3. Controller에서 메서드 구현
(1) path 경로 담은 멤버변수 생성
@Value("${spring.servlet.multipart.location}")
// application.properties에 정의한 경로를 읽어와서 변수에 넣어줌.
private String path; // path = /Users/~~~/Desktop/img/
(2) 파일 업로드 메서드
<h3>업로드폼</h3>
<form action="/upload/upload" method="post" enctype="multipart/form-data">
title:<input type="text" name="title"><br/>
file:<input type="file" name="file"><br/>
<input type="submit" value="저장">
(name 을 멤버변수 이름과 똑같이 해야 함!)
public String upload(ImgVo vo) {
MultipartFile f = vo.getFile();
String fname = f.getOriginalFilename(); // 원본 파일명
File f2 = new File(path + fname); // 업로드된 파일을 저장할 새 파일 생성
f.transferTo(f2); // 파일 복사
return "redirect:/upload/list";
}
1. 업로드 폼에서 업로드한 파일 (vo의 File에 담겨져 있음)을 MultipartFile 변수에 담는다.
2. 파일명을 String 에 담는다.
getOriginalFilename();
3. 업로드 된 파일을 저장할 새 파일을 생성한다. (파일 경로는 기존 경로에 파일명을 붙여 지정)
- File은 파일에 대한 정보를 가지고 있는 객체다.
4. 새로 생성한 파일에 MultipartFile객체를 찐 업로드 처리한다. (클라이언트 컴퓨터에 저장된 파일이 서버 컴퓨터로 복사됨.)
MulipartFile.transferTo(File);
(3) 파일 읽어오기
@GetMapping("/list")
public void list(Model m) {
File dir = new File(path);
String[] files = dir.list(); // 디렉토리에 저장된 파일들 이름을 배열에 담아줌.
m.addAttribute("imgs", files);
}
1. path 경로에 있는 파일(디렉토리)에 대한 정보를 불러와 dir에 담는다.
2. 디렉토리에 저장된 파일들 이름(fname)만 배열에 담아 jsp로 전달한다.
<h3>업로드 목록</h3>
<c:forEach var="img" items="${imgs }"> <!-- 파일 이름이 들어가있음. -->
<!-- 컨트롤러로 요청 보냄. -->
<img src="/upload/read_img?fname=${img }" style="width:200px;height:200px">
</c:forEach>
3. Controller에서 전달받은 이미지 이름을 다시 Controller로 요청보내 실제 이미지 자체를 들고 온다.
img src에 기존에는 이미지 경로 전체를 썼지만, 지금은 이미지 파일 경로가 웹에서 쓰이는 경로가 아니기 때문에,
이미지를 바이너리값으로 읽어올 Controller 메서드를 호출.
@GetMapping("/read_img")
// 이미지는 바이너리값 -> byte[]
public ResponseEntity<byte[]> read_img(String fname){
File f = new File(path+fname);
HttpHeaders header = new HttpHeaders(); // HttpHeaders : 여러 설정을 담음.
ResponseEntity<byte[]> result = null; // ResponseEntity 응답 객체 선언.
try { // 여러 설정값 중 Content-Type라는 값이 있음.
header.add("Content-Type", Files.probeContentType(f.toPath())); // 응답 데이터의 종류를 설정
// 응답 객체 생성
result = new ResponseEntity<byte[]>(FileCopyUtils.copyToByteArray(f),
header, HttpStatus.OK);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
바이너리값(이미지)을 갖고있는 응답객체를 return해 요청을 보낸 jsp로 돌아가 이미지를 뿌려준다~
0. Controller 총 코드
더보기
@Controller
@RequestMapping("/upload")
public class UploadController {
@Value("${spring.servlet.multipart.location}")
// application.properties에 정의한 경로를 읽어와서 변수에 넣어줌.
private String path; // path = /Users/~~~/Desktop/img/
@GetMapping("/form")
public void form() {
}
@PostMapping("/upload")
public String upload(ImgVo vo) {
MultipartFile f = vo.getFile();
String fname = f.getOriginalFilename(); // 원본 파일명
File f2 = new File(path + fname); // 업로드된 파일을 저장할 새 파일 생성
try {
f.transferTo(f2); // 파일 복사
System.out.println("title:" + vo.getTitle());
System.out.println(f2.getAbsolutePath());
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "redirect:/upload/list";
}
@GetMapping("/list")
public void list(Model m) {
File dir = new File(path);
String[] files = dir.list(); // 디렉토리에 저장된 파일들 이름을 배열에 담아줌.
m.addAttribute("imgs", files);
}
@GetMapping("/read_img")
// 이미지는 바이너리값 -> byte[]
public ResponseEntity<byte[]> read_img(String fname){
File f = new File(path+fname);
HttpHeaders header = new HttpHeaders(); // HttpHeaders : 여러 설정을 담음.
ResponseEntity<byte[]> result = null; // ResponseEntity 응답 객체 선언.
try { // 여러 설정값 중 Content-Type라는 값이 있음.
header.add("Content-Type", Files.probeContentType(f.toPath())); // 응답 데이터의 종류를 설정
// 응답 객체 생성
result = new ResponseEntity<byte[]>(FileCopyUtils.copyToByteArray(f),
header, HttpStatus.OK);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
}