struts 2 - upload & download

Published on: 2009. 7. 5. 16:17 by louis.dev


작업순서
1. upload 하기 위한 library 파일을 추가한다.
www.apache.org --> commons --> io 와 FileUpload library를 다운받아 추가 한다.

2. FormBean class를 생성한다

--------------------------------------------------------------------------------------------------
package com.myhome.upload.beans;

import java.io.File;

 

public class UploadFormBean {

 //form property 설정
 private int      num;
 private String name;
 private String sex;
 private String tel;
 
 /*file upload property*/
 private File   file;
 private String fileFileName;
 private long   fileFileSize;
 private String fileContentType;

 
 
 public int getNum() {
  return num;
 }
 public void setNum(int num) {
  this.num = num;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getSex() {
  return sex;
 }
 public void setSex(String sex) {
  this.sex = sex;
 }
 public String getTel() {
  return tel;
 }
 public void setTel(String tel) {
  this.tel = tel;
 }
 public File getFile() {
  return file;
 }
 public void setFile(File file) {
  this.file = file;
 }
 public String getFileFileName() {
  return fileFileName;
 }
 public void setFileFileName(String fileFileName) {
  this.fileFileName = fileFileName;
 }
 public long getFileFileSize() {
  return fileFileSize;
 }
 public void setFileFileSize(long fileFileSize) {
  this.fileFileSize = fileFileSize;
 }
 public String getFileContentType() {
  return fileContentType;
 }
 public void setFileContentType(String fileContentType) {
  this.fileContentType = fileContentType;
 }
 
 
}
--------------------------------------------------------------------------------------------------
file 을 저장하는 property 부분을 오면
private File   file;
private String fileFileName;
private long   fileFileSize;
private String fileContentType;
다음과 같이 선언되어 있는데 fileName,fileSiz,ContentType의 이름은 private File file + property 이름을 하면 자동으로 파일에 대한 정보가 맵핑이 된다.
즉 file + FileName
         + FileSize
         + Contenttype
으로 선언해야 자동으로 파일에 대한 정보가 들어가게 된다.

3. DTO를 생성한다.

4. DB에 접근할 DAO를 생성한다.

5. SqlMap 파일 생성

[option]
6. properties 파일을 만든다.
# upload project message bundle
# file name ; package.properties

register.title=Struts2 File Upload (Register)
register.name=성 명
register.sex=성 별
register.tel=연락처
register.file=첨부

error.name=성명은 필수 입력항목입니다.
error.name.length=잘못 입력된 성명입니다.
error.tel=연락처를 입력하세요!!!
error.tel.length=사용할 수 없는 번호 입니다.

# native2ascii -encoding euc-kr package.properties package_ko.properties

다음과 같이 생성한 후에 jsp 페이지에서 <s:text name="register.name" /> 접근하면 properties파일에 생성된 register.name이란 키 값으로 텍스트를 출력한다.

properties파일은 xml 파일의 옵션을 설정함으로서 xml파일이름+.properties 란 이름으로 지정된다. 이렇게 되었을때 xml을 로딩할때 같은 패키지에 같은 이름의 properties파일이 있게 되면 이때 같이 로딩이된다.
여기서 properties 파일 이름을 global.properties나  package.properties 파일로 지정하게 면 was가 실행될때 자동으로 로딩되어 설정을 사용할 수 있게 된다.


7. upload.xml파일 생성 후 struts.xml에 추가

8. UploadUtil class 생성

package com.myhome.upload.util;

public final class UploadUtil {
 
 public static final String SAVE = "D://JAVA/Java Web2/edu/uploadTest/";
 
 public static final long SIZE = 1024 * 1024 *20;
}


9.uploadAction class 생성
--------------------------------------------------------------------------------------------------
package com.myhome.upload.actions;

import java.io.File;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


import com.myhome.upload.beans.UploadFormBean;
import com.myhome.upload.dao.UploadDAO;
import com.myhome.upload.dto.UploadDTO;
import com.myhome.upload.util.UploadUtil;
import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class UploadMultiAction extends ActionSupport{

 public static final Log log = LogFactory.getLog(UploadMultiAction.class);
 
 private UploadFormBean bean;
 private UploadDTO dto;
 /*
  * 등록부분
  * */
 public String register() throws Exception{

//jsp페이지로 들어온 정보는 bean에 저장된다.

  dto = new UploadDTO();
  BeanUtils.copyProperties(dto, bean);      //bean의 정보를 dto에 저장한다.
  if(bean.getFile() != null){
   upload();
  }else{
   dto.setFileName("");
   dto.setFileSize(0L);
  }
  new UploadDAO().insert(dto);
  return SUCCESS;
 }

 protected void upload() throws Exception{
/*bean이 참조하고 있는 파일을 실제 파일로 얻어온다.*/
  File file = new File(UploadUtil.SAVE + bean.getFileFileName());       
/*templete에는 파일을 실제파일로 복사여 폴더에 저장한다.*/
  FileUtils.copyFile(bean.getFile(), file);
   /*templete에 있는 파일을 삭제한다.*/
FileUtils.forceDelete(bean.getFile());
 
/*DB에 저장하기 위해 빈으로 부터 파일과 크기를 받는다.*/
  dto.setFileName(file.getName());
  dto.setFileSize(file.length());
 }
 
 public UploadFormBean getBean() {
  return bean;
 }

 public void setBean(UploadFormBean bean) {
  this.bean = bean;
 }

 public UploadDTO getDto() {
  return dto;
 }
 
 
}
--------------------------------------------------------------------------------------------------


2. File Download

File Download 는 일반 html 처럼 <a>태그로 파일의 주소를 링크걸어 사용하는 것이 아니라 FileInputStream을 이용하여 사용자에게 직접 Stream을 쏴주는 방법을 채택하고 있다.

1) jsp 페이지에서 download Action 요청
jsp페이지로부터 Download Action을 요청하면 xml의 ActionMapping을 통하여 ActionClass가 실행된다.

2) ActionMpping을 수행할 xml문서를 생성한다.

<action name="download"
       class="com.myhome.upload.actions.DownloadAction"
       method = "execute">
     
      <!-- type : stream으로 설정하면 Action class의 InputStream을 받아온다  --> 
      <result name="success" type="stream">
          <param name="contentType">application/octet-stream</param> <!-- 이렇게 하지 않으면 다운로드 안된다 -->
          <param name="contentLength">${contentLength}</param>
          <param name="contentDisposition">${contentDisposition}</param>
          <param name="bufferSize">4096</param>  <!-- 버퍼사이즈 적용 -->
      </result>
     </action>
 
param-name의 이름으로 다음과 같은 값을을 jsp페이지로 리턴하게 된다. 위의 값은 Action class에서 정의한 property들이다.

3) Actios Class 생성

File을 InputStream으로 쏴줄 Class 파일이다.
이중에서 다음과 같은 프로퍼티와 getter 와 setter는 반드시 설정되어 있어야 한다.
private InputStream inputStream;
private int              contentLength;
private String          contentDisposition;

다음과 같은 프로퍼티와 getter와 setter가 있어야 Action의 다음단계인 Result로 데이터를 쏴줄수가 있게 된다.

--------------------------------------------------------------------------------------------------
package com.myhome.upload.actions;

import com.opensymphony.xwork2.ActionSupport;

import com.myhome.upload.util.UploadUtil;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;

public class DownloadAction extends ActionSupport {
 
 private static final long serialVersionUID = 1L;
 
 /*form property fields*/
 private String filename;
 
 /*result property fields*/
 private InputStream inputStream;
 private int   contentLength;
 private String   contentDisposition;

 
 @Override
 public String execute()throws Exception {
  if(filename != null){
   download();
  }
  return SUCCESS;
 }

 public void download()throws Exception {
     /*form param으로 설정된 파일을 받는다.*/
    String encFile = filename;
   
    /*encFile를 실제 파일로 객체를 생성한다.*/
    File file = new File(UploadUtil.SAVE+encFile);
   
    /*contentLength를 설정한다.
     * 설정하지 않으면  다운로드 되지 않는다.
     * */

    setContentLength((int)file.length());
   
    /*어떤 파일이든지 다운로드가 되도록 어터치한다.*/
    setContentDisposition("attachment;filename=" + toEng(file.getName())+";");
   
    /*실제 다운로드를 받기 위해 스트림한다.*/
    setInputStream(new FileInputStream(UploadUtil.SAVE+file.getName()));
 }
 
 public String getFilename() {
  return filename;
 }

 public void setFilename(String filename) {
  this.filename = filename;
 }

 public InputStream getInputStream() {
  return inputStream;
 }

 public void setInputStream(InputStream inputStream) {
  this.inputStream = inputStream;
 }

 public int getContentLength() {
  return contentLength;
 }

 public void setContentLength(int contentLength) {
  this.contentLength = contentLength;
 }

 public String getContentDisposition() {
  return contentDisposition;
 }

 public void setContentDisposition(String contentDisposition) {
  this.contentDisposition = contentDisposition;
 }
 /*decoding 처리 해줌(MS949 -> ISO 8859_1)*/
 protected String toEng(String data){
  try{
   data = new String(data.getBytes("MS949"),"ISO8859_1");
  }catch(Exception e){
   
  }
  return data;
 }
}

--------------------------------------------------------------------------------------------------

'Framework > STRUTS 2' 카테고리의 다른 글

struts 2 - Interceptor  (3) 2009.07.06
struts 2 - properties 파일  (1) 2009.07.05
struts 2 - session 사용하기  (1) 2009.07.05
struts 2 - action을 선언한 xml에서 result property 들  (0) 2009.07.05
struts 2 - validator  (0) 2009.07.03