Spring

[Spring] 파일업로드 (+방명록에 적용)

(งᐛ)ว 2023. 11. 23. 00:52
728x90

필요한 파일을 세팅하자 

방명록만들기에서 사용한 파일 중 복붙하기

pom.xml (Overview에서 Artifact Id와 프로젝트 Name만 수정)

resources의 5개 패키지(내용 수정 필요 / WebInitializer.java / Context_1_dataSource.java / Context_2_mybatis.java 세 파일은 동일하게 사용)

 

 

 

파일업로드를 위한 라이브러리 다운로드

https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload

Apache Commons FileUpload 1.3.1버전 Maven 영역 복사하여

pom.xml의 <dependencies</dependencies>  영역 사이에 붙여넣기

 

 

 

파일업로드를 위한 라이브러리 다운로드

https://mvnrepository.com/artifact/commons-io/commons-io

Apache Commons IO 2.4버전Maven 영역 복사하여

pom.xml의 <dependencies> </dependencies>  영역 사이에 붙여넣기

 

 

 

PhotoVO.java

package vo;

import org.springframework.web.multipart.MultipartFile;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class PhotoVO {

	//우리가 전송하는 데이터? 제목과 파일! 
	private String title; //우리가 설정한 제목
	private String fileName; //실제 파일 이름 
	private MultipartFile photo; //사진이든 동영상이든 일단 정보를 담아주자 
}

 

 

 

Context_4_fileUpload.java

package context;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

@Configuration
public class Context_4_fileUpload {

	@Bean
	public CommonsMultipartResolver multipartResolver() {
		CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
		multipartResolver.setDefaultEncoding("UTF-8");
		multipartResolver.setMaxUploadSize(10485760);//최대업로드용량 지정 10mb정도 
		return multipartResolver;
		
	}
}

 

이와같이 전에 없던 Context파일을 생성한다면 WebInitializer.java의 

해당 영역에 추가해줘야함

 

 

 

FileUploadController.java

package com.korea.upload;

import java.io.File;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class FileUploadController {
	
	static final String VIEW_PATH = "WEB-INF/views/";
	
	@RequestMapping(value= {"/","insert_form.do"})
	public String insert_form() {
		return VIEW_PATH+"insert_form.jsp";
	}
	
}

 

컨트롤러의 객체는 ServletContext파일에서 만드는데 이번처럼 파일업로드의 경우 

db사용이 없으므로 수동탐색하지 않아도됨

자동탐색으로 만들어보자 

 

**참고로 db사용이 없으므로 upload.xml 파일에도 입력되는 쿼리 없음

**자동탐색으로 만드는 경우 자동생성파일인 HomeController와 충돌하여 오류를 발생시킬 수 있으므로 HomeController파일은 삭제한다.

 

 

 

ServletContext.java

package mvc;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


@Configuration
@EnableWebMvc
@ComponentScan("com.korea.upload") //자동탐색

//어노테이션에도 상속관계가 있다
/*
 *@Component
 *	ㄴ@Controller
 *	ㄴ@Service
 *	ㄴ@Repository 
 * */

//컴포넌트의 자식객체가 들어있으면 사실 Controller가 아니어도 만들어 질 수 있다.
public class ServletContext implements WebMvcConfigurer {

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {
		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
	}
	
//	  @Bean 
//	  public InternalResourceViewResolver resolver() {
//	  InternalResourceViewResolver resolver = new InternalResourceViewResolver();
//	  resolver.setViewClass(JstlView.class); resolver.setPrefix("/WEB-INF/views/");
//	  resolver.setSuffix(".jsp"); return resolver; }

}

 

 

 

insert_form.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Insert title here</title>
		<script type="text/javascript">
			function send(f){
				f.action = "upload.do";
				f.submit();
			}
		</script>
	</head>
	<body>
		<form method="POST" enctype="multipart/form-data">
			제목 : <input name = "title"><br>
			사진 : <input type = "file" name = "photo"><br>
			<input type = "button" value = "전송" onclick="send(this.form)">
		</form>
	</body>
</html>

 

 

 

FileUploadController.java

@Autowired : 필드주입 어노테이션 (내장객체 지원)

package com.korea.upload;

import java.io.File;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import vo.PhotoVO;

@Controller
public class FileUploadController {
	
	//필드주입 어노테이션
	//session, request와 같은 내장객체를 스프링에서도 지원함 
	@Autowired
	HttpServletRequest request;
	
	
	static final String VIEW_PATH = "WEB-INF/views/";
	
	@RequestMapping(value= {"/","insert_form.do"})
	public String insert_form() {
		return VIEW_PATH+"insert_form.jsp";
	}
	
	@RequestMapping("upload.do")
	public String upload(PhotoVO vo) {
		//우선 우리가 지정한 경로에 파일이 잘 업로드되는지 확인하자 
		String webPath ="/resources/upload"; //상대경로
		String savePath = request.getServletContext().getRealPath(webPath); //절대경로
		
		/* ServletContext app = request.getServletContext(); //위에서 autowired로 필드주입했기때문에 리퀘스트 사용가능
		 * app.getRealPath(webPath); //36행처럼 한줄로 줄여버릴 수 있음
		 */ 
		
		
		
		//업로드된 파일의 정보 
		//MultipartRequest 클래스가 없기 때문에 MultipartFile로 받는다 
		MultipartFile photo = vo.getPhoto();
		String filename="no_file";
		
		if(!photo.isEmpty()) { //비어있지 않을 때
			//getOriginalFilename() : 업로드된 실제 파일명 반환 
			//getName() : 파라미터의 이름(input태그의 이름) 반환 
			filename = photo.getOriginalFilename();
			
			//파일을 저장할 경로 지정 
			File saveFile = new File(savePath,filename);
			
			//만약 경로가 없다면 폴더를 만들어라 
			if(!saveFile.exists()) {
				saveFile.mkdirs(); //이미지도 폴더로 만들어버림..	
			}else {
				//동일한 이름파일의 경우 폴더형태로 변환 불가하므로 업로드 시간을 붙여서 이름이 중복되는 것을 방지 
				long time = System.currentTimeMillis();
				filename = String.format("%d_%s", time,filename);
				saveFile = new File(savePath,filename);
			}
			
			//물리적으로 파일을 변환하는 코드 
			try {
				photo.transferTo(saveFile);
			} catch (IllegalStateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		
		vo.setFileName(filename); //vo.getPhoto()로 얻어온 파일정보에서 파일이름을 뽑아내 저장 
		
		//기존에는 model로 바인딩했는데 request로 바인딩해보자!
		request.setAttribute("vo", vo);
		
		
		return VIEW_PATH+"input_result.jsp";
	}
}

 

 

 

input_result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>Insert title here</title>
	</head>
	<body>
		제목 : ${vo.title}<br>
		<img src = "${pageContext.request.contextPath}/resources/upload/${vo.fileName}" width="150">
	</body>
</html>

 

 

 

실행결과

 

 

 


 

 

방명록만들기(이전글)에 사진업로드를 적용해보자!

 

1. 파일업로드 프로젝트의 pom.xml 파일을 방명록만들기 프로젝트의 pom.xml 파일로 붙여넣기한다.

2.Context_4_fileUpload.java 파일을 방명록만들기 프로젝트에도 추가(붙여넣기)한다. + 방명록만들기 프로젝트 WebInitializer.java 내용도 추가 

3. 방명록만들기 프로젝트의 mapper파일인 visit.xml 새글추가 쿼리 부분에 파일이름도 추가(사진참고)

 

 

4. 여기까지 했을때, VISIT 테이블 자체에는 filename 속성이 없으므로 추가해줘야함

쿼리문 :

ALTER TABLE VISIT ADD FILENAME VARCHAR2(100);

 

 

5. 방명록만들기 프로젝트의 VisitVO.java 파일도 추가하자 

사진을 가져와서 filename 추출가능하게끔 하기위해,,

 

 

6. visit_insert_form.jsp 바디영역에 해당내용추가 

 

 

7. VisitController.java 해당내용추가 

 

 

8. visit_list.jsp 바디영역에 해당내용추가 

 

 

 

실행결과

 

728x90