아키텍처와 함께

블로그 이미지
by gregorio
  • Total hit
  • Today hit
  • Yesterday hit

프로젝트를 수행하면서 파일 업로드는 다양한 방식으로 개발이 가능하다.


파일 업로드 시 업로드할 파일을 Drag and Drop 방식으로 File을 브라우저에 첨부한 후 업로드하는 방식에 대해 설명하고자 한다.


인터넷을 검색하면 Drag and Drop의 다양한 파일 업로드 방식이 있으나, 적용 시 손쉽게 적용할 수 있는 방법을 소개한다.


먼저 파일을 업로드하는 Jsp파일이다.


■ fileUpload.jsp 전체 소스

<html>

<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>

<style>

#dragandrophandler

{

border:2px dotted #0B85A1;

width:400px;

color:#92AAB0;

text-align:left;vertical-align:middle;

padding:10px 10px 10 10px;

margin-bottom:10px;

font-size:200%;

}



.progressBar {

    width: 200px;

    height: 22px;

    border: 1px solid #ddd;

    border-radius: 5px; 

    overflow: hidden;

    display:inline-block;

    margin:0px 10px 5px 5px;

    vertical-align:top;

}

 

.progressBar div {

    height: 100%;

    color: #fff;

    text-align: right;

    line-height: 22px; /* same as #progressBar height if we want text middle aligned */

    width: 0;

    background-color: #0ba1b5; border-radius: 3px; 

}

.statusbar

{

    border-top:1px solid #A9CCD1;

    min-height:25px;

    width:700px;

    padding:10px 10px 0px 10px;

    vertical-align:top;

}

.statusbar:nth-child(odd){

    background:#EBEFF0;

}

.filename

{

display:inline-block;

vertical-align:top;

width:250px;

}

.filesize

{

display:inline-block;

vertical-align:top;

color:#30693D;

width:100px;

margin-left:10px;

margin-right:5px;

}

.abort{

    background-color:#A8352F;

    -moz-border-radius:4px;

    -webkit-border-radius:4px;

    border-radius:4px;display:inline-block;

    color:#fff;

    font-family:arial;font-size:13px;font-weight:normal;

    padding:4px 15px;

    cursor:pointer;

    vertical-align:top

    }

</style>


<script>


var arrStatus = [];

var formDatas = [];

$(document).ready(function()

{

var obj = $("#dragandrophandler");

obj.on('dragenter', function (e) 

{

    e.stopPropagation();

    e.preventDefault();

    $(this).css('border', '2px solid #0B85A1');

});

obj.on('dragover', function (e) 

{

     e.stopPropagation();

     e.preventDefault();

});

obj.on('drop', function (e) 

{

 

     $(this).css('border', '2px dotted #0B85A1');

     e.preventDefault();

     var files = e.originalEvent.dataTransfer.files;

 

     //We need to send dropped files to Server

     handleFileUpload(files,obj);

});

$(document).on('dragenter', function (e) 

{

    e.stopPropagation();

    e.preventDefault();

});

$(document).on('dragover', function (e) 

{

  e.stopPropagation();

  e.preventDefault();

  obj.css('border', '2px dotted #0B85A1');

});

$(document).on('drop', function (e) 

{

    e.stopPropagation();

    e.preventDefault();

});

$("#upload").click(function(e){

e.preventDefault();

alert("send file to server");

for (var i = 0; i < arrStatus.length; i++) {

debugger;

sendFileToServer(formDatas[i], arrStatus[i]);

}

    });  

});

function sendFileToServer(formData,status)

{

    var uploadURL ="http://localhost:8080/sample/fileupload.do"; //Upload URL

    var extraData ={path:"d:/temp/files", }; //Extra Data.

    formData.append("path", "d:/temp/files");

    formData.append("saveName", "log_org.zip");

    

    debugger;

    var jqXHR=$.ajax({

            xhr: function() {

            var xhrobj = $.ajaxSettings.xhr();

            if (xhrobj.upload) {

                    xhrobj.upload.addEventListener('progress', function(event) {

                        var percent = 0;

                        var position = event.loaded || event.position;

                        var total = event.total;

                        if (event.lengthComputable) {

                            percent = Math.ceil(position / total * 100);

                        }

                        //Set progress

                        status.setProgress(percent);

                    }, false);

                }

            return xhrobj;

        },

    url: uploadURL,

    type: "POST",

    contentType:false,

    processData: false,

        cache: false,

        data: formData,

        success: function(data){

            status.setProgress(100);

 

            $("#status1").append("File upload Done<br>");         

        }

    }); 

 

    status.setAbort(jqXHR);

}

 

var rowCount=0;

function createStatusbar(obj)

{

     rowCount++;

     var row="odd";

     if(rowCount %2 ==0) row ="even";

     this.statusbar = $("<div class='statusbar "+row+"'></div>");

     this.filename = $("<div class='filename'></div>").appendTo(this.statusbar);

     this.size = $("<div class='filesize'></div>").appendTo(this.statusbar);

     this.progressBar = $("<div class='progressBar'><div></div></div>").appendTo(this.statusbar);

     this.abort = $("<div class='abort'>Abort</div>").appendTo(this.statusbar);

     obj.after(this.statusbar);

 

    this.setFileNameSize = function(name,size)

    {

        var sizeStr="";

        var sizeKB = size/1024;

        if(parseInt(sizeKB) > 1024)

        {

            var sizeMB = sizeKB/1024;

            sizeStr = sizeMB.toFixed(2)+" MB";

        }

        else

        {

            sizeStr = sizeKB.toFixed(2)+" KB";

        }

 

        this.filename.html(name);

        this.size.html(sizeStr);

    }

    this.setProgress = function(progress)

    {       

        var progressBarWidth =progress*this.progressBar.width()/ 100;  

        this.progressBar.find('div').animate({ width: progressBarWidth }, 10).html(progress + "% ");

        if(parseInt(progress) >= 100)

        {

            this.abort.hide();

        }

    }

    this.setAbort = function(jqxhr)

    {

        var sb = this.statusbar;

        this.abort.click(function()

        {

            jqxhr.abort();

            sb.hide();

        });

    }

}

function handleFileUpload(files,obj)

{

   for (var i = 0; i < files.length; i++) {

    //FormData

var fd = new FormData();

        fd.append('file', files[i]);

        formDatas[i] = fd;

 

        //Status bar

        var status = new createStatusbar(obj); //Using this we can set progress.

        status.setFileNameSize(files[i].name,files[i].size);

        arrStatus[i] = status;

        //sendFileToServer(fd,status);

 

   }

}


</script>

</head>

 

<body>

<div id="dragandrophandler">Drag & Drop Files Here</div>

<br><br>

<div>

<button type="button" id="upload" name="upload">upload</button>

</div>

<div id="status1"></div>


</body>

</html>


Drag and Drop으로 파일 업로드하는 두가지 방식이 있다.

인터넷을 검색하여 찾은 소스는 파일 선택 시 바로 업로드 하게 되어 있는데 변경한 방식은 UPLOAD 버튼을 선택 시 파일을 업로드 하게 재구성하였다.



Script의 handleFileUpload의 FormData와 status객체를 생성하여 sendFileToServer function을 바로 호출하면 파일을 Drag and Drop이 완료된 후 바로 파일을 업로드 한다.



■ Drag & Drop 시 서버로 파일 전송

  function handleFileUpload(files,obj)

{

   for (var i = 0; i < files.length; i++) {

var fd = new FormData();

        fd.append('file', files[i]);

 

        //Status bar

        var status = new createStatusbar(obj); //Using this we can set progress.

        status.setFileNameSize(files[i].name,files[i].size);

        sendFileToServer(fd,status);

 

   }

}



그러나 업무상으로 File을 Drag & Drop으로 첨부한 후 upload 버튼을 선택 시 파일을 서버로 전송하고자 하는 경우에는 Array Object를 생성하여 FormData와 status를 Array Object에 저장한 후 Upload 버튼 선택 시 파일을 업로드할 수 있다.


■ Drag & Drop 파일 객체 저장 방식

  function handleFileUpload(files,obj)

{

   for (var i = 0; i < files.length; i++) {

    //FormData

var fd = new FormData();

        fd.append('file', files[i]);

        formDatas[i] = fd;

 

        //Status bar

        var status = new createStatusbar(obj); //Using this we can set progress.

        status.setFileNameSize(files[i].name,files[i].size);

        arrStatus[i] = status;

 

   }

}


■ upload 버튼 Click 시 파일 전송

$("#upload").click(function(e){

e.preventDefault();

alert("send file to server");

for (var i = 0; i < arrStatus.length; i++) {

debugger;

sendFileToServer(formDatas[i], arrStatus[i]);

}

 


파일을 업로드 할 때 추가적인 정보를 같이 넘겨주는 경우가 있는데 파일을 저장하기 위해 FormData 객체를 사용하고 있기 때문에 FormData 의 append method를 이용하여 추가적인 정보를 같이 전달할 수 있다.


  function sendFileToServer(formData,status)

{

    var uploadURL ="http://localhost:8080/sample/fileupload.do"; //Upload URL

    var extraData ={path:"d:/temp/files", }; //Extra Data.

    formData.append("path", "d:/temp/files");

    formData.append("saveName", "log_org.zip");

    



다음은 서버 프로그램이다.


먼저 Fileupload 화면을 보여주는 Controller이다.


@RequestMapping(value="/sample/filePageView.do")

public ModelAndView filePageView() throws Exception {

ModelAndView mav = new ModelAndView();

mav.setViewName("fileUpload");

return mav;


ModelAndView 객체를 생성하여 fileUpload.jsp를 browser에 보여준다.


파일을 업로드하는 Controller이다.


@RequestMapping(value="/sample/fileupload.do", method = RequestMethod.POST)

    public @ResponseBody LinkedList<Map<String, Object>> upload(MultipartHttpServletRequest request, HttpServletResponse response,

    String path, String saveName) {

 

        //1. build an iterator

         Iterator<String> itr =  request.getFileNames();

         MultipartFile mpf = null;

 

         LinkedList<Map<String, Object>> files = new LinkedList<Map<String, Object>>();

         //2. get each file

         while(itr.hasNext()){

 

             //2.1 get next MultipartFile

             mpf = request.getFile(itr.next());

             LOGGER.debug(mpf.getOriginalFilename() +" uploaded! "+ files.size());

 

 

             //2.3 create new fileMeta

             Map<String, Object> fileMeta = new HashMap<String, Object>();

             fileMeta.put("fileName", mpf.getOriginalFilename());

             fileMeta.put("fileSize", mpf.getSize()/1024+" Kb");

             fileMeta.put("fileType", mpf.getContentType());

// 

             try {

//                fileMeta.setBytes(mpf.getBytes());

 

                 // copy file to local disk (make sure the path "e.g. D:/temp/files" exists)            

                 FileCopyUtils.copy(mpf.getBytes(), new FileOutputStream("D:/temp/files/"+mpf.getOriginalFilename()));

 

            } catch (IOException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

             //2.4 add to files

             files.add(fileMeta);

         }

        // result will be like this

        // [{"fileName":"app_engine-85x77.png","fileSize":"8 Kb","fileType":"image/png"},...]

        return files;

    } 


Chrome과 IE 11버전에서 정상적으로 실행되는것을 확인하였다.




'Spring Framrwork' 카테고리의 다른 글

Spring framework Property Reload  (0) 2018.04.13
Mybatis include sql  (0) 2018.03.23
Spring framework XML Marshaller( Jaxb2Marshaller )  (0) 2018.03.09
spring framework interceptor  (0) 2018.03.02
Google Map javascript API 사용법  (0) 2018.02.07
AND

ARTICLE CATEGORY

분류 전체보기 (56)
Spring Framrwork (33)
Linux (1)
APM (1)
Java (8)
python (0)
ant (1)
chart (1)
OS (1)
tomcat (1)
apache (1)
database (0)

RECENT ARTICLE

RECENT COMMENT

CALENDAR

«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

ARCHIVE

LINK