티스토리 뷰

728x90
반응형

개인 토이프로젝트 진행중 AJAX를 사용하여 form의 input 데이터와 file 데이터를 Controller로 전달을 했어야 했는데 

구글링을 하여 이것저것 찾아봤지만 다수의 글이 form에 enctype을 설정하거나 AJAX에 enctype을 설정하는 방법이 많았지만 file을 base64로 변환하여 컨트롤러에 전달하여 파일 객체를 생성 후 디렉토리에 저장하는 방법이 있어서 참고하여 글을 진행하겠습니다!

 

Step 01 - JavaScript로 파일 업로드하여 base 64로 변환

  • js부분은 파일을 업로드 후 22 ~ 25번 라인만 보시면 되는데 파일이 업로드가 되었으면 filename, cover의 id에 각각 값을 할당하고 있습니다. filename, cover는 각 <input />입니다.

 

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
<Input class="uploadProfileInput" type="file" id="newProfilePhoto" accept="image/*" style="display: none;" />
 
$(document).on("change"".uploadProfileInput"function () {
  var triggerInput = this;
  var currentImg = $(this).closest(".pic-holder").find(".pic").attr("src");
  var holder = $(this).closest(".pic-holder");
  var wrapper = $(this).closest(".profile-pic-wrapper");
  $(wrapper).find('[role="alert"]').remove();
  
  var files = !!this.files ? this.files : [];
  if (!files.length || !window.FileReader) {
    return;
  }
  if (/^image/.test(files[0].type)) {
    var reader = new FileReader(); // instance of the FileReader
    reader.readAsDataURL(files[0]); // read the local file
 
    var file = $("#newProfilePhoto")[0].files[0];
    var filename = file.name;
    
    reader.onloadend = function () {
        var base64data = reader.result;
        var data = base64data.split(',')[1];
        $("#filename").val(filename);  //여기         
        $("#cover").val(data);  //여기
    }; 
  }
});
cs

 

Step 02 - AJAX로 Controller에 값 전달하기

  • 17번 라인에서 serializeObject() 함수를 사용하여 전달하고 있는데 이것을 사용한 이유는 form의 <input name />에서 name을 array로 던지기 위함입니다. - #submitForm은 form의 id입니다.
  • cover에 bas64로 값을 세팅하여 전달하고 있습니다.

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
jQuery.fn.serializeObject = function() { 
    var obj = null
    try { 
        if(this[0].tagName && this[0].tagName.toUpperCase() == "FORM" ) { 
            var arr = this.serializeArray(); 
            if(arr){ obj = {}; 
            jQuery.each(arr, function() { 
                obj[this.name= this.value; }); 
            } 
        } 
    }catch(e) { 
        alert(e.message); 
    }
    return obj; 
}
 
var data = $("#submitForm").serializeObject();
 
var request = $.ajax({
       url: "/app/mapper/write",
       type : "POST",
       data:JSON.stringify(data),
      contentType:'application/json',
       dataType:'json',
   });
cs

 

Step 03 - Controller에서 값 받기

  • Controller에서 다른 기능은 삭제를 하고 해당 예제에 맞는 데이터만 param으로 출력을 하고 있습니다.
  • import org.apache.commons.codec.binary.Base64; 를 import해줘야 합니다. 
  • 해당 Base64를 사용하기 위해서는 pom.xml에 commons-codec DI를 추가해줘야 합니다.
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
32
33
34
35
36
@PostMapping(value = "/app/mapper/write")
@ResponseBody
public void write(@RequestBody Map<String, Object> param) throws Exception {
    
    try {
        String filePath  = null;
        String file      = (String) param.get("cover");
        String filename  = (String) param.get("filename");
        
        if(file != "") {
          UUID uuid = UUID.randomUUID();
           filePath  = 업로드할 디텍토리 경로 + "" + uuid + "_" +filename;
            
            makeFileWithString(file, filename, uuid);
        }

// filePath <- 변수를 DB에 저장 (이미지 업로드 경로)
    } catch (Exception e) {
        e.printStackTrace();
    }
}
 
private static void makeFileWithString(String base64, String filename, UUID uuid){
    byte decode[] = Base64.decodeBase64(base64);
    FileOutputStream fos;
    try{
        File target = new File(업로드할 디텍토리 경로 + "" + uuid + "_" +filename);
        target.createNewFile();
        fos = new FileOutputStream(target);
        fos.write(decode);
        fos.close();
    }catch(Exception e){
        e.printStackTrace();
    }
}
cs
 
 
 

 

1
2
3
4
5
6
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.9</version>
</dependency>
cs

 

Step 04 - 파일 업로드 결과 확인

결과를 보면 해당 프로젝트 디렉토리 경로에 파일이 업로드 된것을 확인할 수 있습니다.

 

DB에는 업로드한 디렉토리의 경로만 저장을 하고 있습니다.

728x90
반응형