파일 업로드를 위해 아래와 같이 VO에 MultipartFile 필드를 추가한다.
private MultipartFile uploadFile;
form 화면 매핑
@GetMapping("/insertGoods")
public void insertForm() {
}
파일 업로드를 위해서는 form enctype을 multipart/form-data 로 설정해야 한다.
<body>
<h2>상품 등록</h2>
<form action="insertGoods" method="post" enctype="multipart/form-data">
상품명 : <input name="name"><br>
가격 : <input name="price"><br>
수량 : <input name="qty"><br>
사진 : <input type="file" name="uploadFile"><br>
<input type="submit" value="등록">
<input type="reset" value="취소">
</form>
</body>
//업로드한 파일 (g는 vo. 파일은 vo에 자동으로 저장됨)
MultipartFile uploadFile=g.getUploadFile();
//업로드한 파일의 이름
String fname=uploadFile.getOriginalFilename();
//업로드한 파일이 저장될 경로
String path=request.getServletContext().getRealPath("images");
주의: 파일을 첨부하지 않았어도 uploadFile이 null이 아님.
//파일 쓰기
try {
byte[] data=uploadFile.getBytes();
FileOutputStream fos=new FileOutputStream(path+"/"+fname);
fos.write(data);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
//vo에 fname을 set
g.setFname(fname);
int re=dao.insert(g);
//업로드 실패 시
if(re<=0) {
mav.addObject("msg", "등록 실패");
mav.setViewName("error");
}
get 방식에서 수정할 글의 vo를 view로 보내줌
@RequestMapping(method=RequestMethod.GET)
public void form(int no, Model model) {
model.addAttribute("b",dao.findByNo(no));
}
<form action="updateBoard" method="post" enctype="multipart/form-data">
<input type="hidden" name="no" value=${b.no }>
글제목 : <input name="title" value="${b.title }"><br>
글암호 : <input type="password" name="pwd"><br>
글내용 : <br>
<textarea rows="10" cols="80" name="content">${b.content }</textarea><br>
<!-- 수정 전 첨부파일 이름을 hidden으로 보내주기 -->
<input type="hidden" name="fname" value="${b.fname }">
첨부파일 : ${b.fname }
<input type="file" name="uploadFile"><br>
<input type="submit" value="수정">
<input type="reset" value="취소">
</form>
String path=request.getServletContext().getRealPath("data");
String oldFname=b.getFname(); //글 수정 전 파일 이름
String fname=""; //글 수정 후 파일 이름
MultipartFile uploadFile=b.getUploadFile();
fname=uploadFile.getOriginalFilename();
if(fname!=null && !fname.equals("")) {
b.setFname(fname);
}
⇒ b의 fname을 새로운 파일 이름으로 set
int re=dao.update(b);
if(re<=0) {
mav.addObject("msg","게시물 수정에 실패했습니다.");
mav.setViewName("error");
}else {
//insert 성공 & 새 첨부파일이 있을 경우-> 파일을 폴더에 쓰기
if(fname!=null && !fname.equals("")) {
byte[] data;
try {
data = uploadFile.getBytes();
FileOutputStream fos=new FileOutputStream(path+"/"+fname);
fos.write(data);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
//insert 성공 & 새 첨부파일이 있을 경우 & 예전 첨부파일도 있을 경우 -> 예전 파일 지우기
if(oldFname!=null && !oldFname.equals("")) {
File file=new File(path+"/"+oldFname);
file.delete();
}
}
}
update 전체 코드
package com.example.demo.controller;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import com.example.demo.dao.BoardDAO;
import com.example.demo.vo.BoardVO;
import jakarta.servlet.http.HttpServletRequest;
@Controller
@RequestMapping("/updateBoard")
public class UpdateBoardController {
@Autowired
private BoardDAO dao;
public void setDao(BoardDAO dao) {
this.dao = dao;
}
@RequestMapping(method=RequestMethod.GET)
public void form(int no, Model model) {
model.addAttribute("b",dao.findByNo(no));
}
@RequestMapping(method=RequestMethod.POST)
public ModelAndView submit(BoardVO b, HttpServletRequest request) {
ModelAndView mav=new ModelAndView("redirect:/listBoard");
String path=request.getServletContext().getRealPath("data");
String oldFname=b.getFname();
String fname="";
MultipartFile uploadFile=b.getUploadFile();
fname=uploadFile.getOriginalFilename();
if(fname!=null && !fname.equals("")) {
b.setFname(fname);
}
int re=dao.update(b);
if(re<=0) {
mav.addObject("msg","게시물 수정에 실패했습니다.");
mav.setViewName("error");
}else {
if(fname!=null && !fname.equals("")) {
byte[] data;
try {
data = uploadFile.getBytes();
FileOutputStream fos=new FileOutputStream(path+"/"+fname);
fos.write(data);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
if(oldFname!=null && !oldFname.equals("")) {
File file=new File(path+"/"+oldFname);
file.delete();
}
}
}
return mav;
}
}
삭제하기 전 묻기
$("#delete").click(function(){
if(confirm("정말로 삭제하시겠습니까?")){
var no=$("#no").text();
location.href="deleteGoods?no="+no;
}
})
@RequestMapping("/deleteGoods")
public ModelAndView delete(int no, HttpServletRequest request ) {
ModelAndView mav=new ModelAndView("redirect:/listGoods");
String fname=dao.findByNo(no).getFname();
String path=request.getServletContext().getRealPath("images");
int re=dao.delete(no);
//삭제 성공하면 파일도 지우기
if(re>0) {
File file=new File(path+"/"+fname);
file.delete();
}else{
mav.addObject("msg","상품 삭제 실패");
mav.setViewName("error");
}
return mav;
}