초급의 끄적거림

[Spring] 파일 다운로드/업로드 게시판 (등록, 목록, 상세보기) 본문

Framework/Spring

[Spring] 파일 다운로드/업로드 게시판 (등록, 목록, 상세보기)

codingD 2019. 10. 18. 16:17

0. 준비


- webapp/media/stoarage 폴더 생성 : 사용자가 전송시킨 파일 저장소

- webapp/media/temp 폴더 생성 : 임시로 사용할 폴더

- net.utility 패키지 생성, Utility.java의 String root = "/mymelon"; 확인

 → MediaCont.java의 root를 생성할 때 사용

 

 

1. 파일 다운로드 / 업로드 '등록하기'


MediaCont.java

전송된 파일처리
- 실제 파일은 /media/storage 폴더에 저장
- 저장된 파일관련 정보는 media 테이블에 저장
package kr.co.mymelon.media;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
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 net.utility.UploadSaveManager;
import net.utility.Utility;

@Controller
public class MediaCont {
	
	private static final ServletRequest req = null;
	//DAO객체 생성
	private MediaDAO dao=new MediaDAO();
	
	public MediaCont() {
		System.out.println("-----MediaCont() 객체 생성 됨");
	}//MediaCont end
//------------------- 파일 등록 --------------------------------------------------------------------------------	
	//결과 확인 http://localhost:8090/mymelon/media/create.do
	// get 방식
	@RequestMapping(value = "/media/create.do", method = RequestMethod.GET)
	public String createForm() {
		return "media/createForm";
	}//createForm() end
	
	//post 방식
	@RequestMapping(value = "/media/create.do", method = RequestMethod.POST)
	public ModelAndView createForm(MediaDTO dto, HttpServletRequest req) {
		//1) pom.xml → 파일 업로드 / 다운로드 관련 의존성 추가
		//2) MediaDTO → postMF, filenameMF 필드 추가 후 getter, setter 함수 생성
		//3) servlet-context.xml에 스프링빈 등록
		ModelAndView mav=new ModelAndView();
		mav.setViewName("media/msgView");  //화면에 보일 view 단 (.jsp)
		mav.addObject("root", Utility.getRoot());  //utility 안에 있는 root : mymelon
//-------------------------------------------------------------------------------------------------------			
//	전송된 파일 처리
//  → 실제 파일은 /media/storage 폴더에 저장
//  → 저장된 파일 관련 정보는 media테이블에 저장
		String basePath=req.getRealPath("/media/storage");  //realpath 사용하지 말라고 하지만 그냥 진행
		
		//1) createForm.jsp의 <input type='file' name='posterMF' size='50'>
		//dto로 받아오기 위해서 getter, setter추가
		MultipartFile posterMF = dto.getPosterMF();
		
		//파일 저장하고 리네임된 파일명 반환 (똑같은 파일명을 가진 파일이 있 수도 있기 때문에 똑같은 파일명이 있을 경우 리네임 시켜줘야함)
		//posterMF 라는 파일 값을 경로에서 찾아보고 있으면 리네임
		//net.utility.Utility.UploadSaveManger.saveFileSpring30은 static 함수라서 이렇게 빨리 쓸 수 있음, 리턴값이 String 이라서 String poster.
		String poster=UploadSaveManager.saveFileSpring30(posterMF, basePath); //(파일명, 경로)
		
		//리네임된 파일명을 dto 객체에 담기
		dto.setPoster(poster);
		
		//2) createForm.jsp의 <input type='file' name='filenameMF' size='50'>
		//파일이름 뿐만 아니라 파일 사이즈도 가져와야 하기 때무넹 filenameMF의 size()도 챙기기
		MultipartFile filenameMF=dto.getFilenameMF();
		String filename=UploadSaveManager.saveFileSpring30(filenameMF, basePath);
		dto.setFilename(filename);
		dto.setFilesize(filenameMF.getSize());
//-------------------------------------------------------------------------------------------------------
		int cnt=dao.create(dto);
		if(cnt==0) {
			mav.addObject("msg1", "<p>음원등록 실패T.T</p>");
			mav.addObject("img", "<img src='../images/fail.png'>");
			mav.addObject("link1", "<input type='button' value='목록으로' onclick='location.href=\"list.do\"'>");
			mav.addObject("link2", "<input type='button' value='다시시도' onclick='javascript:history.back()'>");
		}else {
			mav.addObject("msg1", "<p>음원등록 성공!</p>");
			mav.addObject("img", "<img src='../images/sound.png'>");
			mav.addObject("link1", "<input type='button' value='목록으로' onclick='location.href=\"list.do\"'>");
		
		}//if end
		return mav;
	}//createForm() end

}//class end

 

+ 확인) UploadSaveManager.java - saveFileSpring30 메소드

 

 

MediaDAO.java

 - create

public int create(MediaDTO dto) {
	int cnt=0;
	try {
		Connection con=DBOpen.getConnection();
		StringBuilder sql=new StringBuilder();
		
		sql.append(" INSERT INTO media (mediano, title, rdate, poster, filename, filesize) ");
		sql.append(" VALUES ((SELECT NVL(MAX(mediano),0)+1 as mediano FROM media), ?, sysdate, ?, ?, ?) ");
		
		PreparedStatement pstmt=con.prepareStatement(sql.toString());
		pstmt.setString(1, dto.getTitle());
		pstmt.setString(2, dto.getPoster());
		pstmt.setString(3, dto.getFilename());
		pstmt.setLong(4, dto.getFilesize());
		cnt=pstmt.executeUpdate();
		
	}catch(Exception e) {
		System.out.println("행 추가 실패 : "+e);
	}//try end
	return cnt;
}//create() end

 

msgView.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>msgView.jsp</title>
<style type="text/css">
* {
	font-family: gulim;
	font-size: 20px;
 }
</style>
<link href="../css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
	<div class="title">알림</div>
	<div class="content">
		<dl>
			<dd>${msg1 !=null ? img : "" } ${msg1 }</dd>
			<dd>${msg2 !=null ? img : "" } ${msg2 }</dd>
			<dd>${msg3 !=null ? img : "" } ${msg3 }</dd>
		</dl>
		<p>
			${link1 } ${link2 } ${link3 }
		</p>
	</div>
</body>
</html>

 

- 결과 확인  http://localhost:8090/mymelon/media/create.do

'등록' 버튼을 누르면 콘솔창에 전송하고자 한 파일이 들어간 것을 확인할 수 있음

 

2. 파일 다운로드/업로드 게시판의 목록보기

MediaCont.java 

@RequestMapping("/media/list.do")
	public ModelAndView list() {
		ModelAndView mav=new ModelAndView();
		mav.setViewName("media/list");
		mav.addObject("list", dao.list());
		mav.addObject("root", Utility.getRoot());
		return mav;
}//list() end

 

MediaDAO.java

 - list

public ArrayList<MediaDTO> list(){
	ArrayList<MediaDTO> list=null;
	try {
		Connection con=DBOpen.getConnection();
		StringBuilder sql=new StringBuilder();
		
		sql.append(" SELECT mediano, title, rdate, poster, filename, filesize, mview ");
		sql.append(" FROM media ");
		sql.append(" WHERE mview= 'Y' ");
		sql.append(" ORDER BY mediano DESC ");
		
		PreparedStatement pstmt=con.prepareStatement(sql.toString());
		ResultSet rs=pstmt.executeQuery();
		
		if(rs.next()) {
			list=new ArrayList<MediaDTO>();
			do {
				MediaDTO dto=new MediaDTO();
				dto.setMediano(rs.getInt("mediano"));
				dto.setTitle(rs.getString("title"));
				dto.setRdate(rs.getString("rdate"));
				dto.setPoster(rs.getString("poster"));
				dto.setFilename(rs.getString("filename"));
				dto.setFilesize(rs.getLong("filesize"));
				list.add(dto);
			} while (rs.next());
		}else {
			list=null;
		}//if end
	}catch(Exception e) {
		System.out.println("목록 보기 실패 : "+e);
	}//try end
	return list;
}//list() end

 

 

list.jsp (view 단)

- mymelon/src/main/webapp/media/list.jsp

- 커스텀태그 추가 <taglib> 

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>	
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>	
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>list.jsp</title>
<style type="text/css">
* {
	font-family: gulim;
	font-size: 20px;
}
</style>
<link href="../css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="title">음원목록</div>
  <table>
	<tr>
  	  <th>번호</th>
	  <th>제목</th>
	  <th>등록일</th>
	  <th>음원파일명</th>
	  <th>수정/삭제</th>
	</tr>
	<c:forEach var="dto" items="${list}">
	<tr>
	  <td>${dto.mediano }</td>
	  <td><a href="read.do?mediano=${dto.mediano }">${dto.title }</a></td>
	  <td>${dto.rdate }</td>
	  <td>${dto.filename }<br>
	    <c:set var="filesize" value="${dto.filesize/1024 }"></c:set>  
	    <c:set var="filesize" value="${fn:substringBefore(filesize, '.')}"></c:set>
	    ${filesize } KB
	  </td>
	  <td>
		<input type="button" value="수정" onclick="location.href='update.do?mediano=${dto.mediano}'">
		<input type="button" value="삭제" onclick="location.href='delete.do?mediano=${dto.mediano}'">
	  </td>
	</tr>
	</c:forEach>
 </table>
	
<div class="bottom">
  <input type="button" value="음원등록" onclick="location.href='create.do'">
</div>
</body>
</html>
 

 

 2-1) 목록만들기

list가 가지고 있는 값을 dto 에 한 줄씩 옮겨라, list는 MediaCont.java의 '글목록'에 있음

 ★ request 안에 있는 list 이기 때문에 ${} 안에 list 써야함

 2-2) 목록에 파일사이즈 추가

 - substring : dto.filesize/1024로 나누면서 소수점이 발생하게 되고 substring을 이용하여 소숫점까지 (' . ') 자름

 - 제목에 링크를 걸어서 '상세보기'를 만들기 위해 <a> 태그를 이용하여 링크

  : mediano 로 불러 오기 위해서 ? 뒤에 mediano

 

3. 파일 다운로드/업로드 게시판의 상세보기


MediaCont.java

@RequestMapping("/media/read.do")
	public ModelAndView read(int mediano) {
		ModelAndView mav=new ModelAndView();
		MediaDTO dto=dao.read(mediano);
		if(dto!=null) {
			String filename=dto.getFilename();
			
			//음원파일명을 전부 소문자로 치환
			filename=filename.toLowerCase();
			if(filename.endsWith(".mp3")) {
				mav.setViewName("media/readMP3");
			}else if(filename.endsWith(".mp4")){
				mav.setViewName("media/readMP4");
			}//if end
		}//if end
		mav.addObject("dto", dto);
		return mav;
	}//read() end

 

MediaDAO.java

public MediaDTO read(int mediano) {
		MediaDTO dto=null;
		try {
			Connection con=DBOpen.getConnection();
			StringBuilder sql=new StringBuilder();
			
			sql.append(" SELECT mediano, title, rdate, poster, filename, filesize, mview ");
			sql.append(" FROM media ");
			sql.append(" WHERE mediano=? ");
			
			PreparedStatement pstmt=con.prepareStatement(sql.toString());
			pstmt.setInt(1, mediano);
			ResultSet rs=pstmt.executeQuery();
			if(rs.next()) {				
					dto=new MediaDTO();
					dto.setMediano(rs.getInt("mediano"));
					dto.setTitle(rs.getString("title"));
					dto.setRdate(rs.getString("rdate"));
					dto.setPoster(rs.getString("poster"));
					dto.setFilename(rs.getString("filename"));
					dto.setFilesize(rs.getLong("filesize"));
				
			}else {
				dto=null;
			}//if end
		}catch(Exception e) {
			System.out.println("상세보기 실패 : "+e);
		}//try end
		return dto;
	}//read() end

 

 3-1) View 단

readMP3.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>readMP3.jsp</title>
<style type="text/css">
	* {
		font-family: gulim;
		font-size: 20px;
	  }
</style>
<link href="../css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
	<div class="title">음악듣기</div>
	<div class="content">
	${dto.title }<br>
	<img src="storage/${dto.poster}" width="400">
	<br>
	<audio src="storage/${dto.filename }" controls autoplay></audio> <!-- autoplay : 자동재생 -->
	</div>
	
	<div class="bottom">
		<input type="button" value="음원목록" onclick="location.href='list.do'"> 
	</div>
</body>
</html>

 

음원 목록의 제목을 클릭하면 '상세보기'로 넘어가면서 mp3가 나타남

readMP4.jsp

 - readMP3.jsp 와 거의 흡사하지만 <audio> 태그를 <video>로 바꿔줘야함

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>readMP4.jsp</title>
<style type="text/css">
	* {
		font-family: gulim;
		font-size: 20px;
	  }
</style>
<link href="../css/style.css" rel="stylesheet" type="text/css">
</head>
<body>
	<div class="title">영상보기</div>
	<div class="content">
	${dto.title }<br>
	<img src="storage/${dto.poster}" width="400">
	<br>
	<video src="storage/${dto.filename }" 
		   poster="storage/${dto.poster }" 
		   width="500"
		   controls autoplay>
	</video> <!-- autoplay : 자동재생 -->
	</div>
	
	<div class="bottom">
		<input type="button" value="음원목록" onclick="location.href='list.do'"> 
	</div>
</body>
</html>

Comments