순서
1. 태그 추가 및 CSS 설정 추가
2. 이미지 출력 메서드 작성(showUploadImage())
3. 사용자가 정의한 값 즉 이미지만 선택할 수 있도록 <input> 태그에 속성 추가
4. encodeURIComponent() 메서드 적용
1. 태그 추가 및 CSS 설정 추가
업로드 파일 선택 <input> 태그 바로 아래 업로드 한 이미지를 볼 수 있도록 코드를 추가했습니다.
이후 CSS 설정을 추가했는데, 따로 작성하지 않고 해당 insertProduct.jsp 파일에 바로 추가했습니다.
<style type="text/css">
#result_card img{
max-width: 100%;
height: auto;
display: block;
padding: 5px;
margin-top: 10px;
margin: auto;
}
#result_card {
position: relative;
}
.imgDeleteBtn{
position: absolute;
top: 0;
right: 5%;
background-color: #ef7d7d;
color: wheat;
font-weight: 900;
width: 30px;
height: 30px;
border-radius: 50%;
line-height: 26px;
text-align: center;
border: none;
display: block;
cursor: pointer;
}
</style>
2. 이미지 출력 메서드 작성(showUploadImage())
AJAX success 속성의 콜백 함수에 전달받은 이미지 데이터를 활용하여 이미지가 출력되도록 코드를 작성했습니다.
작성할 코드량이 많았기 때문에 콜백 함수 내부에 작성하지 않고, 따로 메서드를 선언하여 그 구현부에 이미지를 출력하는 코드를 작성한 뒤 해당 함수를 호출하는 형태로 구현했습니다.
선언 및 호출할 메서드의 이름은 'showUploadImage'로 했습니다.
AJAX의 success 속성 값으로 작성한 콜백 함수에 showUploadImage() 메서드를 미리 호출하고 인자 값으로 서버로 전달받은 result를 부여했습니다. (업로드한 이미지 데이터(fileName, uuid, path)를 활용하여 이미지를 출력시키기 위함입니다.)
<script> 태그 제일 하단에 showUploadImage() 메서드를 선언 및 구현했습니다.
/* 이미지 출력 */
function showUploadImage(uploadResultArr){
}
success 콜백 함수가 실행된다는 것은 업로드 이미지 메서드가 정상적으로 수행되었다는 것이기 때문에 반환 데이터인 result를 전달받지 못할 가능성은 낮습니다만 혹여나 데이터를 전달받지 못했을 경우, 이미지를 출력시키는 태그를 추가해선 안되기 때문에 데이터를 검증하는 코드를 추가했습니다.
/* 이미지 출력 */
function showUploadImage(uploadResultArr){
/* 전달받은 데이터 검증 */
if(!uploadResultArr || uploadResultArr.length == 0)
{return}
}
id 속성 uploadResult인 <div> 태그 요소에 접근하기 위해 변수 선언 및 초기화했습니다.
/* 이미지 출력 */
function showUploadImage(uploadResultArr){
/* 전달받은 데이터 검증 */
if(!uploadResultArr || uploadResultArr.length == 0){return}
let uploadResult = $("#uploadResult");
}
서버에서 뷰로 반환할 때 List 타입 데이터를 전송하고 뷰에서 해당 데이터를 배열 형태로 전달받습니다.
제 프로젝트에선 한 개의 이미지 파일만 처리하기 때문에 이미지 데이터(filename, path, uuid)에 쉽게 접근할 수 있도록 변수 obj를 선언하여 서버로부터 전달받은 배열 데이터의 첫 번째 요소로 초기화했습니다.
/* 이미지 출력 */
function showUploadImage(uploadResultArr){
/* 전달받은 데이터 검증 */
if(!uploadResultArr || uploadResultArr.length == 0){return}
let uploadResult = $("#uploadResult");
let obj = uploadResultArr[0];
}
id 속성 값 uploadResult인 <div> 태그 내부에 이미지를 출력하는 태그 코드를 추가하기 위해 변수를 선언하고 초기화했습니다.
/* 이미지 출력 */
function showUploadImage(uploadResultArr){
/* 전달받은 데이터 검증 */
if(!uploadResultArr || uploadResultArr.length == 0){return}
let uploadResult = $("#uploadResult");
let obj = uploadResultArr[0];
let str = "";
}
이미지 출력을 요청하는 URL 매핑 메서드("/display")에 전달해 줄 파일의 경로와 이름을 포함하는 값을 저장하기 위한 변수를 추가했습니다.
/* 이미지 출력 */
function showUploadImage(uploadResultArr){
/* 전달받은 데이터 검증 */
if(!uploadResultArr || uploadResultArr.length == 0){return}
let uploadResult = $("#uploadResult");
let obj = uploadResultArr[0];
let str = "";
let fileCallPath = obj.uploadPath + "/s_" + obj.uuid + "_" + obj.fileName;
}
str 변수에 추가되어야 할 태그 코드인 문자열 값들을 저장해줍니다.
/* 이미지 출력 */
function showUploadImage(uploadResultArr){
/* 전달받은 데이터 검증 */
if(!uploadResultArr || uploadResultArr.length == 0){return}
let uploadResult = $("#uploadResult");
let obj = uploadResultArr[0];
let str = "";
let fileCallPath = obj.uploadPath + "/s_" + obj.uuid + "_" + obj.fileName;
str += "<div id='result_card'>";
str += "<img src='/display?fileName=" + fileCallPath +"'>";
str += "<div class='imgDeleteBtn'>x</div>";
str += "</div>";
}
태그 코드가 담긴 문자열 값인 str을 uploadResult 태그에 append() 메서드를 호출하여 추가했습니다.
/* 이미지 출력 */
function showUploadImage(uploadResultArr){
/* 전달받은 데이터 검증 */
if(!uploadResultArr || uploadResultArr.length == 0){return}
let uploadResult = $("#uploadResult");
let obj = uploadResultArr[0];
let str = "";
let fileCallPath = obj.uploadPath + "/s_" + obj.uuid + "_" + obj.fileName;
str += "<div id='result_card'>";
str += "<img src='/display?fileName=" + fileCallPath +"'>";
str += "<div class='imgDeleteBtn'>x</div>";
str += "</div>";
uploadResult.append(str);
}
마지막으로 fileCallPath 변수를 선언 및 초기화하는 코드를 아래와 같이 수정했습니다.
replace(/\\/g, '/'): 대상 String 문자열 중 모든 '\'을 '/'로 변경해준다는 의미
JavaScript는 Java의 replaceAll()과 같은 메서드가 없기 때문에 정규 표현식을 사용하여 치환 대상의 모든 문자를 지정할 수 있습니다.
// 변경 전
let fileCallPath = obj.uploadPath + "/s_" + obj.uuid + "_" + obj.fileName;
// 변경 후
let fileCallPath = obj.uploadPath.replace(/\\/g, '/') + "/s_" + obj.uuid + "_" + obj.fileName;
변경 후 테스트를 진행하면 정상적으로 이미지가 출력됩니다.
3. 사용자가 정의한 값 즉 이미지만 선택할 수 있도록 <input> 태그에 속성 추가
파일 선택을 눌렀을 때 모든 유형의 파일을 선택할 수 있게 하지 않고, 사용자가 지정한 값 즉 이미지만 선택할 수 있도록 <input> 태그에 accept 속성을 추가했습니다.
// 변경 전
<input type="file" class="upload-name" value="첨부파일" id ="fileItem" placeholder="첨부파일" name="uploadFile">
// 변경 후
<input type="file" class="upload-name" value="첨부파일" id ="fileItem" placeholder="첨부파일" name="uploadFile" accept=".gif, .jpg, .png">
4. encodeURIComponent() 메서드 적용
2번의 테스트에서 파일 이름에 한글이 들어갔지만, 웹브라우저에서 자동으로 한글을 UTF-8로 변환해줬기 때문에 정상적으로 동작했습니다.
하지만 UTF-8로 인코딩을 자동으로 해주지 않는 웹브라우저도 있기 때문에 encodeURIComponent() 메서드를 사용하여 코드를 보완했습니다.
encodeURIComponent() 메서드는 A-Z, a-z, 0-9, -, _,.,!, ~, *, ', ()을 제외한 모든 문자를 UTF-8로 인코딩하여 이스케이프 문자로 변환해줍니다.
fileCallPath 변수를 선언 및 초기화 한 문자 코드를 아래와 같이 변경했습니다.
//변경 전
let fileCallPath = obj.uploadPath.replace(/\\/g, '/') + "/s_" + obj.uuid + "_" + obj.fileName;
//변경 후
let fileCallPath = encodeURIComponent(obj.uploadPath.replace(/\\/g, '/') + "/s_" + obj.uuid + "_" + obj.fileName);
더불어 encodeURIComponent() 메서드는 '/'와 '\' 문자 또한 인코딩을 하기 때문에 replace() 메서드를 사용하지 않아도 동작합니다.
// replace 적용 => 동작 o
let fileCallPath = encodeURIComponent(obj.uploadPath.replace(/\\/g, '/') + "/s_" + obj.uuid + "_" + obj.fileName);
// replace 적용 x => 동작 o
let fileCallPath = encodeURIComponent(obj.uploadPath + "/s_" + obj.uuid + "_" + obj.fileName);
마지막으로 테스트하여 정상적으로 동작하는지 확인합니다.
'😎 STS3 Spring 쇼핑몰' 카테고리의 다른 글
STS3 쇼핑몰 프로젝트[26] 업로드 이미지 삭제 - 2 (0) | 2022.09.30 |
---|---|
STS3 쇼핑몰 프로젝트[26] 업로드 이미지 삭제 - 1 (0) | 2022.09.30 |
STS3 쇼핑몰 프로젝트[25] 업로드 된 이미지 출력 - 1 (0) | 2022.09.28 |
STS3 쇼핑몰 프로젝트[24] 상품 이미지 업로드(서버 단계 이미지 파일 체크) - 7 (0) | 2022.09.28 |
STS3 쇼핑몰 프로젝트[24] 상품 이미지 업로드(이미지 정보 뷰 반환2) - 6 (0) | 2022.09.27 |