Part 23. 브라우저에서 섬네일 처리
23.2 업로드된 이미지 처리
- 업로드된 결과는 JSON 형태로 받아왔기 때문에 이를 이용해 화면에 적절한 섬네일을 보여주거나 화면에 파일 아이콘 등을 보여주어서 결과를 피드백해줄 필요가 있다.
- Ajax의 처리결과를 보여주도록 수정한다.
23.2.1 파일 이름 출력
- uploadAjax.jsp에는 별도의 JavaScript 함수를 추가해 특정한 < ul > 태그 내에 업로드된 파일의 이름을 보여주도록 한다.
- 화면에는 < ul > 태그를 작성해 첨부파일 이름을 목록으로 처리할 수 있도록 준비한다.
< uploadAjax.jsp >
<div class='uploadDiv'>
<input type='file' name='uploadFile' multiple>
</div>
<div class='uploadResult'>
<ul>
</ul>
</div>
- JavaScript에서는 목록을 보여주는 부분을 별도의 함수로 처리한다.
< uploadAjax.jsp >
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()을 호출하도록 수정한다.
< uploadAjax.jsp >
$.ajax({
url: '/uploadAjaxAction',
processData: false,
contentType: false,
data: formData,
type: 'POST',
dataType:'json',
success: function(result){
console.log(result);
showUploadedFile(result);
$(".uploadDiv").html(cloneObj.html());
}
}); //$.ajax
- 화면에서는 업로드 후에 단순하게 업로드된 파일의 이름들이 보이는 것을 확인할 수 있다.
첨부파일을 업로드할 때마다 목록에 추가되고, < input type='file' > 부분은 초기화
23.2.2 일반 파일의 파일 처리
- 첨부파일의 섬네일 이미지를 보여주는 작업은 조금 더 복잡하므로 우선적으로 일반 파일이 업로드된 상황에서 첨부파일의 아이콘 등을 보여주도록 수정한다.
- 기존의 webapp 밑에 resources 폴더의 내용을 그대로 추가하고, img 폴더를 생성한다.
- 일반 첨부파일의 이미지를 보여줄 attach.png 파일을 추가한다.(attach.png 파일은 인터넷 등에서 구할 수 있는 무료 이미지를 활용했다.)
- uploadAjax.jsp 에서 일반 파일의 경우에는 attach.png 이미지가 보이게 수정한다.
- 화면에는 약간의 스타일을 적용해 첨부파일 영역을 처리한다.
< uploadAjax.jsp >
<style>
.uploadResult {
width:100%;
background-color: gray;
}
.uploadResult ul{
display:flex;
flex-flow: row;
justify-content: center;
align-items: center;
}
.uploadResult ul li {
list-style: none;
padding: 10px;
}
.uploacResult ul li img{
width: 20px;
}
</style>
<div class='uploadResult'>
<ul>
</ul>
</div>
... 생략 ...
function showUploadedFile(uploadResultArr) {
var str = "";
$(uploadResultArr).each(function(i, obj) {
if(!obj.image) {
str += "<li><img src='/resources/img/attach.png'>" + obj.fileName + "</li>";
} else {
str += "<li>" + obj.fileName + "</li>";
}
});
uploadResult.append(str);
}
- showUploadFile()은 이미지 파일이 아닌 경우에 파일 아이콘을 보여주는 형태로 작성된다.
- 일반 파일을 첨부하면 아래와 같은 모습으로 보이게 된다.
23.2.3 섬네일 이미지 보여주기
- 일반 파일의 경우에는 단순히 파일 이미지만을 보여주지만 이미지 파일의 경우에는 섬네일 파일을 보여주어야 한다.
- 섬네일은 서버를 통해 URI를 호출하면 보여줄 수 있도록 처리하는데, 해당 파일의 경로와 uuid가 붙은 파일의 이름이 필요하므로 조금 복잡해진다.
- 서버에서 섬네일은 GET 방식을 통해 가져올 수 있도록 처리한다.
- 특정한 URI 뒤에 파일 이름을 추가하면 이미지 파일 데이터를 가져와서 < img > 태그를 작성하는 과정을 통해 처리한다.
- 서버에서 전송하는 데이터는 '파일의 경로' + 's_' + 'uuid가 붙은 파일 이름'이다.
- 이때 주의해야 하는 항목은 경로나 파일 이름에 한글 혹은 공백 등의 문자가 들어가면 문제가 발생할 수 있으므로 JavaScript의 encodeURIComponent() 함수를 이용해 URI에 문제가 없는 문자열을 생성해서 처리한다.
UploadController에서 섬네일 데이터 전송하기
- UploadController에서는 특정한 파일 이름을 받아서 이미지 데이터를 전송하는 코드를 우선 생성한다.
< UploadController >
@GetMapping("/display")
@ResponseBody
public ResponseEntity<byte[]> getFile(String fileName) {
log.info("fileName: " + fileName);
File file = new File("d:\\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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
- getFile()은 문자열로 파일의 경로가 포함된 fileName을 파라미터로 받고 byte[]를 전송한다.
- byte[]로 이미지 파일의 데이터를 전송할 때 신경 쓰이는 것은 브라우저에 보내주는 MIME 타입이 파일의 종류에 따라 달라지는 점이다.
- 이 부분을 해결하기 위해 probeContentType()을 이용해 적절한 MIME 타입 데이터를 Http의 헤더 메시지에 포함할 수 있도록 처리한다.
- uuid가 있으면 호출할 때 복잡하므로 단순한 이름의 파일들을 업로드와 관계된 경로에 추가한다.
- 테스트를 위해 확장자가 jpg인 파일들과 png인 파일들을 폴더에 넣어준다.
- 호출은 '/display?fileName='뒤에 '년/월/일/파일이름'의 형태로 호출한다.
- 브라우저에서는 올바르게 이미지가 보이고, 파일의 확장자에 맞게 MIME 타입이 변경되는 것을 볼 수 있다.
JavaScript 처리
- 브라우저에서 GET 방식으로 첨부파일의 이름을 사용할 때에는 항상 파일 이름에 포함된 공백 문자나 한글 이름 등이 문제가 될 수 있다.
- 이를 수정하기 위해서 encodeURIComponent()를 이용해 URI 호출에 적합한 문자열로 인코딩 처리해야 한다(크롬과 IE의 경우 서로 다르게 처리되어 첨부파일에 문제가 있을 수 있기 때문이다.).
< uploadAjax.jsp >
function showUploadedFile(uploadResultArr) {
var str = "";
$(uploadResultArr).each(function(i, obj) {
if(!obj.image) {
str += "<li><img src='/resources/img/attach.png'>" + obj.fileName + "</li>";
} else {
str += "<li>" + obj.fileName + "</li>";
var fileCallPath = encodeURIComponent( obj.uploadPath+ "/s_"+obj.uuid+"_"+obj.fileName);
str += "<li><img src='/display?fileName="+fileCallPath+"'><li>";
}
});
uploadResult.append(str);
}
- 브라우저에서는 이미지 종류의 파일을 업로드한 경우에는 섬네일 이미지가, 일반 파일의 경우에는 파일 아이콘이 보이게 된다.