[32] 파일 업로드 처리 - 브라우저에서 섬네일 처리

브라우저에서 첨부파일의 업로드 결과가 위와 같이 JSON 객체로 반환되었다면, 남은 작업은 다음과 같다.

  • 업로드 후에 업로드 부분을 초기화 시키는 작업
  • 결과 데이터를 이용해서 화면에 섬네일이나 파일 이미지를 보여주는 작업

현재 업로드는 <input type='file'>을 통해서 이루어지기 때문에 한 번 업로드가 끝난 후에는 이를 초기화 시켜주는 작업과 업로드된 결과를 화면에 반영해 줄 필요가 있다.

 

1. <input type='file'> 의 초기화 

 

<input type='file'>은 다른 DOM 요소들과 조금 다르게 readonly라 안쪽의 내용을 수정할 수 없기 때문에 별도의 방법으로 초기화 시켜서 또 다른 첨부파일을 추가할 수 있도록 만들어야 한다.

 

- uploadAjax.jsp에 아래 코드를 추가한다.

 

우선 첨부파일을 업로드 하기 전에 아무 내용이 없는 <input type = 'file'> 객체가 포함된 <div>를 복사한다. 첨부파일을 업로드한 뒤에는 복사된 객체를 <div>내에 다시 추가해서 첨부파일 부분을 초기화 시킨다. 

 

 

화면에서 첨부파일을 추가하고 버튼을 클릭하면 이전과 달리 첨부파일을 다시 추가할 수 있는 형태로 변경되는 것을 확인 할 수 있다. 

 

2. 업로드된 이미지 처리

 

업로드된 결과는 JSON 형태로 받아왔기 때문에 이를 이용해서 화면에 적절한 섬네일을 보여주거나 화면에 파일 아이콘 등을 보여주어서 결과를 피드백해줄 필요가 있다. Ajax의 처리결과를 보여주도록 수정한다. 

 

2-1. 파일 이름 출력

 

uploadAjax.jsp에는 별도의 JavaScript 함수를 추가해서 특정한 <ul> 태그 내에 업로드된 파일의 이름을 보여주도록 한다. 

 

화면에는 <ul> 태그를 작성해서 첨부파일 이름을 목록으로 처리할 수 있도록 준비한다.

 

- uploadAjax.jsp

 

JavaScript에서는 목록을 보여주는 부분을 별도의 함수로 처리한다.

	var uploadResult = $(".uploadResult ul");
		function showUploadedFile(uploadResultArr){
			var str = "";
			$(uploadResultArr).each(function(i,obj){
				str += "<li>" + obj.fileName + "</li>";
			});
			
			uploadResult.append(str);
		}

 

showUploadedFile()은 JSON 데이터를 받아서 해당 파일의 이름을 추가한다. Ajax결과에서는 받은 JSON 데이터를 ShowUploadedFile()을 호출하도록 수정한다. 

 

화면에서는 업로드 후에 단순한게 업로드된 파일의 이름들이 보이는 것을 확인할 수 있다. 

 

2-2. 일반 파일의 파일 처리

 

우선적으로 일반 파일이 업로드된 상황에서 첨부파일의 아이콘 등을 보여주도록 수정한다.

 

기존의 webapp 밑에 resources 폴더의 내용을 그대로 추가하고, img 폴더를 생성한다. 일반 첨부파일의 이미지를 보여줄 attach.png 파일을 추가한다. (attach.png 파일은 인터넷 등에서 구할 수 있는 무료 이미지이다)

 

uploadAjax.jsp 에서 일반 파일의 경우에는 attach.png 이미지가 보이게 수정한다. 화면에는 약간의 스타일을 적용해서 첨부파일 영역을 처리한다.

 

 

showUploadedFile()은 이미지 파일이 아닌 경우에 파일 아이콘을 보여주는 형태로 작성된다. 일반 파일을 첨부하면 아래와 같은 모습으로 보이게 된다.

 

2-3. 섬네일 이미지 보여주기 

 

일반 파일의 경우에는 단순히 파일 이미지만을 보여주지만 이미지 파일의 경우에는 섬네일 파일을 보여주어야 한다. 섬네일은 서버를 통해서 특정 URI를 호출하면 보여줄 수 있도록 처리하는데, 해당 파일의 경로와 uuid가 붙은 파일의 이름이 필요하므로 조금 복잡하다. 서버에서 섬네일은 GET 방식을 통해서 가져올 수 있도록 처리한다. 특정한 URI 뒤에 파일 이름을 추가하면 이미지 파일 데이터를 가져와서 <img> 태그를 작성하는 과정을 통해서 처리한다.

 

서버에 전송하는 데이터는 '파일의 경로' + 's_' + 'uuid'가 붙은 파일이름' 이다. 이때 주의해야 하는 항목은 경로나 파일 이름에 한글 혹은 공백 등의 문자가 들어가면 문제가 발생할 수 있으므로 JavaScript의 encodeURIComponent() 함수를 이용해서 URI에 문제가 없는 문자열을 생성해서 처리한다. 

 

[ uploadController 에서 섬네일 데이터 전송하기 ]

 

UploadController 에서는 특정한 파일 이름을 받아서 이미지 데이터를 전송하는 코드를 우선 생성한다. 

 

- UploadController.java

	@GetMapping("/display")
	@ResponseBody
	public ResponseEntity<byte[]> getFile(String fileName){
		log.info("fileName : " + fileName);
		File file = new File("c:\\upload\\" + fileName);
		log.info("file:" + file);
		
		ResponseEntity<byte[]> result = null;
		
		try {
			HttpHeaders header = new HttpHeaders();
			
			header.add("Content - Type", Files.probeContentType(file.toPath()));
			result = new ResponseEntity<>(FileCopyUtils.copyToByteArray(file), header, HttpStatus.OK);
		}catch (IOException e) {
			e.printStackTrace();
		}
		return result;
	}

 

getFile()은 문자열로 파일의 경로가 포함된 fileName을 파라미터로 받고 byte[]를 전송한다. byte[]로 이미지 파일의 데이터를 전송할 때 신경 쓰이는 것은 브라우저에 보내주는 MIME 타입이 파일의 종류에 따라 달라지는 점이다. 이 부분을 해결하기 위해서 probeContentType()을 이용해서 적절한 MIME 타입 데이터를 Http의 헤더 메시지에 포함할 수 있도록 처리한다. 

 

getFile()의 테스트는 upload 폴더 밑에 테스트할 수 있는 영문 이름의 파일들을 추가하고, 브라우저에서 http://localhost:8080/display?fileName=2018/07/06/test3.jpg와 같이 경로와 파일 이름을 같이 전달해 보는 방식으로 테스트할 수 있다.

 

uuid가 있으면 호출할 때 복잡하므로 단순한 이름의 파일들만 업로드와 관계된 경로에 추가한다. 테스트를 위해서 확장자가 jps인 파일들과 png인 파일들을 폴더에 넣어둔다. 

 

호출한 결과화면 ㅎㅎ 귀엽 ㅎ

브라우저에서는 올바르게 이미지가 보이고, 파일의 확장자에 맞게 MIME 타입이 변경되는 것을 볼 수 있다.

 

[ JavaScript 처리 ]

 

브라우저에서 GET 방식으로 첨부파일의 이름을 사용할 때에는 항상 파일 이름에 포함된 공백 문자나 한글 이름 등이 문제가 될 수 있다. 이를 수정하기 위해서는 encodeURIComponent()를 이용해서 URI 호출에 적합한 문자열로 인코딩 처리해야 한다. (크롬과 IE의 경우 서로 다르게 처리되어 첨부파일에 문제가 있을 수 있기 때문)

 

- uploadAjax.jsp 의 일부

 

브라우저에서는 이미지 종류의 파일을 업로드한 경우에는 섬네일 이미지가, 일반 파일의 경우에는 파일 아이콘이 보이게 된다. (근데 내 사진은 왜이리 쪼그맣지..?)