본문 바로가기
웹 프로그래밍 기초/자바기반의 웹&앱 응용SW 개발자

자바기반의 웹&앱 응용 SW개발자 양성과정 49일차 -78

by oncerun 2020. 5. 5.
반응형

파일 저장을 위한 물리 경로 얻기

 

<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");
	}

}
반응형

댓글