Notice
Recent Posts
Recent Comments
Link
투케이2K
13. (spring/스프링) Post Body Form Data 사용해 서버 로컬에 사진 이미지 저장 실시 - post man (포스트맨) 멀티 파트 예시 추가 본문
Spring
13. (spring/스프링) Post Body Form Data 사용해 서버 로컬에 사진 이미지 저장 실시 - post man (포스트맨) 멀티 파트 예시 추가
투케이2K 2021. 7. 15. 17:48[ 개발 환경 설정 ]
개발 툴 : inteli j
개발 언어 : spring
[ 폴더 및 파일 추가 ]
[소스코드 : controller >> ModuleApiController]
package com.project.solutionpackage.controller;
import org.springframework.boot.configurationprocessor.json.JSONArray;
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.ui.Model;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
// [rest 방식 컨트롤러 / Controller = view 연결]
@RestController
public class ModuleApiController {
/**
* [클래스 설명]
* 1. thymeleaf 타임리프 view 지정 부분 (html 지정)
* */
// [post body form data 방식 : map]
// [경로 지정 : http://localhost:7000/resourceInsertImage]
// [body 요청 데이터 : idx = 특정 값 / file = 저장할 파일]
// [로직 : 사용자 url 호출 및 body 데이터 전송 >> 서버 로컬 pc에 이미지 저장 >> 리턴 데이터 반환]
@PostMapping("/resourceInsertImage")
public String resourceInsertImage(
@RequestParam("idx") String idx,
@RequestParam("file") MultipartFile files){
// 사용자는 매개변수에서 지정한 파라미터 명칭에 맞게 key 값으로 넣어야합니다
System.out.println("\n");
System.out.println("=======================================");
System.out.println("[ModuleApiController] : [resourceInsertImage] : [start]");
System.out.println("[request idx] : " + String.valueOf(idx)); //추가 파라미터
System.out.println("[request FileName] : " + String.valueOf(files.getOriginalFilename())); //이미지 이름
System.out.println("[request FilSize] : " + String.valueOf(files.getSize())); //이미지 사이즈
System.out.println("=======================================");
System.out.println("\n");
// [로직 수행 결과 값을 전송할 변수 선언]
JSONObject result = new JSONObject();
// [서버 로컬에 이미지 저장 로직 수행 실시]
try {
// 시스템 os 정보 확인 변수 선언
String os = System.getProperty("os.name").toLowerCase();
// 사진을 저장할 폴더 경로 변수 선언
String folderRoot = "";
// File 객체 정의
File file;
// os 정보 확인 및 사진을 저장할 서버 로컬 경로 지정 실시
if(os.contains("win")) {
System.out.println("\n");
System.out.println("=======================================");
System.out.println("[ModuleApiController] : [resourceInsertImage] : [os check]");
System.out.println("[os] : " + "Windows");
System.out.println("=======================================");
System.out.println("\n");
folderRoot = "c:/Home/Resource/assets/"; //윈도우 경로 (디스크 필요)
}
else if(os.contains("linux")) {
System.out.println("\n");
System.out.println("=======================================");
System.out.println("[ModuleApiController] : [resourceInsertImage] : [os check]");
System.out.println("[os] : " + "Linux");
System.out.println("=======================================");
System.out.println("\n");
folderRoot = "/Home/Resource/assets/"; //리눅스 경로
}
else {
System.out.println("\n");
System.out.println("=======================================");
System.out.println("[ModuleApiController] : [resourceInsertImage] : [os check]");
System.out.println("[os] : " + "None");
System.out.println("=======================================");
System.out.println("\n");
// os 확인을 하지 못한 경우 즉시, api 종료
try {
result.put("state", "F");
result.put("message", "Not Storage");
return result.toString();
} catch (JSONException jsonException) {
jsonException.printStackTrace();
}
}
// 파일 객체 생성 및 폴더 생성 여부 확인 수행
file = new File(folderRoot);
if(!file.exists()) { //폴더가 존재하지 않는 경우
file.mkdirs(); //폴더 생성 수행
System.out.println("\n");
System.out.println("=======================================");
System.out.println("[ModuleApiController] : [resourceInsertImage] : [folder check]");
System.out.println("[folder] : " + "not exists");
System.out.println("[folder] : " + "create");
System.out.println("=======================================");
System.out.println("\n");
}
else { //폴더가 존재하는 경우
System.out.println("\n");
System.out.println("=======================================");
System.out.println("[ModuleApiController] : [resourceInsertImage] : [folder check]");
System.out.println("[folder] : " + "exists");
System.out.println("=======================================");
System.out.println("\n");
}
// 파일명에 현재 연도,월,일,시,분,초 + 이미지 파일명 조합 실시 및 서버 로컬에 이미지 저장 수행
String fileName = getNowTime24() + "_" + String.valueOf(files.getOriginalFilename());
FileOutputStream fos = new FileOutputStream(folderRoot+fileName);
byte data[] = files.getBytes();
InputStream inputStream = files.getInputStream();
int readCount = 0;
while ((readCount = inputStream.read(data)) != -1){
fos.write(data,0, readCount);
}
fos.close();
inputStream.close();
// 모든 로직 처리가 정상 완료 된 경우
System.out.println("\n");
System.out.println("=======================================");
System.out.println("[ModuleApiController] : [resourceInsertImage] : [image save]");
System.out.println("[result] : " + "Success");
System.out.println("[fileRoot] : " + (folderRoot+fileName));
System.out.println("=======================================");
System.out.println("\n");
result.put("state", "T");
result.put("message", "Success");
}
catch (Exception e){
// 로직 처리 중 예외가 발생한 경우
System.out.println("\n");
System.out.println("=======================================");
System.out.println("[ModuleApiController] : [resourceInsertImage] : [image save]");
System.out.println("[result] : " + "Fail");
System.out.println("=======================================");
System.out.println("\n");
try {
result.put("state", "F");
result.put("message", "Fail");
} catch (JSONException jsonException) {
jsonException.printStackTrace();
}
e.printStackTrace();
}
return result.toString(); //리턴 데이터 반환
}
// [현재 시간 알아오는 메소드]
public static String getNowTime24() {
long time = System.currentTimeMillis();
//SimpleDateFormat dayTime = new SimpleDateFormat("hh:mm:ss");
SimpleDateFormat dayTime = new SimpleDateFormat("yyyyMMddkkmmss");
String str = dayTime.format(new Date(time));
return "PT"+str; //TODO [PT는 picture 의미]
}
}
[소스코드 : static >> imageUpload.html]
<!DOCTYPE HTML>
<!-- 자바스크립트 차단된 콘텐츠 자동 허용 실시 -->
<!-- saved from url=(0013)about:internet -->
<!-- 표시 언어 지정 -->
<html lang="ko">
<!-- 헤더 정의 부분 -->
<head>
<title>HTML TEST</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- 내부 CSS 스타일 지정 -->
<style>
/* html, body 영역 스타일 지정 */
html, body{
width : 100%;
height : 100%;
margin : 0;
padding : 0;
border : none;
/* 스크롤바 표시 지정 */
overflow : auto;
}
/* body 스크롤바 메인 스타일 지정 */
body::-webkit-scrollbar {
/* 스크롤바 너비 지정 */
width: 10px;
/* 스크롤바 배경 색상 지정 */
background-color: #c1c1c1;
}
/* body 스크롤바 thumb 스타일 지정 */
body::-webkit-scrollbar-thumb {
/* 스크롤바 thumb 색상 지정 */
background-color: #444444;
}
/* 이미지 레이아웃 스타일 지정 */
#image-container {
width : 40%;
height : 50%;
margin : 0 auto;
padding : 0;
border : 2px solid #000000;
background-color : #ffffff;
border-radius : 20px;
position: relative;
top: 5%;
left: 0%;
}
#preview-image {
width : 100%;
height : 100%;
margin : 0 auto;
padding : 0;
border-radius : 20px;
position: relative;
top: 0%;
left: 0%;
}
/* input 레이아웃 스타일 지정 */
#input-container {
width : 40%;
height : 10%;
margin : 0 auto;
padding : 0;
border : none;
background-color : #ff00ff;
border-radius : 20px;
position: relative;
top: 10%;
left: 0%;
}
#input-file-button {
width : 100%;
height : 100%;
margin : 0 auto;
padding : 0;
border-radius : 20px;
background-color: #FF6600;
cursor: pointer;
position: relative;
top: 0%;
left: 0%;
display: table;
}
#input-txt {
color: #ffffff;
text-align: center;
font-size: 150%;
font-weight: bold;
display: table-cell;
vertical-align: middle;
}
/* delete 레이아웃 스타일 지정 */
#delete-container {
width : 40%;
height : 10%;
margin : 0 auto;
padding : 0;
border : none;
background-color : #999999;
border-radius : 20px;
position: relative;
top: 13%;
left: 0%;
cursor: pointer;
display: table;
}
#delete-txt {
color: #ffffff;
text-align: center;
font-size: 150%;
font-weight: bold;
display: table-cell;
vertical-align: middle;
}
/* 서버 로컬 저장 레이아웃 스타일 지정 */
#server-container {
width : 40%;
height : 10%;
margin : 0 auto;
padding : 0;
border : none;
background-color : #000000;
border-radius : 20px;
position: relative;
top: 16%;
left: 0%;
cursor: pointer;
display: table;
}
#server-txt {
color: #ffffff;
text-align: center;
font-size: 150%;
font-weight: bold;
display: table-cell;
vertical-align: middle;
}
</style>
<!-- Jquery CDN 로드 : 항상 최신 버전 사용 -->
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<!-- 내부 JS 지정 -->
<script>
/*
[JS 요약 설명]
1. window.onload : 웹페이지 로드 완료 상태를 나타냅니다
2. document.getElementById : 특정 객체 id 를 설정합니다
3. addEventListener : 특정 객체에 이벤트를 부여합니다
4. readAsDataURL : 파일을 읽습니다
5. reader.onload : 파일을 정상적으로 읽은 경우를 나타냅니다
*/
/* [html 최초 로드 및 이벤트 상시 대기 실시] */
window.onload = function() {
console.log("");
console.log("[window onload] : [start]");
console.log("");
// [input 에 이벤트 부여 실시]
const inputImage = document.getElementById("input-image");
inputImage.addEventListener("change", readImage, false);
};
/* [이미지 불러오기 이벤트 수행 함수] */
function readImage(evt){
console.log("");
console.log("[readImage] : [start]");
console.log("");
// 인풋 태그에 파일이 있는 경우
if(evt.target.files && evt.target.files[0]) {
console.log("");
console.log("[readImage] : [reader]");
console.log("");
// FileReader 인스턴스 생성
const reader = new FileReader();
// 이미지가 로드가 된 경우
reader.onload = function (e) {
const previewImage = document.getElementById("preview-image");
previewImage.src = e.target.result;
console.log("");
console.log("[readImage] : [data] : " + previewImage.src);
console.log("");
}
// reader가 이미지 읽도록 하기
reader.readAsDataURL(evt.target.files[0]);
}
};
/* [삭제 이벤트 수행 함수] */
function deleteImage(){
console.log("");
console.log("[deleteImage] : [start]");
console.log("");
// 인풋 태그 src 값이 들어있는지 확인
const previewImage = document.getElementById("preview-image");
var data = previewImage.src;
console.log("");
console.log("[deleteImage] : [src] : " + data);
console.log("");
if(data != "undefined" && data != null && data != ""){
previewImage.src = "";
}
};
/* [서버 로컬 이미지 업로드 수행 함수] */
function serverUploadImage(){
console.log("");
console.log("[serverUploadImage] : [start]");
console.log("");
//필요 전송 데이터 정의 실시
var url = "http://localhost:7000/resourceInsertImage";
var inputIdx = "1";
// 전송 데이터 체크 실시
console.log("");
console.log("[serverUploadImage] : [request]");
console.log("[url] : " + url);
console.log("[method] : " + "post body form data");
console.log("[idx] : " + inputIdx);
console.log(document.getElementById("input-image").files[0]);
console.log("");
// input file 에 저장된 파일을 얻어옵니다
var formData = new FormData();
formData.append("idx", inputIdx); //추가 파라미터 전송
formData.append("file", document.getElementById("input-image").files[0]); //실제 파일 데이터 전송
// post body form data 형식으로 요청
$.ajax({
/* 요청 시작 부분 */
url: url, //주소
data: formData,
type: "POST", //전송 타입
async: true, //비동기 여부
enctype: "multipart/form-data",
processData: false, //프로세스 데이터 지정
contentType: false, //헤더의 Content-Type을 설정
/* 응답 확인 부분 */
success: function(response) {
console.log("");
console.log("[serverUploadImage] : [response] : " + JSON.stringify(response));
console.log("");
},
/* 에러 확인 부분 */
error: function(xhr) {
console.log("");
console.log("[serverUploadImage] : [error] : " + xhr);
console.log("");
},
/* 완료 확인 부분 */
complete:function(data,textStatus) {
console.log("");
console.log("[serverUploadImage] : [complete] : " + textStatus);
console.log("");
}
});
};
</script>
</head>
<body>
<!-- 이미지 레이아웃 -->
<div id="image-container">
<!-- src 실제로 표시될 이미지 / [초기화] onerror src 에 표시할 이미지가 없을 경우 대체 표시 -->
<img id="preview-image" src = "">
</div>
<!-- input file 레이아웃 -->
<div id="input-container" for="input-image">
<!-- input display none 처리 >> label for 사용해 input 지정 후 스타일 커스텀 -->
<label id="input-file-button" for="input-image"><p id="input-txt">이미지 불러오기</p></label>
<input id="input-image" type="file" style="display: none">
</div>
<!-- 불러온 이미지 지우기 레이아웃 -->
<div id="delete-container" onclick="deleteImage();">
<p id="delete-txt">초기화</p>
</div>
<!-- 서버 로컬 저장 레이아웃 -->
<div id="server-container" onclick="serverUploadImage();">
<p id="server-txt">서버 로컬 저장</p>
</div>
</body>
</html>
[결과 출력]
[포스트맨 사용해 멀티 파트 테스트 방법]
반응형
'Spring' 카테고리의 다른 글
Comments