새소식

JAVA 교육/Spring

Spring 파일 업로드

  • -

스프링 파일 업로드

1. 음원등록

▲  위와 같은 형식의 폼이 있습니다. 이 폼은 '해당 파일'과 파일에 대한 포스터, 이름을 등록하는 폼의 형태입니다. 모듈 1 방식에서 파일 업로드하는 것을 배우긴 했지만, Spring 과는 많이 다르기 때문에 다시 포스팅하겠습니다.

 

먼저 음원 등록을 하기 위해서는 음원 파일이나, 포스터 이름 등의 데이터가 들어갈 테이블이 필요하겠죠? media라는 이름을 가진 테이블을 생성해보겠습니다. 

 

 

 

 -- 테이블 생성 
 CREATE TABLE media ( 
   mediano NUMBER           NOT NULL PRIMARY KEY,           -- 미디어 번호 
   title        VARCHAR2(255) NOT NULL,                              -- 제목 
   poster     VARCHAR2(255) DEFAULT 'poster.jpg' NOT NULL,   -- 포스터 이미지 
   filename  VARCHAR2(255) NOT NULL,                              -- 음원 파일명 
   filesize    NUMBER          DEFAULT 0 NOT NULL, 
   mview    CHAR(1)           DEFAULT 'Y' NOT NULL,               -- 출력모드 
   rdate      DATE               NOT NULL                                -- 등록일 
 );

 

▲  media 테이블에는 일렬 번호 mediano, 제목 title, 포스터 이미지 poster, 파일명과 파일크기 출력 모드, 등록일
이렇게 7개의 칼럼을 넣어줬습니다. poster의 default값은 poster.jpg 가 정해졌고, mview 출력 여부를 default를 'Y'로   설정했습니다. 

 

 

2. media 프로젝트 생성

Spring Legacy Project로 media 프로젝트를 생생해줍니다.
Spring 은 개발을 도와주는 편한 기능이긴 하지만, 개발 환경 구축이 어렵다는 단점이 있습니다. 하지만 환경 구축이 어렵다고 사용하지 않을 수는 없겠죠? 차근차근 환경설정을 해 보겠습니다.

 

1) 기본 환경 구축

1) pom.xml  : 개발하는데 필요한 라이브러리 다운로드 (Oracle, fileupload)
2) web.xml  :  한글 필터 등록
3) servlet-context.xml  : " <beans propertis name="prefix" value="/"> " 와 같이 prefix의 value값 변경
4) resources mapping을 없애준 후, <default-servlet-handler/> 추가

 

2). do

명령어 입력 시 home 이아닌 list.do로 이동할 수 있게 수정하겠습니다.

package kr.co.mymelon;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HomeController {
	
	
	public HomeController() {
		System.out.println("-------------HomeController() 객체생성됨");
	}
	//mymelon프로젝트 첫 페이지 호출 명령어 등록
	// http://localhost:8090/mymelon/home.do
		@RequestMapping(value="/home.do",method=RequestMethod.GET)
		public ModelAndView home() {
			ModelAndView mav=new ModelAndView();
			//reditrect->등록된 명령어를 호출한다.
			mav.setViewName("redirect:/media/list.do");
			return mav;
			}//home end
	
}

 

RequestMapping의 value 값을 " /home.do " 로 해준 다음에 ModelAndView 객체를 생성 후 mav에 list.do 명령어를 입력해 주었습니다. 

 

 

3. create.do

 

1) createForm.jsp

음원 등록을 할 수 있는 폼 형태의 jsp 페이지를 만들어주고, form의 action을./create.do로  해줍니다.

 

<form method="post"
        action="./create.do"
        enctype="multipart/form-data" > 
    <table align='center' border='1px' cellspacing='0px' cellpadding='5px'>
    <tr>
      <th>제목</th>
      <td><input type='text' name='title' size='50' value='mp3'></td>    
    </tr>
    <tr>
      <th>포스터</th>
      <td><input type='file' name='posterMF' size='50'></td>    
    </tr>
    <tr>
      <th>미디어 파일</th>
      <td><input type='file' name='filenameMF' size='50'></td>    
    </tr>    
  </table>    

  <div class='bottom'>
    <input type='submit' value='등록'>
    <input type='button' value='음원목록' onclick="location.href='list.do'">
  </div>
  
  </form>

 

2) MediaCont.java

 

package kr.co.mymelon;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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 kr.com.mymelon.media.MediaDAO;
import kr.com.mymelon.media.MediaDTO;
import net.utility.UploadSaveManager;
import net.utility.Utility;

@Controller
public class MediaCont {
		MediaDAO dao=new MediaDAO();
		
	public MediaCont() {
		System.out.println("-------------MediaCont() 객체생성됨");
	}
		//http://localhost:8090/mymelon/media/create.do
		@RequestMapping(value="/media/create.do",method=RequestMethod.GET)
		public String createForm() {
			return "media/createForm";
			}//createForm() end
		
		@RequestMapping(value="/media/create.do",method=RequestMethod.POST)
		public ModelAndView createProc(MediaDTO dto,HttpServletRequest req) {
			//1)pom.xml  => 파일업로드/다운로드 관련 의존성 추가
			//2)MediaDTO =>posterMF,filenameMF  필드추가후
			//				getter setter 함수 행성
			//3)servlet-context.xml 에 스프링빈 등록
			ModelAndView mav=new ModelAndView();
			mav.setViewName("media/msgView");

		}//create end
}//class end

 

31 line createForm 에서 create.do명령어로 요청이 들어오면  media 컨트롤러에서 받은 요청을 get 방식으로 받아 다시 createForm으로 return 합니다. 

 

36 line 이렇게 return으로 폼에 돌아와서 파일들을 선택하여 create.do 로 값을 가지고 요청을 보내면 다시 한번 media 컨트롤러에서 그 값을 받아 post 방식으로 ModelAndView 이용하여  다음 페이지로 이동하게 됩니다.

 

. do 명령어의 요청과 응답의 경로가 헷갈린다면 아래의 사진을 참고하십시오.

 

 

 

 ▲ 위의 사진은 form에서 요청이 들어와  return 해주고 다시 form에서 값 또는 데이터를 넘겨주면 3 경로를 통해 다시 한번 컨트롤러로 가게 됩니다. 이렇게 컨트롤러로 오게 되면 여기서 보내준 값을 처리하게 되는 것입니다.

 

 

4. MediaDTO

테이블에 들어가 있는 데이터를 한꺼번에 집어넣고 손쉽게 불러오기 위해서는 DTO 객체를 이용해야 합니다.

모듈 1 방식에서도 많이 사용하던 객체인데 이렇게 다시 한번 설명을 하는 이유는  파일을 업로드해줄 때에는 다른 형태의 칼럼이 들어가기 때문입니다.

 

package kr.com.mymelon.media;

import org.springframework.web.multipart.MultipartFile;

public class MediaDTO {
	  private int mediano;  
	  private String title;    
	  private String poster;   
	  private String filename; 
	  private long filesize; 
	  private String mview;    
	  private String rdate;
	  
//--------------------------------------------------
//	스프링 파일 객체 멤버변수
//	<intput type='file' name='posterMF'>	  
	  private MultipartFile posterMF;
//	<intput type='file' name='filenameMF'>	  
	  private MultipartFile filenameMF;
//--------------------------------------------------

 

 ▲ 위의 코드를 보게 되면 media라는 테이블을 생성할 때의 칼럼명들이 보입니다. 여기까지는 문제가 없습니다.

 

 

하지만 우리는 form에서 posterMF라는 이미지와 filenameMF라는 미디어 파일의 값을 전달받습니다.

칼럼명에 filename이라는 칼럼이 있는데 굳이 posterMF와 filenameMF의 칼럼을 DTO 에 입력할 필요가 있을까요?

 

위에서 받는 filename 은 정말 string 형태의 이름값일 뿐입니다. 그렇기 때문에 posterMF 와 filenameMF 의 데이터를 받아 분석하여 데이터를 저장할 필요가 있습니다. 

 

17,19 line 은 스프링 파일 객체 멤버 변수라 하는데 이 스프링 파일 객체 멤버 변수를 DTO에 넣기 위해선 파일을 객체화해서 받을 환경 설정이 필요합니다.

 

이제 DTO 칼럼을 설정을 했으면 getter와 setter 함수를 만들어주어 DTO 클래스를 마무리하겠습니다.

 

 

5. servlet-context.xml

<!-- 파일전송이 있는 경우 스프링빈 등록 
	CommonsMultipartResolver
	->전송된 파일을 읽어서 MultipartFile 객체로 변환
-->
	<beans:bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	</beans:bean>

 

▲ 위의 CommonsMultipartResolver라는 스프링 빈을 등록해 주면 위의 스프링 파일 객체 멤버 변수를 설정해 줄 수 있습니다.

 

 

6. MediaCont

@RequestMapping(value="/media/create.do",method=RequestMethod.POST)
		public ModelAndView createProc(MediaDTO dto,HttpServletRequest req) {
			//1)pom.xml  => 파일업로드/다운로드 관련 의존성 추가1
			//2)MediaDTO =>posterMF,filenameMF  필드추가후
			//				getter setter 함수 행성
			//3)servlet-context.xml 에 스프링빈 등록
			ModelAndView mav=new ModelAndView();
			mav.setViewName("media/msgView");
			mav.addObject("root", Utility.getRoot());// /mymelon
//----------------------------------------------------------			
//			전송된 파일 처리
//			-> 실제 파일은 / media/stroage 폴더에 저장
//			-> 저장된 파일관련 정보는 media테이블에 저장
//			//파일이 저장될 실제 물리적인 경로
			String basePath=req.getRealPath("/media/storage");
			
			//1)<input type='file' name='posterMF'>
			//파일 가져오기
			MultipartFile posterMF=dto.getPosterMF();
			//파일 저장하고 리네임된 파일명 반환
			//static 함수이기 때문에 사용
			String poster=UploadSaveManager.saveFileSpring30(posterMF, basePath);
			//리네임된 파일명 dto객체에 담기
			dto.setPoster(poster);
			
			//2)<input type='file' name='filenameMF'>
			
			MultipartFile filenameMF=dto.getFilenameMF();
			//파일 저장하고 리네임된 파일명 반환
			//static 함수이기 때문에 사용
			String filename=UploadSaveManager.saveFileSpring30(filenameMF, basePath);
			//리네임된 파일명 dto객체에 담기
			dto.setFilename(filename);
			dto.setFilesize(filenameMF.getSize());
//----------------------------------------------------------
			int cnt=dao.create(dto);
			if(cnt==0) {
				mav.addObject("msg1",   "<p>음원등록 실패!!! 실패!!! 실패했다고</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("link3", "<input type='button' value='목록으로' onclick='location.href=\"list.do\"'>");
			}
			return mav;
		}//create end

 

9 line : mav.addObject("root", Utility.getRoot()); 현제 만들어진 프로젝트에서 Utility를 사용하기위해 mav에 root를 지정해 줍니다. 이제 Utility의 함수들을 가져와 사용할 수 있게 되었습니다.

 

15 line : 실제 파일이 저장되는 폴더를 req.getRealPath(""); 를 통해 " basePath" 에 저장하였습니다. 

 

<input type='file' name='posterMF'>

17~24 line :  Multipartfile 객체로 폼에서 보낸 데이터 posterFM 파일을 가져와 변수에다가 담았습니다.
저장된 파일을 다시 한번 더 가져와서 poster이라는 변수에 파일명을 담아 DTO객체에 담아주었습니다.

 

<input type='file' name='filenameMF'>

26~34 line : posterMF 객체로 폼에서 보낸 데이터 filenameFM파일을 가져와 변수에다가 담았습니다.
저장된 파일을 다시 한번 더 가져와서 filename이라는 변수에 파일명을 담아 DTO객체에 담아주었습니다.

 

36~46 line : 성공했을때와 실패했을때의 메시지, 이미지 링크등을 mav 참조변수에 담아 return 해주겠습니다.

 

 

7. msgView

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>media/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>

 

▶ 폼에서 데이터를 보내고 백엔드단에서 처리과정을 거쳐 msgView 페이지로 이동을 합니다.
데이터 처리 과정에서 msg에 와 img에 넣어두었던 String 값을 화면에 출력해 주겠습니다.

 

결과

 

 

============================================================================

 

업로드한 포스터와 미디어 파일들의 리스트 목록과 수정 삭제 페이지들은 따로 포스팅을 하고 
지금은 upload 와  download 만 설명을 하겠습니다.

 

============================================================================ 

'JAVA 교육 > Spring' 카테고리의 다른 글

Spring 프로젝트생성 및 환경구축 (사칙연산 test)  (0) 2019.11.20
Framework (myBatis)  (0) 2019.11.20
2019/10/17 mymelon  (0) 2019.10.17
2019/10/17 AJax 사용법 2 (JSON, Cookie)  (0) 2019.10.17
2019/10/16 Ajax 사용법  (0) 2019.10.16
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.