스프링

 

서버에는 업로드와 관련해서 다음과 같은 여러 작업이 이루어 진다.

- 사용자가 업로드 하는 시간에 따른 자동적인 폴더 생성

- 업로드 되는 파일의 고유한 이름 생성

- 이미지 파일의 업로드 시 썸네일 이미지 (웹 페이지의 작은 이미지 파일)를 생성

- 이미지 파일의 경우 서버에서 저장된 파일을 읽어서 적당한 MIME 타입으로 서비스

- 일반 파일의 경우 다둔로드 타입으로 파일 데이터 서비스

 

이미지 파일의 경우에는 이미지를 깨끗하게 축소할 수 있는 imgScalr 라이브러리를 활용한다.

imgScalr 라이브러리는 큰 이미지 파일을 고정된 크기로 변환할때 편리하다.

 

* 라이브러리 설정

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

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>

 

Imgscalr A Java Image Scaling Library

<!-- https://mvnrepository.com/artifact/org.imgscalr/imgscalr-lib -->
<dependency>
    <groupId>org.imgscalr</groupId>
    <artifactId>imgscalr-lib</artifactId>
    <version>4.2</version>
</dependency>

 

스프링에서 multipartResolver 라고 하는  이  객체의 설정은 웹과 관련 있기 때문에 root-context.xml 이 아닌 servlet-context.xml 을

이용해서 설정한다.

servlet-context.xml

	<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	  <beans:property name="maxUploadSize"   value="10485760" />
	</beans:bean>
	
	

 

서버의 파일 저장 경로 설정

파일을 저장할 경로는 상수처럼 사용되기 때문에 servlet-context.xml 파일을 이용해서 특정 경로를 문자열로 설정한다.

 

1.

	<!-- 서버의 파일 저장 경로 설정 -->
	<beans:bean id="uploadPath" class="java.lang.String">
	 <beans:constructor-arg  value="/resources/upload"  />
	</beans:bean>

 

2. 실제 서버내 리눅스 주소를 입력 해라

	<!-- 서버의 파일 저장 경로 설정 -->
	<beans:bean id="uploadPath" class="java.lang.String">
	 <beans:constructor-arg  value="d:\\dev\\upload"  />
	</beans:bean>

 

 

FileCopyUtils 는 파일 데이터를 파일로 처리하거나, 복사하는 등의 작업에 유용하게 사용될 수 있다.  FileCopyUitls 클래스의 모든 static 메소드는

copy 이고, 다음과 같은 방식들이 제공된다.

 

주요 static 메소드                                                                                                        설명

copy(byte[] in, File out )                                                                데이터가 담긴 바이트의 배열(in) 을 파일에 기록한다.

copy(byte[] in, OutputStream out)                                           데이터가 담긴 바이트의 배열(in) 을 특정한 OutputStream 으로 전송한다.

copy(InputStream in, OutputStream out)                              특정한 InputStream 을 특정한 OutputStream 으로 전송한다.

copy(String in, Writer out)                                                            문자열을 그대로 Writer 를 이용해서 기록한다.

cpyToByteArray(InputStream in)                                             주어진 InputStream 을 읽어서 byte[] 로 만들어 반환한다.

 

 

 1. 기본적인 파일 업로드  방식

 

UploadController

package test.controller;

import java.io.File;
import java.util.UUID;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class UploadController {

	private static final Logger logger = LoggerFactory.getLogger(UploadController.class);

	@Resource(name="uploadPath")
	private String uploadPath;
	
	@RequestMapping(value="/test/uploadForm", method=RequestMethod.GET)
	public void uploadForm() throws Exception{	
	}
	
	
	@RequestMapping(value="/test/uploadForm", method=RequestMethod.POST)
	public void uploadForm(MultipartFile file, Model model ) throws Exception{
		logger.info("originalName :  "  + file.getOriginalFilename());
		logger.info("size : " + file.getSize());
		logger.info("contentType : " +file.getContentType());
		
		String savedName= uploadFile(file.getOriginalFilename(), file.getBytes());
		
		model.addAttribute("savedName", savedName);
	}
	
	
	private String uploadFile(String originalName, byte[] fileData) throws Exception{
		
		UUID uid=UUID.randomUUID();
	
		String savedName=uid.toString() + "_"+ originalName;
		
		File target =new File(uploadPath, savedName);
		
		FileCopyUtils.copy(fileData, target);
		
		return savedName;
	}
	
}

 

uploadForm.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>


	<form id="form1" action="uploadForm" method="post" enctype="multipart/form-data">
		<input type="file" name="file">
		<input type="submit">
	</form>

		<script type="text/javascript">
			var savedName = '${savedName}';

			if (savedName != '') {
				alert(savedName);
				location.href = "/test/uploadForm";
			}
		</script>
</body>
</html>

 

 

 

 2. 기본적인 Ajax 방식의 파일 업로드

 

 

 

Controller

@Controller
public class UploadController {


       private static final Logger logger = LoggerFactory.getLogger(UploadController.class);

	@Resource(name="uploadPath")
	private String uploadPath;


	//실질적으로 파일 저장
	private String uploadFile(String originalName, byte[] fileData) throws Exception{
		
		UUID uid=UUID.randomUUID();
	
		String savedName=uid.toString() + "_"+ originalName;
		
		File target =new File(uploadPath, savedName);
		
		FileCopyUtils.copy(fileData, target);
		
		return savedName;
	}
	

	//Ajax 업로드용 컨트롤러와 JSP 작성하기
	@RequestMapping(value="/test/uploadAjax", method=RequestMethod.GET)
	public void uploadAjax(){
		
	}
	
	
	@ResponseBody
	@RequestMapping(value="/test/uploadAjax", method=RequestMethod.POST,
					produces="text/plain;charset=UTF-8")
	public ResponseEntity<String> uploadAjax(MultipartFile file) throws Exception{
		
		logger.info("originalName ,  {} ",  file.getOriginalFilename());
		logger.info("size  : " , file.getSize());
		logger.info("contentType : " + file.getContentType());		
		return new ResponseEntity<String>(file.getOriginalFilename(), HttpStatus.CREATED);
	}



	
}	

 

 

 

uploadAjax.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
.fileDrop{

	width:100%;
	height:200px;
	border:1px dotted blue;

}

small{
	margin-left:3px;
	font-weight:bold;
	color:gray;
}

</style>
</head>
<body>


<h3>Ajax File Upload</h3>
<div class="fileDrop"></div>
<div class="uploadedList"></div>

<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>

<script>
~~
</script>
</body>
</html>

 

<script>
$(".fileDrop").on("dragenter dragover", function(event){
	event.preventDefault();
});

$(".fileDrop").on("drop", function(event){
	event.preventDefault();
	
	var files=event.originalEvent.dataTransfer.files;
	
	var file=files[0];
	
	console.log(file);
	var formData=new FormData();
	formData.append("file", file);

	$.ajax({
		
		url:'/test/uploadAjax',
		data:formData,
		dataType:'text',
		processData:false,
		contentType:false,
		type:'POST',
		success:function(data){
			alert(data);	
		}
	});
	
		
});

</script>

 

drop 이벤트가 발생했을 때 이벤트 처리 코드의 핵심적인 부분은 dataTransfer.files 의 부분으로, 전달된 파일 데이터를 가져오는 부분이다.

 

event.originalEvent 는 jQuery 를 이용하는 경우 event 가 순수한 DOM 이벤가 아니기 때문에 event.originalEvent 를 이용해서 순수한 원래의

DOM 이벤트를 가져온다.

       var file=files[0];

    var formData=new FormData();
    formData.append("file", file);
 

FormData append() 를 이용해서 file 이름으로 끌어다 놓은 파일 객체를 추가하는 것을 볼 수 있다.

FormData 의 경우 HTML5에서 지원되기 시작했기 때무에 브라우저의 제약이 있는 경우가 있다.

 

jquery의 $.ajax() 를 이용해서 FormData 객체에 있는 파일 데이터를 전송하기 위해서는 위 코드에 나와 있는 'processData' 와

'contentType' 옵션을 반드시 false 로 지정해야만 한다. 이 두개의 옵션은 데이터 전송을  <form> 태그를 이용하여 파일 업로드와 동일하게

해주는 결정적인 역할을 한다.

 

processData : 데이터를 일반적인 query string 으로 변환할 것인지를 결정한다. 기본값은 true, 'application/x-www-form-urlencoded' 타입으로

전송합니다. 다른 형식으로 데이터를 보내기 위하여 자동 변환하고 싶지 않은 경우는 false 를 지정합니다.

contentType : 기본 값은 'appplication / x-www-form-urlencoded' 이다.  파일의 경우 multipart/form-data 방식으로 전송하기 위해서 false 로

지정한다.

 

    @RequestMapping(value="/test/uploadAjax", method=RequestMethod.POST,
                    produces="text/plain;charset=UTF-8")

 

@RequestMapping 의 속성으로 produces 속성을 지정하고 있는데, 이것은 한국어를 정상적으로 전송하기 위한 간단한 설정이다.

맨 마지막의 ResponseEntitiy 를 전송하는 부분에서는 HttpStatus.CREATED 값을 지정했다. HttpStatus.CREATED 는 원하는 리소스가

정상적으로 생성되었다는 상태 토드이다.   원한다면 HttpStatus.OK 를 이용해도 무방하다.

 

 

스프링 내 파일 경로를 가져 올때

package com.macaronics.www.util.fileupload;

import java.io.File;

import javax.servlet.http.HttpServletRequest;

public class UploadPath {

	public static String attach_path ="WEB-INF/uploads/";
	
	
	public static String path(HttpServletRequest request){	
		String uploadPath ="";		
		try{
			String root_path =request.getServletContext().getRealPath("/");
			
			uploadPath =root_path+attach_path.replace('/', File.separatorChar);
			
		}catch(Exception e){
			e.printStackTrace();
		}		
		return uploadPath;
	}
	
	
}

 

 

 

 

about author

PHRASE

Level 60  라이트

The proof of the pudding is in the eating. (말보다 싫증(實證)

댓글 ( 5)

댓글 남기기

작성