Jam's story
[Spring] 파일업로드 본문
1️⃣ form enctype="multipart/form-data" method="post" 설정
✨폼태그 코딩이 이렇게 되어있는지 확인하기
2️⃣멀티 파트 형식으로 데이터 (첨부파일) 가 전송이 되면 스프링 MVC 에서 사용할 수 있도록 변환해주는 객체 - MultipartResover 스프링 빈으로 등록
- CommonMultipartResolver - Commons FileUpload API 이용해서 데이터 처리 +++ (수업)
- StandardServletmultipartResolver - 서블릿 3.0 의 Part 이용해서 데이터 처리
3️⃣ 주의할 점
- MultipartResover 스프링 빈으로 등록할 때 반드시 이름 "multipartResolver" 라고 설정.
- DispatcherServlet 프론트 컨트롤러에서 해당이름으로 처리하도록 코딩되어져있기 때문.
- 2-2. 스프링이 기본 제공하는 MultipartResover 2가지 종류
- 서버 재시작 (restart)
- 업로드 파일 접근하는 방법 (4가지)
- MultipartFile 인터페이스 이용
- 컨트롤러 메서드
- RequestMapping()
- public String upload(MultipartFile multipartFile) { }
- File 파일객체 = new File(파일경로)
- 첨부된 파일 유무 - multipartFile.transferTo(파일객체)
- RequestParam 어노테이션을 이용
- <input type="file" name="f">
- MultipartFile 인터페이스 이용
ㄱ. MultiparFile 인터페이스 이용
컨트롤러 메서드
@RequestMapping()
public String upload( MultiparFile multiparFile ){
File 파일객체 = new File(파일경로);
첨부된 파일 유무 - multiparFile.tansferTo( 파일 객체 );
}
ㄴ. @RequestParam 어노트페이션을 이용
<input type="file" name="f">
@RequestMapping()
public String upload( @ReqeustParam("f") MultiparFile multiparFile ){
File 파일객체 = new File(파일경로);
첨부된 파일 유무 - multiparFile.tansferTo( 파일 객체 );
}
ㄷ. Multipart[HttpServerRequest]을 이용
@RequestMapping()
public String upload( Multipart[HttpServerRequest] mrequest ){
MutipartFile mfile = mrequest.getFile("f");
File 파일객체 = new File(파일경로);
첨부된 파일 유무 - mfile.tansferTo( 파일 객체 );
}
***ㄹ.커맨드 객체를 통해 업로드 파일 접근. ***
1) Notice.java
<input type="file" id="txtFile" name="file" />
ublic String noticeReg( Notice notice )
2) 필드 추가
private CommonsMultipartFile file;
3) MultipartFile 인터페이스 주요 메서드
ㄱ. String getName() 파라미터 이름
ㄴ. String getOriginalFilename() 업로드한 파일의 이름
ㄷ. boolean isEmpty() 업로드한 파일 존재 유무
ㄹ. long getSize() 업로드한 파일 크기
ㅁ. byte [] getBytes() 업로드한 파일의 바이트 데이트
ㅂ. InputStream getInputStream() 업로드한 파일의 읽기 스트림 객체 반환
ㅅ. transferTo( File ) 업로드한 파일을 저장
ㅁ. 서블릿 3.0의 Part 이용
@RequestMapping()
public String upload( @ReqeustParam("f") Part part ){
}
1️⃣dispatcher-servlet.xml
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="-1"></property>
</bean>
maxUploadSize 최대 업로드 가능한 크기. 기본값 -1
maxInMemorySize 디스크에 임시파일을 생성하기 전에 메모리에 보관할 수 있는 최대바이트 크키. 기본값 1024.
defaultEncoding 기본값 ISO-8859-1
2️⃣NoticeReg.jsp에서 확인
//form태그에
<form action="" method="post" enctype="multipart/form-data">
//파일 올리는 칸
<input type="file" id="txtFile" name="file" />
3️⃣Notice.java
2번(NoticeReg.jsp에서 name="file" 속성명 )이랑 DTO필드명이랑 같아야한다.
/* jsp에서 <input type="file" id="txtFile" name="file" /> */
private CommonsMultipartFile file;
public CommonsMultipartFile getFile() {
return file;
}
public void setFile(CommonsMultipartFile file) {
this.file = file;
}
4️⃣컨트롤러에 noticeReg(Notice notice )메소드 추가
Notice.jsp에 글쓰기 버튼을 누르면 noticeReg.htm요청을 하고,
이에 맞는 @RequestMapping(value={"noticeReg.htm"}) 컨트롤러 메소드 실행
<a class="btn-write button" href="noticeReg.htm">글쓰기</a>
//글쓰기+첨부된 파일
@RequestMapping( value = {"noticeReg.htm"}, method = RequestMethod.POST )
public String noticeReg(Notice notice ,HttpServletRequest request ) throws Exception {
//1 첨부된 파일의 유무 확인 후에 파일저장
CommonsMultipartFile multipartFile= notice.getFile();
String uploadRealPath=null;
if(!multipartFile.isEmpty()) { //첨부된 파일이 있다면
uploadRealPath =request.getServletContext().getRealPath("/customer/upload");
System.out.println("uplaodRealPath:"+uploadRealPath);
String originalFilename=multipartFile.getOriginalFilename(); //오천 "a.txt" ->"a_1.txt"
//이렇게 인덱스를 붙이는 함수 (이미 존재할 수 도 있으니까)
String filesystemName = getFileNameCheck(uploadRealPath, originalFilename);
File dest=new File(uploadRealPath,filesystemName);
multipartFile.transferTo(dest); //실질적으로 파일을 저장
//originalFilename , filesystemName Notices 테이블의 칼럼이 2개 존재
String filesrc=filesystemName; //저장하고자하는 파일
notice.setFilesrc(filesrc);
}
//2.Notices 테이블에 공지사항 INSERT
notice.setWriter("kenik");
int rowCount = this.noticeDao.insert(notice);
if (rowCount==1) {
return "redirect:notice.htm";
}else {
return "redirect:noticeReg.jsp?error";
}
} // noticeReg
//순수한 파일명+인덱스추가 만드는 메소드
private String getFileNameCheck(String uploadRealPath, String originalFilename) {
int index = 1;
while(true) {
File f = new File(uploadRealPath, originalFilename); // 파일객체
if( !f.exists()) return originalFilename;
String fileName=originalFilename.substring(0,originalFilename.length()-4);
String ext=originalFilename.substring(originalFilename.length()-4);
originalFilename = fileName+"-"+(index)+ext;
index++;
} // while 문 닫기
}
5️⃣customer 폴더 밑에 upload 폴더 추가
다운로드할때 텍스트나 이미지는 다운로드가 되지 않고, 브라우저가 열리면서 보인다.
다운로드가 되도록
1️⃣noticeDetail.jsp 수정
<a href="download.htm?p=customer/upload&f=${ notice.filesrc }">${ notice.filesrc }</a>
2️⃣컨트롤러 수정
기존 헤더에 추가려하려는 것과 같은 키값이 존재할 경우.
addHeader() : 그 키에 해당하는 값을 하나 더 추가한다.
setHeader() : 새롭게 설정한 값으로 덮어 쓴다.
// 컨트롤러 메서드 선언
// download.htm
//?
//p=customer/upload 경로
//&
//f=다운로드할 파일명
//이미지나 텍스트파일이 바로 펼쳐지지않게
@RequestMapping("download.htm")
public void download (
HttpServletResponse response
, HttpServletRequest request
, @RequestParam("p") String p
, @RequestParam("f") String f
) throws Exception{
// 이창익(서버) -> 함세강(클라이언트 즉, 브라우저)
// 아이스크림 응답 -> 먹었다.
// 표지 [ 상자 :아이스크림 ] 응답 -> X 저장 대화상자 띄운다.
// 응답 헤드 X
String fname = f;
response.setHeader("Content-Disposition","attachment;filename="+
new String(fname.getBytes(), "ISO8859_1"));
String fullPath = request.getServletContext().getRealPath( p + "/" + fname);
FileInputStream fin = new FileInputStream(fullPath);//읽어올 파일 지정
ServletOutputStream sout = response.getOutputStream(); // 응답 스트림
byte[] buf = new byte[1024];
int size = 0;
while((size = fin.read(buf, 0, 1024)) != -1) {
sout.write(buf, 0, size);
}
fin.close();
sout.close();
} // download
글 수정할때
noticeDetail.jsp
<a class="btn-edit button" href="noticeEdit.htm?seq=${notice.seq}">수정</a>
@RequestMapping(value = {"noticeEdit.htm"}, method = RequestMethod.POST)
public String noticeEdit(
Notice notice
, @RequestParam("oFilesrc") String oFilesrc // 원래 첨부파일 유무 체크
, HttpServletRequest request
) throws Exception {
String uploadRealPath = request.getServletContext().getRealPath("/customer/upload");
CommonsMultipartFile multipartFile = notice.getFile();
if (!multipartFile.isEmpty()) { // 새로 첨부파일 있다면
// 원래 첨부된 파일이 있다면 삭제.
File delOFile = new File(uploadRealPath, oFilesrc);
if (delOFile.exists()) {
delOFile.delete();
}
// ㄱ. upload 폴더 - 저장
System.out.println("> uploadRealPath: " + uploadRealPath);
String originalFilename = multipartFile.getOriginalFilename(); // a.txt
originalFilename = getFileNameCheck(uploadRealPath, originalFilename);
File dest = new File(uploadRealPath, originalFilename);
multipartFile.transferTo(dest); // 업로드 폴더에 파일 저장.
// ㄴ. notice.filesrc 업로드된 파일이름 저장: a.txt -> [a-1.txt]
notice.setFilesrc(originalFilename);
} else { // 새로 첨부파일 있다면
notice.setFilesrc(oFilesrc);
}
int rowCount = noticeDao.update(notice);
return "redirect:noticeDetail.htm?seq=" + notice.getSeq();
}
삭제
1️⃣ NoticeDetail.jsp
<a class="btn-del button" href="noticeDel.htm?seq=${notice.seq}&filesrc=${notice.filesrc}">삭제</a>
2️⃣
@RequestMapping(value= {"noticeDel.htm"})
public String noticeDel(String seq ,String filesrc, HttpServletRequest request) throws Exception{
//1 첨부파일이 있을 경우엔 첨부파일을 upload 폴더 삭제
//서버 배포 실제 경로
String uploadRealPath =request.getServletContext().getRealPath("/customer/upload");
/*
* 첨부파일을 select 알아야 왔다.
Notice notice=this.noticeDao.getNotice(seq);
String filesrc=notice.getFilesrc();
if(filesrc !=null) {
File delFile=new File( uploadRealPath, filesrc);
delFile.delete();
}
*/
// filesrc 는 파일이 없는경우 파라미터 값 x
File delFile=new File( uploadRealPath, filesrc);
if(delFile.exists() ) {delFile.delete();}
//2
int rowCount=this.noticeDao.delete(seq);
if(rowCount==1) return "redirect:notice.htm";
else return "redirect:noticeDetail.htm?seq"+seq;
}
'Spring' 카테고리의 다른 글
[Spring] NamedParameterJdbcTemplate (0) | 2022.07.18 |
---|---|
[Spring] JDBC (0) | 2022.07.17 |
[Spring] 스프링 파일 업로드 (0) | 2022.07.14 |
[Spring] MVC2 모델을 이용한 게시판 구현 (0) | 2022.07.14 |
[Spring] 다이나믹웹프로젝트생성과 MVC2패턴 (0) | 2022.07.13 |