[21.10.25] file 입출력

4385 단어 SpringwebSpring

Ajax로 파일업로드 (Drag&Drop)

크롬 기본기능은 브라우저에 파일 및 이미지를 끌어다 놨을경우 해당 이미지를 새탭으로 보여줌

특정 div에 파일을 끌어다놓으면 파일 업로드를 위한 드래그가 되게끔 하려면

먼저 브라우저가 파일을 자동으로 열어주는 기능을 막아야함

$('.file-drop').on('dragenter dragover', function(event){
	event.preventDefault();
});
			
$('.file-drop').on('drop', function(event){
	event.preventDefault();   
	var formData=new FormData();
	var files=event.originalEvent.dataTransfer.files; //드래그한 file 정보
	var i=0;
				
	for(i=0;i<files.length; i++){
		console.log(files[i]);
		//서버로 보낼 form-data 작성
		formData.append("files", files[i]);					
	}

	$.ajax({
		type:'post',
		url:'/ex05/upload-ajax',
		data:formData,
		processData:false,
		contentType:false,
		success:function(data){
			console.log(data);
		}
	});
});
  • preventDefault() : event의 기본동작을 막음
  • FormData() : multipart/form-data 타입으로 파일을 업로드하는 객체
@PostMapping("/upload-ajax")
@ResponseBody
public ResponseEntity<String> uploadAjaxPOST(MultipartFile[] files) throws IOException {
	logger.info("uploadAjaxPOST() 호출");
		
	//임의의 파일 하나만 저장
	String result=null; //파일 경로 및 썸네일 이미지 이름
	result=FileUploadUtil.saveUploadedFile(
			uploadPath, files[0].getOriginalFilename(), files[0].getBytes()); 
		
	return new ResponseEntity<String>(result, HttpStatus.OK);		
}
  • getOriginalFilename() : 파일 이름
  • getBytes() : 파일 정보

임의로 하나만 저장해봄. 그러면 오늘날짜 폴더에 원본과 썸네일용이미지가 생성된다

서버에서 이미지파일 꺼내기

브라우저에서 서버로 이미지를 보내 저장하고 저장한 이미지를 서버에서 다시 꺼내는 건 시점문제때문에 불가능하다!

그래서 이미지의 경로만 서버에 저장한다. db에는 이미지 데이터를 가져오는게 아니라 데이터의 경로가 저장되어 있는 것.
이미지의 이름만 DB에 넣고 꺼낼땐 이미지의 경로와함께 사용하기

데이터 insert 시
jsp에서 이미지파일을 넣으면 controller에서 이미지의 이름을 db에 넣고 만들어진 폴더에 이미지 데이터를 저장.

데이터 select 시
DB에서 데이터를 가져오면 이미지의 이름만 나옴. 이미지 이름으로 다시 서버에서 폴더에 저장된 이미지 데이터를 가져오기

@GetMapping("/display")
public ResponseEntity<byte[]> display(String fileName) throws Exception{
	logger.info("display() 호출");
	ResponseEntity<byte[]> entity=null;
	InputStream in=null;
	
	String filePath=uploadPath+fileName;
	in=new FileInputStream(filePath); //파일넣기
		
	//파일 확장자
	String extension=filePath.substring(filePath.lastIndexOf(".")+1);
	logger.info(extension);
	
    	//응답헤더
	HttpHeaders httpHeaders=new HttpHeaders();
	httpHeaders.setContentType(MediaUtil.getMediaType(extension));
	
	//데이터 전송
	entity=new ResponseEntity<byte[]>(
		IOUtils.toByteArray(in), //파일에서 읽은 데이터
		httpHeaders, //응답헤더
		HttpStatus.OK);
	
	return entity;
}

파일이름을 전송해서 함수를 호출하면 서버에서 이미지를 확인할 수 있음

  • ResponseEntity<byte[]> : 이미지도 byte형태의 데이터이기 때문에 이미지데이터를 넘겨주기 위한 return 타입
  • HttpHeaders : org.springframework.http. 응답헤더에 Content-Type 설정

이미지 업로드 후 출력

위에서 다 했다. display를 통해 서버에 저장된 이미지를 다시 웹브라우저로 전송받았기때문에(그 결과가 ajax이 success) img태그로 전송받은 이미지데이터를 출력해주면 된다

$.ajax({
	type:'post',
	url:'/ex05/upload-ajax',
	data:formData,
	processData:false,
	contentType:false,
	success:function(data){
		console.log(data); //서버에 업로드된 파일이름을 가지고옴
		$('.upload-list').html("<img src=/ex05/display?fileName="+data+">");						
	}//success
}); //end ajax
  • processData : jquery에서 데이터를 기본적으로 쿼리스트링형태로 보내는데 파일전송은 쿼리스트링형태로 보내면 안되기 때문에 false로 해야함
  • contentType : default 값이 application/x-www-form-urlencoded; charset=UTF-8인데 파일은 multipart/form-data형태로 보내야 해서 false로 설정

설계가 중요
ajax를 사용하는 경로는 rest api를 따로 만들어서 사용
전자정부프레임워크=MVC구조=스프링!

좋은 웹페이지 즐겨찾기