반응형
파일업로드 Ajax 방식 요청 처리
- 이미지 변경 시 데이터 확인
ajaxHome.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script type="text/javascript" src="/resources/js/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
//파일업로드 Ajax 방식 요청 처리
$("#inputFile").on("change", function(event){
console.log("change!!");
//event.target : <input type="file"...
let files = event.target.files;
let file = files[0];
console.log("file : ", file);
});
});
</script>
<h2>ajaxHome.jsp</h2>
<form>
<p><input type="text" id="boardNo" name="boardNo"></p>
<p><input type="text" id="title" name="title"></p>
<p>
<textarea rows="3" cols="30" id="content"
name="content"></textarea>
</p>
<p><input type="text" id="writer" name="writer"></p>
<p><input type="text" id="userId" name="userId"></p>
<p><input type="password" id="password" name="password"></p>
<p><input type="file" name="inputFile" id="inputFile"></p>
</form>
- ajax 이용하여 파일 정보 보내기
ajaxHome.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script type="text/javascript" src="/resources/js/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
//파일업로드 Ajax 방식 요청 처리
$("#inputFile").on("change", function(event){
console.log("change!!");
//event.target : <input type="file"...
let files = event.target.files;
let file = files[0];
console.log("file : ", file);
//formData : <form></form>
let formData = new FormData();
/* append : 부모의 마지막 자식요소를 추가
<form>
<input type="file" name="file" />
</form>
*/
formData.append("file",file);
//아작나써유..피씨다타써
$.ajax({
url:"/uploadAjax",
processData:false,
contentType:false,
data:formData,
type:"post", //파일 업로드시에는 반드시 post 방식이어야함
dataType:"text",
success:function(data) {
console.log("data : " + data);
alert(data);
}
});
});
});
});
</script>
<h2>ajaxHome.jsp</h2>
<form>
<p><input type="text" id="boardNo" name="boardNo"></p>
<p><input type="text" id="title" name="title"></p>
<p>
<textarea rows="3" cols="30" id="content"
name="content"></textarea>
</p>
<p><input type="text" id="writer" name="writer"></p>
<p><input type="text" id="userId" name="userId"></p>
<p><input type="password" id="password" name="password"></p>
<p><input type="file" name="inputFile" id="inputFile"></p>
</form>
MemberController.java
package kr.or.ddit.controller;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import kr.or.ddit.service.MemberService;
import kr.or.ddit.vo.Address;
import kr.or.ddit.vo.Card;
import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class MemberController {
/*
<form>
<input type="file" name="file" />
</form>
*/
@ResponseBody
@PostMapping("/uploadAjax")
public String uploadAjax(MultipartFile file) { // name="file"와 이름이 같아야함
String fileName = file.getOriginalFilename();
log.info("fileName : " + fileName);
return fileName;
}
}
- append로 다른 값도 같이 보내기
ajaxHome.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script type="text/javascript" src="/resources/js/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
//파일업로드 Ajax 방식 요청 처리
$("#inputFile").on("change", function(event){
console.log("change!!");
//event.target : <input type="file"...
let files = event.target.files;
let file = files[0];
console.log("file : ", file);
let userId = $("#userId").val();
let password = $("#password").val();
//event.target : <input type="file"...
let files = event.target.files;
let file = files[0];
console.log("file : ", file);
//formData : <form></form>
let formData = new FormData();
/* append : 부모의 마지막 자식요소를 추가
<form>
<input type="text" name="userId" value="honggd" />
<input type="text" name="password" value="1234" />
<input type="file" name="file" />
</form>
*/
formData.append("userId",userId);
formData.append("password",password);
formData.append("file",file);
//아작나써유..피씨다타써
$.ajax({
url:"/uploadAjax",
processData:false,
contentType:false,
data:formData,
type:"post", //파일 업로드시에는 반드시 post 방식이어야함
dataType:"json",
success:function(data) {
console.log("data : ", data);
alert(data);
}
});
});
});
});
</script>
<h2>ajaxHome.jsp</h2>
<form>
<p><input type="text" id="boardNo" name="boardNo"></p>
<p><input type="text" id="title" name="title"></p>
<p>
<textarea rows="3" cols="30" id="content"
name="content"></textarea>
</p>
<p><input type="text" id="writer" name="writer"></p>
<p><input type="text" id="userId" name="userId"></p>
<p><input type="password" id="password" name="password"></p>
<p><input type="file" name="inputFile" id="inputFile"></p>
</form>
MemberController.java
package kr.or.ddit.controller;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import kr.or.ddit.service.MemberService;
import kr.or.ddit.vo.Address;
import kr.or.ddit.vo.Card;
import kr.or.ddit.vo.Member;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class MemberController {
/*
<form>
<input type="text" name="userId" value="honggd" />
<input type="text" name="password" value="1234" />
<input type="file" name="file" />
</form>
*/
@ResponseBody
@PostMapping("/uploadAjax")
public Map<String,Object> uploadAjax(String userId, String password,
MultipartFile file) { // name="file"와 이름이 같아야함
String fileName = file.getOriginalFilename();
log.info("userId : " + userId);
log.info("password : " + password);
log.info("fileName : " + fileName);
Map<String,Object> map = new HashMap<String,Object>();
map.put("userId", userId);
map.put("password", password);
map.put("fileName", fileName);
//ResponseBody -> map 객체 -> json string으로 serialize됨
return map;
}
}
비동기로 파일업로드 처리
- 자바빈즈 매개변수 x
create.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/resources/js/jquery.min.js"></script>
<title>Insert title here</title>
<script type="text/javascript">
//e : onchange 이벤트
function handleImg(e){
// <p id="pImg"></p> 영역에 이미지 미리보기를 해보자
let files = e.target.files;
//이미지가 여러개가 있을 수 있으므로 이미지들을 각각 분리해서 배열로 만듦
let fileArr = Array.prototype.slice.call(files);
fileArr.forEach(function(f){
//이미지 파일이 아닌 경우 이미지 미리보기 실패 처리(MIME타입)
if(!f.type.match("image.*")){
alert("이미지 확장자만 가능합니다.");
return;
}
//이미지 객체를 읽을 자바스크립트의 reader 객체 생성
let reader = new FileReader();
$("#pImg").html("");
//e : reader가 이미지 객체를 읽는 이벤트
reader.onload = function(e) {
//e.target : f(이미지 객체)
//e.target.result : reader가 이미지를 다 읽은 결과
let img_html = "<img src=" + e.target.result + " style='width:30%;' />";
//객체.append : 누적, .html : 새로고침, .innerHTML : J/S
$("#pImg").append(img_html);
}
//f : 이미지 파일 객체를 읽은 후 다음 이미지 파일(f)을 위해 초기화 함
reader.readAsDataURL(f);
});
}
$(function(){
//이미지 미리 보기 시작////////
$("#uploadFile").on("change",handleImg);
//이미지 미리 보기 끝////////
$("#btnSave").on("click", function(){
let data = $("#frm").serialize();
let dataArray = $("#frm").serializeArray();
console.log("data : ", data);
console.log("dataArray : ", dataArray);
let param = {};
dataArray.map(function(data, index){
param[data.name] = data.value;
});
console.log("param : ", param)
//------------------------------------
let title = $("input[name='title']").val();
let category = $("input[name='category']").val();
let price = $("input[name='price']").val();
//<form></form>
let formData = new FormData();
formData.append("title",title);
formData.append("category",category);
formData.append("price",price);
/*
<form>
<input type="text" name="title" value="개똥이데이" />
<input type="text" name="category" value="영화" />
<input type="text" name="price" value="12000" />
<input type="file" name="prices" />
<input type="file" name="prices" />
<input type="file" name="prices" />
</form>
*/
let inputFile = $("#uploadFile");
let files = inputFile[0].files;
console.log("files.length : " + files.length);
for(let i=0; i<files.length; i++) {
formData.append("pictures",files[i]); //vo에 있는 이름과 맞춰야함
}
$.ajax({
url:"/createFormData",
processData:false,
contentType:false,
data:formData,
type:"post",
dataType:"text",
success:function(result){
console.log("result : ", result);
}
});
});
});
</script>
</head>
<body>
<h1>책 등록</h1>
<h5>${title}</h5>
<!--
요청URI : /crate
요청파라미터 : {title=개똥이의 모험, category=소설, price=12000}
요청방식 : post
-->
<form id="frm" action="/create" method="post" enctype="multipart/form-data">
<p>제목 : <input type="text" name="title" required placeholder="제목"></p>
<p>카테고리 : <input type="text" name="category" required placeholder="카테고리"></p>
<p>가격 : <input type="number" name="price" required placeholder="가격"></p>
<p id="pImg"></p>
<p>도서이미지 :
<input type="file" id="uploadFile" name="pictures" multiple></p>
<p>
<input type="button" id="btnSave" value="저장">
</p>
</form>
</body>
</html>
BookController.java
package kr.or.ddit.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import kr.or.ddit.service.BookService;
import kr.or.ddit.vo.BookVO;
import lombok.extern.slf4j.Slf4j;
/*
Controller 어노테이션
스프링 프레임워크에게 "이 클래스는 웹 브라우저의 요청(request)를
받아들이는 컨트롤러야" 라고 알려주는 것임.
스프링은 servlet-context.xml의 context:component-scan의 설정에 의해
이 클래스를 자바빈 객체로 등록(메모리에 바인딩).
*/
// Slf4j 사용 시 하단의 로깅 사용 가능
@Slf4j
@Controller
public class BookController {
//서비스를 호출하기 위해 의존성 주입(Dependency Injection-DI)
//IoC(Inversion of Control) - 제어의 역전.(개발자가 객체생성하지 않고 스프링이 객체를 미리 생성해놓은 것을 개발자가 요청)
// DI - 의존성 주입(Dependency Injection) : 이미 만들어져 있는 BookServiceImpl.java를 @Service로 가져다씀
@Autowired
BookService bookService;
//bookVO 객체가 JSON string으로 serialize되어 리턴됨
@ResponseBody
@PostMapping("/createFormData")
public int createFormData(BookVO bookVO) {
/*
BookVO(bookId=0, title=개똥이의 모험, category=소설
, price=12000, insertDate=null)
*/
log.info("bookVO : " + bookVO);
// 도서 등록
int result = this.bookService.createPost(bookVO); // 이곳을 거치면서 bookId값이 채워짐
log.info("createPost->result : " + result);
/*
BookVO(bookId=0, title=개똥이의 모험, category=소설
, price=12000, insertDate=null)
*/
//bookVO에 MultipartFile 타입이 있어서 serialize되지 못함
return bookVO.getBookId();
}
}
- 자바빈즈 매개변수 o
create.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/resources/js/jquery.min.js"></script>
<title>Insert title here</title>
<script type="text/javascript">
$(function(){
$("#btnPlus").on("click",function(){
let pAreaLen = $(".pArea").length;
let str = "";
str += "<p class='pArea'>";
str += "<input type='text' name='licenseVOList["+pAreaLen+"].licNo' id='licNo"+pAreaLen+"' class='form-control col-sm-3 float-left' placeholder='자격증 번호'>";
str += "<input type='text' name='licenseVOList["+pAreaLen+"].licNm' id='licNm"+pAreaLen+"' class='form-control col-sm-3 float-left' placeholder='자격증 명'>";
str += "<input type='date' name='licenseVOList["+pAreaLen+"].licDt' id='licDt"+pAreaLen+"' class='form-control col-sm-3 float-left' placeholder='발급 일'>";
str += "</p>";
str += "<p style='clear:both;'></p>";
$("#btnSubmit").parent().before(str);
});
$("#btnMinus").on("click",function(){
let pAreaLen = $(".pArea").length;
console.log("pAreaLen : ", pAreaLen);
if(pAreaLen < 2) {
alert("최소 하나는 존재해야 합니다.");
return;
}
// next는 선택한 요소의 다음 형제 요소를 반환
$(".pArea").last().next().remove();
$(".pArea").last().remove();
});
$("#btnSubmit").on("click",function(){
let empNo = $("input[name='empNo']").val();
let empName = $("input[name='empName']").val();
let empAddress = $("input[name='empAddress']").val();
let empTelno = $("input[name='empTelno']").val();
let empSalary = $("input[name='empSalary']").val();
let filename = $("input[name='filename']").val();
let formData = new FormData();
formData.append("empNo",empNo);
formData.append("empName",empName);
formData.append("empAddress",empAddress);
formData.append("empTelno",empTelno);
formData.append("empSalary",empSalary);
formData.append("filename",filename);
let inputFile = $("#uploadFile");
let files = inputFile[0].files;
formData.append("uploadFile", files[0]);
$(".pArea").each(function(idx,data){
let licNo = $(this).children().eq(0).val();
let licNm = $(this).children().eq(1).val();
let licDt = $(this).children().eq(2).val();
formData.append("licenseVOList[" + idx + "].licNo", licNo);
formData.append("licenseVOList[" + idx + "].licNm", licNm);
formData.append("licenseVOList[" + idx + "].licDt", licDt);
});
$.ajax({
url:"/employee/createFormData",
processData:false,
contentType:false,
data:formData,
type:"post",
dataType:"text",
success:function(result){
console.log("result : ", result);
}
});
});
});
</script>
</head>
<body>
<h1>직원 등록</h1>
<h5>${title}</h5>
<form action="/employee/create" method="post" enctype="multipart/form-data">
<p><input type="text" name="empNo" placeholder="직원 번호" required /></p>
<p><input type="text" name="empName" placeholder="직원 명" required /></p>
<p><input type="text" name="empAddress" placeholder="직원 주소" required /></p>
<p><input type="text" name="empTelno" placeholder="직원 연락처" required /></p>
<p><input type="number" name="empSalary" placeholder="직원 급여" required /></p>
<!-- multiple 안씀 => EMPLOYEE : 증명사진 = 1 : 1 -->
<p>
<input type="file" id="uploadFile" name="uploadFile" placeholder="증명사진" />
<label for="uploadFile" class="btn btn-info btn-sm col-sm-1">증명사진선택</label>
</p>
<p id="pImg"></p>
<hr />
<p id="pFunc">
<button type="button" class="btn btn-info btn-sm col-sm-1" id="btnPlus" >+</button>
<button type="button" class="btn btn-danger btn-sm col-sm-1" id="btnMinus" >-</button>
</p>
<p class="pArea">
<input type="text" name="licenseVOList[0].licNo" id="licNo0" class="form-control col-sm-3 float-left" placeholder="자격증 번호">
<input type="text" name="licenseVOList[0].licNm" id="licNm0" class="form-control col-sm-3 float-left" placeholder="자격증 명">
<input type="date" name="licenseVOList[0].licDt" id="licDt0" class="form-control col-sm-3 float-left" placeholder="발급 일">
</p>
<p style="clear:both;"></p>
<p><input type="button" id="btnSubmit" value="등록" /></p>
</form>
</body>
</html>
EmployeeController.java
package kr.or.ddit.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.sun.org.apache.xpath.internal.operations.Mod;
import kr.or.ddit.service.EmployeeService;
import kr.or.ddit.vo.EmployeeVO;
import lombok.extern.slf4j.Slf4j;
// 스프링 프레임워크에게 컨트롤러임을 알려줌
// 스프링이 빈(bean,객체)으로 등록하여 관리
@Controller
@RequestMapping("/employee")
@Slf4j
public class EmployeeController {
// 의존성 주입(Dependency Injection)
@Autowired
EmployeeVO myEmpVO;
@Autowired
EmployeeService employeeService;
@ResponseBody
@PostMapping("/createFormData")
public String createFormData(EmployeeVO employeeVO) {
log.info("createPost -> employeeVO : " + employeeVO);
int result = this.employeeService.createPost(employeeVO);
log.info("createPost->result : " + result);
return employeeVO.getEmpNo();
}
}
CKEditor5 파일업로드
UploadController.java
package kr.or.ddit.utils;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import kr.or.ddit.dao.AttachDao;
import kr.or.ddit.vo.AttachVO;
import lombok.extern.slf4j.Slf4j;
@Controller
@Slf4j
public class UploadController {
@Autowired
String uploadFolder;
@Autowired
String uploadFolderDirect;
//static AttachDao attachDao => null이 메모리에 올라감
@Autowired
AttachDao attachDao;
//CKEditor5 파일업로드
// /image/upload
// ckeditor는 이미지 업로드 후 이미지 표시하기 위해 uploaded 와 url을 json 형식으로 받아야 함
// modelandview를 사용하여 json 형식으로 보내기위해 모델앤뷰 생성자 매개변수로 jsonView 라고 써줌
// jsonView 라고 쓴다고 무조건 json 형식으로 가는건 아니고 @Configuration 어노테이션을 단
// WebConfig 파일에 MappingJackson2JsonView 객체를 리턴하는 jsonView 매서드를 만들어서 bean으로 등록해야 함
@ResponseBody
@PostMapping("/image/upload")
public Map<String, Object> image(MultipartHttpServletRequest request) throws IllegalStateException, IOException {
ModelAndView mav = new ModelAndView("jsonView");
// ckeditor 에서 파일을 보낼 때 upload : [파일] 형식으로 해서 넘어오기 때문에 upload라는 키의 밸류를 받아서 uploadFile에 저장함
MultipartFile uploadFile = request.getFile("upload"); // upload 이름은 고정!
log.info("uploadFile : " + uploadFile);
//파일 명
String originalFileName = uploadFile.getOriginalFilename();
log.info("originalFileName : " + originalFileName);
//originalFileName : 개똥이.jpg -> jpg
//originalFileName.indexOf(".") : 확장자 .의 위치
String ext = originalFileName.substring(originalFileName.indexOf("."));
// 서버에 저장될 때 중복된 파일 이름인 경우를 방지하기 위해 UUID에 확장자를 붙여 새로운 파일 이름을 생성
// asdfasdf.jpg
String newFileName = UUID.randomUUID() + ext;
File f = new File(uploadFolderDirect);
if(f.exists()==false) {
f.mkdirs();
}
//저장 경로로 파일 객체를 저장하겠다는라는 계획
// c:\\업로드 경로\\asdfasdf.jpg
File file = new File(uploadFolderDirect, newFileName);
//파일 복사
uploadFile.transferTo(file);
// 브라우저에서 이미지 불러올 때 절대 경로로 불러오면 보안의 위험 있어 상대경로를 쓰거나 이미지 불러오는 jsp 또는 클래스 파일을 만들어
// 가져오는 식으로 우회해야 함
// 때문에 savePath와 별개로 상대 경로인 uploadPath 만들어줌
String uploadPath = "/springProj/resources/upload/" + newFileName;
// uploaded, url 값을 modelandview를 통해 보냄
// mav.addObject("uploaded", true); // 업로드 완료
// mav.addObject("url", uploadPath); // 업로드 파일의 경로
Map<String,Object> map = new HashMap<String, Object>();
map.put("uploaded", true);
map.put("url", uploadPath);
log.info("map : " + map);
return map;
}
}
=> root-context.xml에 있는 이름, uploadFolderDirect에 적어둔 위치에 그대로 저장됨
<bean id="uploadFolderDirect" class="java.lang.String">
<constructor-arg value="C:\\eGovFrameDev-3.10.0-64bit\\workspace\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\webapps\\springProj\\resources\\upload"></constructor-arg>
</bean>
+ UploadController.java
@Autowired
String uploadFolderDirect;
해당 변수명의 이름과 root-context.xml에 있는 이름이 같아야함
반응형
'스프링 프레임워크' 카테고리의 다른 글
[스프링 프레임워크] 21장 스프링 폼 태그 라이브러리 (0) | 2024.05.10 |
---|---|
[스프링 프레임워크] 20장 모델을 통한 데이터 전달 (0) | 2024.05.09 |
[스프링 프레임워크] 18장 Ajax 방식 요청 처리 (0) | 2024.05.08 |
[스프링 프레임워크] 17장 파일 업로드 (0) | 2024.05.03 |
[스프링 프레임워크] 16장 컨트롤러 요청 처리3(폼 필드 요소 값을 매개변수로 처리) (1) | 2024.05.02 |