yahayaha

29. 파일 다운로드( 다운로드 UUID 지우기, 이미지 원본 javascript 처리 ) 본문

spring/프로젝트

29. 파일 다운로드( 다운로드 UUID 지우기, 이미지 원본 javascript 처리 )

yaha 2024. 2. 21. 00:20

다운로드 자체 처리는 완료가 되었음. 그러면 이제 /uploadAjax 화면에서 업로드된 후 파일 이미지를 클릭한 경우 다운로드 될 수 있도록 처리.

 

이미지 파일인 경우는 이미지가 썸네일로 보여야하고 이미지가 아니면 첨부파일 아이콘이 보이게 해야함.

 

그에 대한 javascript 처리를 uploadAjax.jsp 에 진행.

 

function showUploadFile(uploadResultArr){

    var str = "";

    $(uploadResultArr).each(function(i, obj){

            if(!obj.image){
                var fileCallPath = encodeURIComponent( obj.uploadPath+"/"+obj.uuid+"_"+obj.fileName);

                str += "<li><a href='/download?fileName="+fileCallPath+"'>"
                +"<img src='resources/img/attach.png'>"+obj.fileName+"</a></li>"	
            }else{						

                var fileCallPath = encodeURIComponent(obj.uploadPath +"/s_"+obj.uuid+"_"+obj.fileName);

                str += "<li><img src='/display?fileName="+fileCallPath+"'/></li>";

            }
    });
    uploadResult.append(str);
}

 

코드를 수정 후 img 태그를 클릭하면 자동으로 다운로드가 되는걸 확인.

 

log도 확인.

 

다운로드가 정상적으로 이루어진 상태에서 서버에서 파일 이름에 UUID가 붙은 부분을 제거하고 원본 파일 이름으로 저장 할 수 있도록함.

 

UploadController에 코드 일부 추가 작업.

 

@GetMapping(value ="/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@ResponseBody
public ResponseEntity<Resource> downloadFile(@RequestHeader("User-Agent") String userAgent, String fileName){
    log.info("다운로드 파일 : " + fileName);

    // 다운로드할 파일의 경로를 지정하여 Resource 객체 생성
    Resource resource = new FileSystemResource("C:\\upload\\" + fileName);

    log.info("resource" + resource);

    // 파일이 존재하지 않는 경우 404 응답 반환
    if(resource.exists() == false) {
        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }

    // 다운로드할 파일의 이름을 가져옴
    String resourceName = resource.getFilename();

    //UUID 지우기
    String resourceOriginalName = resourceName.substring(resourceName.indexOf("_") + 1);

    // HTTP 응답 헤더 설정
    HttpHeaders headers = new HttpHeaders();

    try {

        //다운로드될 파일의 이름을 저장하는 변수를 선언하기위해 초기화
        String downloadName = null;

        // User-Agent 헤더를 기반으로 브라우저 종류를 파악하여 파일 이름 인코딩 처리
        if(userAgent.contains("Trident")) {

            log.info("IE 브라우저");

            // IE 브라우저인 경우 파일 이름을 UTF-8로 인코딩한 후 공백을 +로 치환하여 설정
            downloadName = URLEncoder.encode(resourceOriginalName, "UTF-8").replaceAll("\\+", " ");
        }else if(userAgent.contains("Edge")) {

            log.info("엣지 브라우저");

            // Edge 브라우저인 경우 파일 이름을 UTF-8로 인코딩하여 설정
            downloadName = URLEncoder.encode(resourceOriginalName, "UTF-8");

            log.info("엣지 name : " + downloadName);
        }else {

            log.info("크롬 브라우저");

            // 그 외의 브라우저인 경우(나는 일단 크롬만 쓸거니까 로그에는 크롬 브라우저만) 파일 이름을 ISO-8859-1로 인코딩하여 설정
            downloadName = new String(resourceOriginalName.getBytes("UTF-8"),"ISO-8859-1");
        }

        headers.add("Content-Disposition", "attachment; fileName=" + downloadName);


    } catch (UnsupportedEncodingException  e) {
        // 예외 발생 시 오류 출력
        e.printStackTrace();
    }

    // 다운로드할 파일의 Resource와 설정된 헤더를 이용하여 ResponseEntity 생성하여 반환
    return new ResponseEntity<Resource>(resource, headers, HttpStatus.OK);
}

 

수정된 부분은 한 줄의 코드.

 

//UUID 지우기
String resourceOriginalName = resourceName.substring(resourceName.indexOf("_") + 1);

파일이름을 가정하고 생각하면.

d73616bb-ca18-49fa-8801-c0d4a185385d_대상혁.jpg

resourceName 파일 이름이 담겨져있는 객체에서  subString(문자열 자르기)로 잘라야할 문자열을 찾아줌. 우리가 지워야하는건  " _ " 그리고 + 1을 해주는데 indexOf("_")는 36번째 위치에 있음. 근대 우리가 보여줘야하는건 대상혁.jpg를 보여줘야 하기에 _ 다음 문자부터를 선택하기 위해서 +1를 더해줌.

resourceName.substring(resourceName.indexOf("_") + 1) 은 밑줄( " _ " ) 다음 문자부터 끝까지의 문자열을 반환을함.

그렇기 때문에  d73616bb-ca18-49fa-8801-c0d4a185385d를 제외한 나머지 부분만 제외하게 됨.

아무튼 파일 이름만 다운로드 되는 것을 확인 가능함.

 

이제 원본 이미지를 보여줘야함. 일반 첨부파일과 다르게 썸네일이 보여지는 이미지 파일 경우 썸네일을 클릭하면 원본 이미지를 볼 수 있게 처리해야함.

 

이미지를 보여줄 jsp를 수정해야함.

function showImage(fileCallPath){
alert(fileCallPath);
}

$(document).ready(function(){


function showUploadFile(uploadResultArr){

    var str = "";

    $(uploadResultArr).each(function(i, obj){

            if(!obj.image){

                var fileCallPath = encodeURIComponent( obj.uploadPath+"/"+obj.uuid+"_"+obj.fileName);

                str += "<li><a href='/download?fileName="+fileCallPath+"'>"
                +"<img src='resources/img/attach.png'>"+obj.fileName+"</a></li>"	
            }else{						

                var fileCallPath = encodeURIComponent(obj.uploadPath +"/s_"+obj.uuid+"_"+obj.fileName);

                var originPath = obj.uploadPath+ "\\"+obj.uuid + "_"+obj.fileName;

                originPath = originPath.replace(new RegExp(/\\/g),"/"); 

                str += "<li><a href=\"javascript:showImage(\'"+originPath+"\')\">
                <img src='/display?fileName="+fileCallPath+"'>
                </a></li>";

            }
    });
    uploadResult.append(str);
}

 

showImage() 함수는 $(document).ready(function(){}의 밭깥쪽에 작성해야함.

 

그래야 a 태그에서 직접 showImage()를 호출할 수 있는 방식으로 작동하기 위함.

 

이미지 첨부파일의 경우 업로드된 경로와 UUID가 붙은 파일의 이름이 필요하기 때문에 originPath라는 변수를 통해서 

 

하나의 문자열을 생성. 생성된 문자열은 \ 기호 때문에 일반 문자열과 다르게 처리됨. 

 

replace를 활용해서 / 변환 후 showImage 파라미터에 전달. 그리고 브라우저에서 파일 업로드 이후 썸네일을 클릭하면 호출되는걸 확인 가능함.

 

이제 이미지를 클릭하면 원본 이미지를 보여주는 div와 style을 작성해줌.

 

<style type="text/css">
.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;
}
.uploadResult ul li img{
	width: 100%;
}

.bigPictureWrapper{
	position: absolute;
	display: none;
	justify-content: center;
	align-items: center;
	top: 0%;
	width: 100%;
	height: 100%;
	background-color: gray;
	z-index: 100;
	background: rgba(255,255,255,0.5);
}
.bigPicture{
	position: relative;
	display: flex;
	justify-content: center;
	align-items: center;
}

.bigPicture img{
	width: 600px;
}


</style>

<div class="bigPictureWrapper">
	<div class="bigPicture">
	</div>
</div>

 

 

그리고 div 이벤트도 처리를 해줘야함.

function showImage(fileCallPath){
//alert(fileCallPath);

function showImage(fileCallPath){
//alert(fileCallPath);

$("bigPictureWrapper").css("display", "flex").show();

$(".bigPicture")
.html("<img src='/display?fileName=" + encodeURI(fileCallPath) + "'>")
.anumate({width: '100%', height: '100%'}, 1000);

$(".bigPictureWrapper").on("click", function(e){
    $(".bigPicture").anomate({width: '0%', height: '0%'}, 1000);
    setTimeout(() => {
        $(this).hide();
        }, 1000);
    }
}

 

 

$(".bigPicture")
.html("<img src='/display?fileName=" + encodeURI(fileCallPath) + "'>")
.animate({width: '100%', height: '100%'}, 1000);​

이 부분은 내부적으로 화면 가운데 배치하는 작업 후 img 태그를 추가하고 animate를 이용해서 지정된 시간동안 화면에 열리는 효과를 처리함.

 

$(".bigPictureWrapper").on("click", function(e){
    $(".bigPicture").animate({width: '0%', height: '0%'}, 1000);
    setTimeout(() => {
        $(this).hide();
        }, 1000);
    }
}

 

원본 이미지 혹은 주변 배경을 선택하면 이미지를 작게 줄여줌. setTimeout에 적용된 => (에로우펑션)은 chrome에서는 정상 작동하지만 IE에서는 제대로 작동이 안됨. 필요하다면 코드를 수정해야함.

일단 브라우저에서 확인.

 

젠장 또 대상혁이야

 

그리고 다른곳을 클릭하면 없어지는걸 확인할 수 있음.