카테고리 없음

[Spring & jQuery] 파일 및 Json 데이터 업로드2 (file & json data)

두리공장 2022. 6. 3. 00:18

지난 포스트에서 파일 업로드를 구현하였는데, 약간의 문제가 있었다.
VO를 Controller에서 return을 받을 경우에는 문제 없는데, 어떤 경우에는 resolver 에서 처리하지 못할 때도 있다.
그래서 json을 String으로 던져야 할 경우도 있다.이럴때 아래와 같이 사용해 보자.

Front는 기존과 동일하다.

$(document).ready(function(){
	/*파일이 변경된 경우*/
    $("#file1").on("change", function(e){
        handleImgFileSelect(e, function(result){
            if(result){
                fn_submit();
            }
            else{
                alert("확장자는 이미지 확장자만 가능합니다");
                return;
            }
        });


    });
});

//파일 업로드
function fn_submit(){
    var jsondata = {"itemno": "110111"};
    var form = $("#form")[0];
    var formData = new FormData();
    formData.append("file", $("#file1")[0].files[0]);
    formData.append("jsondata", new Blob([JSON.stringify(jsondata)], {type: "application/json"}));

    $.ajax({
        url: "/file/upload",
        type: "POST",
        processData: false,
        contentType: false,
        data: formData,
        success: function(res){
            alert("파일 업로드를 성공하였습니다");
            console.log("res:", res);
        },
        error: function(err){
            alert(err.responseText);
        }
    });
}

Java부분은 아래와 같이 바꾸어 보았다.

    // 파일스트림 및 json 데이터 처리
    @RequestMapping(value = "/upload2", method=RequestMethod.POST)
    public ResponseEntity<String> upload2(
            @RequestPart(value = "file", required = false) MultipartFile multi,
            @RequestPart(value = "jsondata") String jsondata) throws Exception {
        String filePath = "/Files";
        //json으로 return하기 위해  헤더에 utf8을 설정한다.
        HttpHeaders resHeader = new HttpHeaders();
        resHeader.add("content-Type", "text/json;charset=utf-8");

        FileVO fileVO = new FileVO();
        ObjectMapper mapper = new ObjectMapper();
        FileOutputStream fos = null;
        try{
            fileVO = mapper.readValue(jsondata,FileVO.class);
            String uploadPath = filePath + "/image/";
            String originalFilename = multi.getOriginalFilename();
            //파일의 확장자를 추출한다.
            String ext = originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length());
            long size = multi.getSize();

            if(!multi.isEmpty()){
                //디렉토리가 없으면 생성한다.
                File dire = new File(uploadPath);
                if(!dire.exists()) dire.mkdirs();

                //파일을 FileOutputStream 으로 저장한다. file.transferTo 를 대체함(Linux 에서 경로 이슈가 있음)
                File file = new File(uploadPath + originalFilename);
                fos = new FileOutputStream(file);
                fos.write(multi.getBytes());

                //VO를 map으로 매핑
                Map<String, Object> map = mapper.convertValue(fileVO, Map.class);

                //VO를 String 으로 매핑
                jsondata = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(fileVO);
            }

        }catch (Exception e){

        }finally {
            if(fos != null){
                fos.close();
            }
        }
        return new ResponseEntity<String>(jsondata, resHeader, HttpStatus.OK);
    }

VO <-> Map <-> String 간의 매핑을 위해서 ObjectMapper 유틸클래스를 사용하였다.
String to VO 할때에는 mapper.readValue 를 사용한다.
VO to Map인 경우에는 mapper.convertValue를 사용한다.
VO to String인 경우에는mapper.writerWithDefaultPrettyPrinter().writeValueAsString() 을 사용한다.

HttpHeader에 content-type 및 charset을 UTF8로 명시하여 Front에서 한글이 정상적으로 나오도록 하였다.
FileOutputStream을 사용하여 디렉토리에 파일을 저장할 경우 리눅스 환경에서도 동일한 위치에 저장되도록 하였다.(transferTO 메서드를 대체함)

이렇게 하고 나서 테스트를 해 보자

파일이 정상적으로 전송된다.