티스토리 뷰


오늘 수업 노트는 다중 파일 업로드이다!!!

다중 파일 업로드를 위해서 기존의 VO와 DB를 수정할 필요가 있다. 한 게시물의 여러 개의 파일이 업로드가 될 수 있도록 변경한다. 새로 만든 테이블에는 게시물을 구분할 수 있는 게시물 번호 칼럼을 추가한다.


 DB 테이블 변경 및 파일을 위한 새로운 테이블 생성

기존의 게시판 테이블에서 파일을 위한 칼럼을 제거하고, 파일 업로드를 위한 테이블을 생성하였다.

 테이블 명은 각각 bbs1, file_table 로 정의하였다.

그리고 file_table 을 위한 DTO(VO)를 하나 생성한다.

public class uploadFileVO {
	private int file_num;
	private String o_name;
	private String file_name;
	private long file_size;
	private int article_num;

	public int getFile_num() {
		return file_num;
	}

	public void setFile_num(int file_num) {
		this.file_num = file_num;
	}

	public String getO_name() {
		return o_name;
	}

	public void setO_name(String o_name) {
		this.o_name = o_name;
	}

	public String getFile_name() {
		return file_name;
	}

	public void setFile_name(String file_name) {
		this.file_name = file_name;
	}

	public long getFile_size() {
		return file_size;
	}

	public void setFile_size(long file_size) {
		this.file_size = file_size;
	}

	public int getArticle_num() {
		return article_num;
	}

	public void setArticle_num(int article_num) {
		this.article_num = article_num;
	}
}

o_name 은 original_name의 약자로 실제 파일의 이름이고, file_name은 중복 처리를 예방하여 저장한 파일 이름이다.

자바에서 글 쓰기 부분이다. view 인 writeForm 에서는 input type file 에 multiple 속성을 추가하면, 여러 개의 파일을 받을 수 있다.

여러 개의 파일을 처리하기 위해서 MultipartHttpServletRequest 를 이용하여 해결한다. 소스를 해석해본다

@Transactional @RequestMapping("/write.do") public ModelAndView write(HttpServletRequest req, @ModelAttribute("article") BoardVO article, MultipartHttpServletRequest mhsq) throws IllegalStateException, IOException { session = req.getSession(); article.setId((String) session.getAttribute("id")); bbsService.write(article); String realFolder = "d:/upload2/"; File dir = new File(realFolder); if (!dir.isDirectory()) { dir.mkdirs(); } // 넘어온 파일을 리스트로 저장 List<MultipartFile> mf = mhsq.getFiles("uploadFile"); if (mf.size() == 1 && mf.get(0).getOriginalFilename().equals("")) { } else { for (int i = 0; i < mf.size(); i++) { // 파일 중복명 처리 String genId = UUID.randomUUID().toString(); // 본래 파일명 String originalfileName = mf.get(i).getOriginalFilename(); String saveFileName = genId + "." + getExtension(originalfileName); // 저장되는 파일 이름 String savePath = realFolder + saveFileName; // 저장 될 파일 경로 long fileSize = mf.get(i).getSize(); // 파일 사이즈 mf.get(i).transferTo(new File(savePath)); // 파일 저장 bbsService.fileUpload(originalfileName, saveFileName, fileSize); } } return new ModelAndView("redirect:list.do"); }

MultipartHttpServletRequest를 사용하면 getFiles 메소드를 통해 List 형태로 받을 수 있다. 주석을 참고하여 이해 하도록 하자.

이후에는 tranferTo 메소드를 이용하여 파일을 저장하고, DB에 등록하도록 한다. 아래는 서비스 단의 소스이다. 위에서 Controll 단에서  처리하는 내용이 많은데, 가급적 서비스 단으로 옮겨서 처리하는 것을 권장한다.

	@Override
	public void fileUpload(String originalfileName, String saveFileName, long fileSize) {
		HashMap<String, Object> hm = new HashMap<>();
		hm.put("originalfileName", originalfileName);
		hm.put("saveFileName", saveFileName);
		hm.put("fileSize", fileSize);
		
		bbsOracleDao.uploadFile(hm);
	}

Mybatis를 이용하였으므로, dao 가 구현 되어있는 자바 소스가 아니라, mapper로 연결되어있고, 쿼리를 연결한다.

	<insert id="uploadFile" parameterType="HashMap">
		INSERT INTO
		"HUMAN"."FILE_TABLE" (FILE_NUM, O_NAME, FILE_NAME, FILE_SIZE,
		ARTICLE_NUM) VALUES (file_seq.nextval, #{originalfileName}, #{saveFileName}, #{fileSize}, bbs_seq.currval)
	</insert>

DB에 저장되는 것은 아래와 같다


게시물을 볼 때에는 기존의 article_num 를 이용해서 여러 게시판의 글을 읽어오는 형태를 응용하여 처리하였다.

게시물 VO에서 파일에 대한 내용을 제거하고, 파일을 위한 VO를 새로 만들었으므로, VO로 리스트를 구축하고, 리스트를 Model에 담아서 전달하면, View Page에서 출력을 해주면 된다.

읽어오는 것은 다음과 같이 진행 된다.

Controller 에서는

	@Transactional
	@RequestMapping("/content.do")
	public ModelAndView content(
			@RequestParam("article_num") String article_num,
			@RequestParam("pageNum") String pageNum) {

		mav = new ModelAndView();
		// hit 수 증가
		bbsService.hitUp(article_num);
		// 게시글 가져오기
		BoardVO article = bbsService.content(article_num);
		List<uploadFileVO> uploadFileList = bbsService.getFileList(article_num);

		mav.addObject("uploadFileList", uploadFileList);
		mav.addObject("article", article);
		mav.addObject("pageNum", pageNum);
		return mav;
	}

게시물 번호로 해당 게시물의 파일들을 uploadFileList 의 형태로 DB에서 얻어와 저장하고, model 에 심어서 보낸다. 그 다음 content.jsp 페이지 에서는

<c:forEach var="uploadFile" items="${uploadFileList}">
				<tr>
					<td class="bgcolor1">파일</td>
					<td class="bgcolor2">  <a href="/bbs2/download.do?o_name=${uploadFile.o_name}&file_name=${uploadFile.file_name}">${uploadFile.o_name}</a></td>
				</tr>
			</c:forEach>

위와 같이 JSTL을 이용해서 uploadFileList 를 받아서 반복문인 forEach를 통해 화면에 출력한다.

다운로드는 기존에 파일 다운로드와 비슷하니 응용해서 해결!!

삭제의 경우에는 다양한 처리 방법이 있으나, 가장 간단하게 article_num 로 해당 게시물의 대한 파일을 미리 리스트 형태로 저장한 다음에 파일을 제거하기 전에 DB에서 먼저 레코드를 제거해 준 다음, 정상적으로 제거 되었으면, 파일을 삭제하면 된다. 



참고하시고, 좋은 방법이나  안 좋은 코딩 습관을 지적해주시면 좋겠습니다 ^ㅡ^


'생활코딩 > Spring' 카테고리의 다른 글

스프링 배우기 - Excel 문서 처리하기  (0) 2014.04.01
스프링 배우기 - log4j  (4) 2014.03.25
스프링 배우기 - AOP 2  (2) 2014.03.19
스프링 배우기 - AOP  (0) 2014.03.18
스프링 배우기 - Connection Pool  (0) 2014.03.17
댓글