본문 바로가기

프레임워크/Struts2

Struts2에서의 파일업로드

org.apache.struts2.interceptor.FileUploadInterceptor
  • 파일 업로드 인터셉터의 역할은 폼의 enctype이 "multipart/form-data"일 경우,

<s:file/>로 업로드한 파일이 있는 요청에서 파일 정보를 뽑아낸다.

  • 이 인터셉터로 부터 자동으로 가져올 수 있는 정보는 다음과 같다.
    • 파일 내용
    • 컨텐츠 타입(postFix : ContentType)
    • 파일명(postFix : FileName)

 

구현하기

여기서는 스트러츠 기반의 가장 단순한 형태의 파일 첨부 모듈을 구현하도록 한다. 임의로 D드라이브 아래에 temp라는 디렉토리를 만들어 둔다. 이 폴더에 첨부한 파일명 그대로 저장될 것이다.

Model

파일을 서버에서 받을때, 실제 파일은 java.io.File이라는 형태로 넘어오게 되는데,
그 파일의 업로드시의 실제 이름이나 타입이 필요하므로, 추가로 ContentType과 FileName을 선언한다.
하지만 이 둘은 개발자가 작업하지 않아도 인터셉터를 통하여 자동으로 받아오게 되므로,
개발자는 이 어트리뷰트의 이름만 신경써서 지정하도록 한다.
인터셉터에서 자동으로 파일어트리뷰트명 뒤에 이름을 붙이므로, 이에 맞추어 작성한다.

 예 ) 파일 어트리뷰트명 : attach 일 때, (대소문자 주의)
    ->파일 타입 : attachContentType
    ->파일 명 : attachFileName
public class User {
	private String id;
	private String name;
	private String address;
	private File attachFile;
	private String attachFileContentType;
	private String attachFileFileName;

JSP

파일 업로드시 Form은 반드시 enctype으로 정의해야 한다. 그러므로, enctype="multipart/form-data" 라는 것을 반드시 추가하도록 한다.

<s:form name='userForm' action='saveUser' theme='simple' enctype="multipart/form-data" method="POST">

이제 <s:file />태그를 이용하여 파일 첨부하는 부분을 지정한다.

<s:file name="user.attachFile"/>

Action

Action 클래스에 파일이 저장될 위치를 선언한다.

public class UserAction extends BaseAction {
	/*
	 * *** PROPERTIES ***
	 */
	private User user;
        ...
	private String FILE_PATH = "D:\\\\temp\\";

이제 java.io.File 타입으로 넘어온 attachFile을 FileInputStream으로 변환하여
FileOutputStream으로 처리하여 서버에 저장하도록 한다. 서버에 저장시 원래이름을 가져오기 위해
attachFileFileName을 쓰도록 한다.

public String saveUser() throws IOException{		
	User checkUser = userService.findUser(user.getId());
	FileInputStream inputStream = new FileInputStream(user.getAttachFile());
	FileOutputStream outputStream = 
           new FileOutputStream(FILE_PATH+user.getAttachFileFileName());
	int bytesRead = 0;
	byte[] buffer = new byte[1024];
	while ((bytesRead = inputStream.read(buffer,0,1024))!=-1){
		outputStream.write(buffer, 0, bytesRead);			
	}
	outputStream.close();
	inputStream.close();				
		
	if (checkUser == null)
		userService.createUser(user);
	else
		userService.updateUser(user);
 
	return SUCCESS;
}

파일 다운로드

다운로드시에는 업로드시 지정했던 경로와 저장 파일 명을 찾아서 java.io.File 타입으로 만든 후에, BufferedOutputStream으로 작성해 준다.

public String downloadFile() throws IOException {
	user = userService.findBlog(user.getId());
	
	user.setAttachFile(new File(FILE_PATH + user.getAttachFileFileName()));
		
	getResponse().setHeader("Content-type", user.getAttachFileContentType());
	getResponse().setHeader("Content-Disposition","attachment;filename ="+ URLEncoder.encode(user.getAttachFileFileName(),"UTF-8")+"");
 
	byte[] buffer = new byte[1024];
	
	BufferedInputStream ins = new BufferedInputStream(new FileInputStream(user.getAttachFile()));
	BufferedOutputStream outs = new BufferedOutputStream(getResponse().getOutputStream());
	int read=0;
	while ((read = ins.read(buffer)) != -1) {
          outs.write(buffer, 0, read);
        }
		
	outs.close();
	ins.close();
	
	return SUCCESS;
}
출처 : http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/File_attaching