배움 __IL/TIL 1기

TIL : 97번째- 230425 [4-4-화]

Mo_bi!e 2023. 4. 25. 20:57

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