I. dom
1. 파일업로드하기
(1) 서버로 파일 전송하기
1) 들어가며
AXIOS -> library 같은 파일전송을 위한 라이브러리도 있다.
2) js 파일업로드 구현
dropzone.ondrop = function(e){
e.preventDefault();
// console.log(e.dataTransfer.types);
if(e.dataTransfer.files.length > 1)
console.log("둘 이상의 파일 업로드 불가");
let file = e.dataTransfer.files[0];
let formData = new FormData();
// formData.append("username", "newlec"); //로그인 정보
// formData.append(file, "file");
formData.append("file", file);
formData.append("test", "hehe");
let request = new XMLHttpRequest();
request.onload = function(){
console.log("done");
}
request.onprogress = function(){
console.log("progress");
}
request.open("POST", "http://localhost:8080/upload");
//3번쨰 인자를 지정하지 않으면 true(비동기)\
// console.log("여기까지 옮?");
//이미 FormData()에 멀티파일 이 있어서 필요가 없음
// request.setRequestHeader("Content-Type", "multipart/form-data");
request.send(formData);
};
formData 객체를 사용해서 파일을 포함한 데이터를 만든다.
- 그리고 이 파일을 XMLHttpRequest()로 비동기적으로 서버와 데이터를 주고받을 수 있는 인스턴스를 만든다.
그 후 진행중인 상태에는 porgress 가 콘솔에 출력된다 (이 경우 속도에 따라서 log 출력횟수가 다르다)
그 후 완료되면 log에 done 이 출력된다.
- formdata.append 를 하면 key 는 file로 하고, 데이터를 file 로 해서 보내준다
"test" key 도 마찬가지이다.
- 이를 httpRequest() 인스턴스를 만들어주고, 서버에 요청을 열고나서 보내준다
- open() 함수로 POST 방식으로 데이터를 전송하는 것을 열고, send()로 데이터를 전송한다.
3) java 서버 단 구현
@CrossOrigin(origins = "*")
@RestController //파일 전송이끼 때문에 Rest
@RequestMapping("/")
public class HomeController {
// @ResponseBody
@GetMapping
public String index(){
return "hello index";
}
@PostMapping("upload")
public String upload
(MultipartFile file, String test){
System.out.println(file);
System.out.println(test);
System.out.println("upload call");
return "ok";
}
}
이거를 upload에서 받아준다
file 의 key 값에 대한 것이 출력되고
tset 의 key값에 대한 hehe가 출력된다
다만 이 경우 CORS 문제 때문에 crossOrigin 이 문제시된다
이를 대비하기 위해서 CrossOrigin을 이용한다.
3)
성공실패관련 http header를 보고 쉽게 업로드 여부에 대해서 보여 줄 수있다
(2) 받은 파일을 저장하기
1)
@PostMapping("upload")
public ResponseEntity<String> upload
(MultipartFile file,
HttpServletRequest request) throws IllegalStateException, IOException{
if(file.isEmpty())
return new ResponseEntity<String>("파일 전송을 하지않았음", HttpStatus.BAD_REQUEST);
//클라이언트로 인해서 저장될 실제 경로를 구하는 과정
//파일은 빠지고 경로만 얻자!
String urlPath = "/upload/";
// String urlfile = urlPath + file.getOriginalFilename();
String realPath = request.getServletContext().getRealPath(urlPath);
System.out.println(realPath);
File filePath = new File(realPath);
//경로가 존재하지 않는경우 만들어주기
if(!filePath.exists())
filePath.mkdirs();
String fileName = file.getOriginalFilename();
File saveFile = new File(filePath + File.separator + fileName);
System.out.println(filePath + File.separator + fileName);
file.transferTo(saveFile);
return new ResponseEntity<String>(fileName, HttpStatus.OK);
}
- 우선 리턴 자료형으로 ResponseEntity 가 있다.
이는 응답에 대해서 한번에 볼수 있는 응답 그릇으로 볼 수있다.
우선 크게 두부분으로 나누어 볼 수있다
파일을 전송한경우, 전송하지않은경우
1 : 우선 전송하지 않은경우는 file.isEmpty() 로 조건문을 만나서 바로 return 이 가능하다
그래서 이에대한 제네릭은 문자열로 하고, 400에러를 발생시킨다.
2 : 한편 전송한 경우는 다음과 같다.
우선 웹 어플리케이션 파일시스템상 경로(실제경로)로 바꾸어 주어야한다
즉 다시말하면 상대경로(즉 wepapp의 root 디렉토리가 아닌 현재 작업중인 디렉토리로 감)
getServletContext().getRealPath() 를 하면, 실제 디스크상의 경로를 구할 수있다
한편 여기서 getServletContext() 는 웹 어플리케이션에 대한 정보, 어플 내 공유되는 자원 관리 하는 것이다.
getRealPath() 는 이러한 웹어플리케이션에 대한 정보를 바탕으로 상대경로를 절대경로로 변환해준다.
- filePath 가 없으면 새로운 디렉토리 만들어준다.
File.separator 는 운영체제 따라 달리되는 구분자를 표현하기 위한 것이다.
transfer() 메소드는 매개변수인 saveFile 객체에 저장하는것을 의미한다.
마지막 return 은 응답 본문데이터와 HTTP 상태코드를 반환할 수있다.
HTTPStatus.OK 는 200 을 보여준다.
1. 보충
2. 회고
1) XMLHTTPReques() 를 오랜만에 써서 반가웠다
2) 그리고 지난번에 잘 이해가 어려웠던 파일전송과 관련해서도 익숙해져서 다행이다.
'배움 __IL > TIL 1기' 카테고리의 다른 글
TIL : 99번째- 230427 [4-4-목] (0) | 2023.04.27 |
---|---|
TIL : 98번째- 230426 [4-4-수] (0) | 2023.04.26 |
TIL : 95번째- 230421 [4-3-금] (0) | 2023.04.21 |
TIL : 94번째- 230420 [4-3-목] (0) | 2023.04.20 |
TIL : 93번째- 230419 [4-3-수] (4) | 2023.04.19 |