파일 저장을 위한 물리 경로 얻기
<td colspan="3" class="text-align-left text-indent"><input type="file"
name="file" /> </td>
파일을 file이라는 키값으로 서버에게 보냈다.
request.getPart('file') 메서드를 사용
· HttpServletRequest에 getParts() 메서드를 사용하여 multipart/form-data 방식으로 가져오는 모든 데이터를 가져올 수 있다.
· getPart(String partName)을 통해 필요한 내용만을 가져올 수도 있다.
스트림을 통해 전달받은 파일을 저장해야하는 경로를 절대 경로로 저장해주어야 한다.
실행 중에 동적으로 경로를 알기 위해
request.getServletContext(). getRealPath("/upload");로 사용해주면
물리 경로를 알려주게 됩니다.
package com.newlec.web.controller.admin.notice;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import com.newlec.web.entity.Notice;
import com.newlec.web.service.NoticeService;
@MultipartConfig(
fileSizeThreshold=1024*1024,
maxFileSize = 1024*1024*5,
maxRequestSize = 1024*1024*5*5)
@WebServlet("/admin/board/notice/reg")
public class RegController extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/VIEW/admin/board/notice/reg.jsp")
.forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String title = request.getParameter("title");
String content= request.getParameter("content");
String isOpen= request.getParameter("open");
boolean pub =false;
Part filePart = request.getPart("file");
String fileName = filePart.getSubmittedFileName();
InputStream fis=filePart.getInputStream();
String realPath = request.getServletContext().getRealPath("/upload");
String filePath = realPath +File.separator+fileName;
FileOutputStream fos = new FileOutputStream(filePath);
byte[] buf = new byte[1024];
int size =0;
while((size =fis.read(buf)) != -1) {
fos.write(buf,0,size);
}
if(isOpen!=null)
pub = true;
Notice notice= new Notice();
notice.setTitle(title);
notice.setContent(content);
notice.setPub(pub);
notice.setWriterId("newlec");
NoticeService service = new NoticeService();
service.insertNotice(notice);
response.sendRedirect("list");
}
}
다중 파일 업로드
여러 개와 하나의 업로드에서 차이는 별로 없습니다.
클라이언트에서 파일을 전 송하기 위한 상자가 여러 개 있으면 여러 개의 파일을 업로드할 수 있습니다.
<tr>
<th>첨부파일</th>
<td colspan="3" class="text-align-left text-indent"><input
type="file" name="file" /></td>
</tr>
<tr>
<th>첨부파일</th>
<td colspan="3" class="text-align-left text-indent"><input
type="file" name="file" /></td>
</tr>
다중 파일을 받기 위한 컨트롤러
Collection<Part> parts = request.getParts();
for (Part p : parts) {
if(!p.getName().equals("file"))continue;
Part filePart = p;
String fileName = filePart.getSubmittedFileName();
InputStream fis = filePart.getInputStream();
String realPath = request.getServletContext().getRealPath("/upload");
String filePath = realPath + File.separator + fileName;
FileOutputStream fos = new FileOutputStream(filePath);
byte[] buf = new byte[1024];
int size = 0;
while ((size = fis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
fos.close();
fis.close();
}
파일을 ,를 구분로 사용해 DB에 넣기 위해 StringBulider 설정
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String title = request.getParameter("title");
String content = request.getParameter("content");
String isOpen = request.getParameter("open");
boolean pub = false;
Collection<Part> parts = request.getParts();
StringBuilder builder = new StringBuilder();
for (Part p : parts) {
if(!p.getName().equals("file"))continue;
Part filePart = p;
String fileName = filePart.getSubmittedFileName();
builder.append(fileName);
builder.append(",");
InputStream fis = filePart.getInputStream();
String realPath = request.getServletContext().getRealPath("/upload");
String filePath = realPath + File.separator + fileName;
FileOutputStream fos = new FileOutputStream(filePath);
byte[] buf = new byte[1024];
int size = 0;
while ((size = fis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
builder.delete(builder.length()-1,builder.length());
fos.close();
fis.close();
}
if (isOpen != null)
pub = true;
Notice notice = new Notice();
notice.setTitle(title);
notice.setContent(content);
notice.setPub(pub);
notice.setWriterId("newlec");
notice.setFiles(builder.toString());
NoticeService service = new NoticeService();
int result = service.insertNotice(notice);
response.sendRedirect("list");
}
만약 파일선택을 하지 않거나 두 개 중 하나만 업로드할 경우 예기치 않은 문제가 발생합니다.
그 이유는 for문을 돌리면서 parts에서 파일이 선택되지 않은 경우도 전달되는 부분에서 발생하는 것입니다.
filePath부분에서 오류가발생합니다.
오류를 해결하기 위해 파일이 없는 경우 전달하지 않도록 합니다.
if(p.getSize() ==0) continue;
현재는 이클립스가 제공해주는 폴더를 사용하지만 실제 배포 시 실제 파일 경로가 존재하지 않는 경우 만들 수 도 있습니다.
File path = new File(realPath);
if(path.exists()) //경로가 존재하지 않는다면
path.mkdirs(); //부모의 경로 폴더까지 없다면 만들어준다.
package com.newlec.web.controller.admin.notice;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import com.newlec.web.entity.Notice;
import com.newlec.web.service.NoticeService;
@MultipartConfig(fileSizeThreshold = 1024 * 1024, maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 5 * 5)
@WebServlet("/admin/board/notice/reg")
public class RegController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/VIEW/admin/board/notice/reg.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String title = request.getParameter("title");
String content = request.getParameter("content");
String isOpen = request.getParameter("open");
boolean pub = false;
Collection<Part> parts = request.getParts();
StringBuilder builder = new StringBuilder();
for (Part p : parts) {
if(!p.getName().equals("file"))continue;
if(p.getSize() ==0) continue;
Part filePart = p;
String fileName = filePart.getSubmittedFileName();
builder.append(fileName);
builder.append(",");
InputStream fis = filePart.getInputStream();
String realPath = request.getServletContext().getRealPath("/upload");
File path = new File(realPath);
if(path.exists())
path.mkdirs();
String filePath = realPath + File.separator + fileName;
FileOutputStream fos = new FileOutputStream(filePath);
byte[] buf = new byte[1024];
int size = 0;
while ((size = fis.read(buf)) != -1) {
fos.write(buf, 0, size);
}
builder.delete(builder.length()-1,builder.length());
fos.close();
fis.close();
}
if (isOpen != null)
pub = true;
Notice notice = new Notice();
notice.setTitle(title);
notice.setContent(content);
notice.setPub(pub);
notice.setWriterId("newlec");
notice.setFiles(builder.toString());
NoticeService service = new NoticeService();
int result = service.insertNotice(notice);
response.sendRedirect("list");
}
}
'웹 프로그래밍 기초 > 자바기반의 웹&앱 응용SW 개발자' 카테고리의 다른 글
자바기반의 웹&앱 응용 SW개발자 양성과정 51일차 -80 (0) | 2020.05.11 |
---|---|
자바기반의 웹&앱 응용 SW개발자 양성과정 50일차 -79 (0) | 2020.05.05 |
자바기반의 웹&앱 응용 SW개발자 양성과정 49일차 -77 (0) | 2020.05.04 |
자바기반의 웹&앱 응용 SW개발자 양성과정 49일차 -76 (0) | 2020.05.04 |
자바기반의 웹&앱 응용 SW개발자 양성과정 49일차 -75 (0) | 2020.05.04 |
댓글