헬스일정웹페이지 개발 때는 Ajax 이용 안하고 View에 다 때려박았다면,
이번엔 Ajax로 파일 전송 및 업로드를 구현해보았다.
어려울 것 같아서 시도도 안해봤었는데 생각보다 할만했다.
우선 파일 업로드 폼을 작성한다.
<table> <tbody><tr><td><input type="file" id="InputImage" onchange="readURL(this)"></td></tr> <tr><td><input type="text" placeholder="가로(pixel)" id="width"><input type="text" placeholder="세로(pixel)" id="height"></td></tr> <tr><td><input type="button" onclick="compression()" value="압축하기"></td></tr> </tbody></table>
onchange="readURL(this)" 와 onclick="compression()" 이 핵심이다
스크립트로 넘어가서 해당 메소드를 정의해준다.
먼저, 이미지 미리보기 소스
function readURL(input) { if (input.files && input.files[0]) { var reader = new FileReader(); reader.readAsDataURL(input.files[0]); reader.onload = function (e) { var tempImage=new Image(); tempImage.src=reader.result; console.log(tempImage); tempImage.onload=function(){ var canvas=document.createElement('canvas'); var canvasContext=canvas.getContext("2d"); var img = new Image(); img.src = e.target.result; canvas.width=img.width*0.5; canvas.height=img.height*0.5; canvasContext.drawImage(this,0,0,canvas.width,canvas.height); var dataURI=canvas.toDataURL("image/png"); document.querySelector("#thumbnail").src=dataURI; } }; } }
file을 선택하면 onchange 함수가 작동되고 input 타입으로 해당 파일이 넘어온다.
FileReader를 통해 해당 파일의 url을 읽어주고,
onload - > 읽혀지게 되면 내부 함수가 실행되고 이미지로 변환하는 소스이다.
썸네일 출력이 목적이기 때문에 원본 이미지의 가로, 세로 비율을 0.5 배해서 출력해주었다.
jpg 형식이면 var dataURI=canvas.toDataURL("image/png"); 를 변경시켜주도록 하는데, 이대로 두어도 출력은 잘 되더라.
출력은 아래 따로 정의된 <img src="./resources/default_original.png" style="border: 2px dotted black" id="thumbnail"/> 여기에 된다.
이제 Spring 과 파일을 주고받는 소스이다.
form method="post" 를 이용할 수도 있겠지만, Ajax로 비동기 처리 해주었다 .
<< script 코드 >>
function compression(){ // initializing $('#img').attr('src', './resources/default.png') .width('50%') .height('50%'); var file=document.querySelector('#InputImage'); var fileList=file.files; var reader=new FileReader(); if(fileList && fileList[0]){ reader.readAsDataURL(fileList[0]); reader.onload = function (e) { var img = new Image(); img.src = e.target.result; var formData = new FormData(); formData.append('RequestParam',fileList[0]); $.ajax( { url:'/springpath', type: 'POST', data: formData, processData: false, contentType: false, dataType: 'json',//xml, json, file을 받을 수 없음 enctype: 'multipart/form-data',//매 우 중 요 success: function(html){ console.log('success'); }, error: function(error){ } }).done(function( data ) {//server에서 데이터 반환된 뒤 실행되는 함수 $('#resultImg').attr('src', 'data:image/png;base64,'+data.resultBytes) //반환된 이미지(바이트스트림) 삽입 .width($('#width').val()) .height($('#height').val()); }); }; } }
나는 서버에서 PNG 이미지 압축을 해주었기 때문에 compress 어쩌고가 많지만, Ajax 형식만 참고하면 될 듯 하다.
다음 Java 코드
@ResponseBody @RequestMapping(value="/springpath", method=RequestMethod.POST,produces="application/json;charset=UTF-8" ) public Map<String, String> compactionImage(@RequestParam("ori") CommonsMultipartFile file) throws IOException { Map<String, String> result; if(file.getContentType().equals("image/jpeg") || file.getContentType().equals("image/jpg")) result=compactService.getCompactedJPGImage(file); else result=compactService.getCompactedPNGImage(file); return result; }
서비스 함수는 일단 회사에서 사용하는거라 올리기 좀 그래서 생략한다.
Pngtastic API를 활용했다는 것만 언급해두겠다.
중요한건,
produces="application/json;charset=UTF-8"
와 Map으로 Json 객체로 변환 후 리턴해 주었다는 것. (jackson core, json-simple maven 의존 추가는 필수다)
@RequestParam("ori") CommonsMultipartFile file
Parameter 명과 타입을 반드시 이렇게 해주어야한다.
MultipartFile로 받으면 계속 에러가난다. 여기서 삽질 하루했다 정말 ㅠㅠㅠ 자동 변환이 안되는 것 같다.
여기서 Param 명은 위 스크립트 코드의
formData.append('ori',fileList[0]);
과 일치시키는 것이다.
fromData도 잘 변환해주어야한다.
서비스 코드 전부를 공개하진 못하지만, 파일은 바이트url로 변경하는 것은
result.put("resultBytes", Base64.getEncoder().encodeToString(Files.readAllBytes(compressed_file.toPath())));
여기 Base64 클래스를 활용하면 된다.
그동안 Javascript 기초가 탄탄하지 않아 넘겼던 Ajax를 드디어 써보았다.
왜 그렇게 쫄았나 싶기도 하고.. 역시 사람은 닥치면 다 하게되는구나 싶기도 하고 ㅋㅋㅋㅋㅋㅋ
'개발 > Java & Spring ' 카테고리의 다른 글
[SpringMVC] GET/POST 요청시 파라미터/body 값 한글 깨짐 해결 (0) | 2018.10.23 |
---|---|
[Spring] ResponseEntity는 왜 쓰는 것이며 어떻게 쓰는걸까? (4) | 2018.10.16 |
[Spring] spring-retry로 요청을 재전송한다 한다 한다맨 - 개발일기 C[3] (0) | 2018.09.26 |
[Spring/Bootstrap] morris.js 로 차트 구현하기 - 개발일기 A[12] (2) | 2018.09.26 |
[Spring] MyBatis @Insert 후, key 값 반환받아오기 - 개발일기 A[11] (0) | 2018.08.16 |