■ 파일 이름 겹치는 문제 해결.

1. 파일 이름 중복 문제 해결 정책 작성.

package com.myhome.upload.policy;

import java.io.File;
import java.io.IOException;

public class FileRenamePolicy {
 
  public File rename(File f) {  //File f는 원본 파일
    if (createNewFile(f)) return f; //생성된 f가
   
    //확장자가 없는 파일 일때 처리
    String name = f.getName();
    String body = null;
    String ext = null;

    int dot = name.lastIndexOf(".");
    if (dot != -1) { //확장자가 없을때
      body = name.substring(0, dot);
      ext = name.substring(dot);
    } else {   //확장자가 있을때
      body = name;
      ext = "";
    }

    int count = 0;
    //중복된 파일이 있을때
    while (!createNewFile(f) && count < 9999) {  
      count++;
      String newName = body + count + ext;
      f = new File(f.getParent(), newName);
    }
    return f;
  }

  private boolean createNewFile(File f) { 
    try {
      return f.createNewFile();  //존재하는 파일이 아니면
    }catch (IOException ignored) {
      return false;
    }
  }
}


2. 적용

import com.myhome.upload.policy.FileRenamePolicy;

.... 생략 ....

protected void upload() throws Exception{
  File file = new File(UploadUtil.SAVE + bean.getFileFileName()); //bean이 참조하고 있는 파일을 실제 파일로 얻어온다
  
  /* file rename policy 적용
   * a.txt가 중복일 경우  -> a1.txt(중복이라면) -> a2.txt........
   * */

  
  file = new FileRenamePolicy().rename(file); //적용!
  
  log.info("template file : " + bean.getFile().toString());
  log.info("original file : " + file.toString());
  
FileUtils.copyFile(bean.getFile(), file); //bean에 있는 파일은 template 파일이다. templete의 파일을 실제파일로 복사여 폴더에 저장한다.
  FileUtils.forceDelete(bean.getFile()); //templete에 있는 파일을 삭제한다. 계속 쌓아 두기 때문에 삭제 해줘야 한다.
  
  dto.setFileName(file.getName()); //DB에 저장하기 위해 빈으로 부터 파일과 크기를 받는다.
  dto.setFileSize(file.length());
  
 }

..... 생략 .....


■ download

property를 구별하기 위해 DownloadAction.java 를 별도로 만들었다.

1. DownloadAction Class 만들기

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 {
    /*encFile를 실제 파일로 객체를 생성한다.*/
    File file = new File(UploadUtil.SAVE + filename);
   
    /*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;
 }
 
 /*decode (MS949 -> ISO8859_1)*/
 protected String toEng(String data){
  try{
   data = new String(data.getBytes("MS949"), "ISO8859_1");
  }catch(java.io.UnsupportedEncodingException uee){}
  return data;
 }

}

2. upload.xml 에 download action 추가.

<action name="download"
       class="com.myhome.upload.actions.DownloadAction">
       <result name="success" type="stream"> <!-- strem으로 설정하면 Action Class의 InputStream으로 받아온다 -->
            <param name="contentType">application/octet-stream</param> <!-- 이렇게 설정 안해주면 한글 다운로드가 안된다. -->
             <param name="contentLength">${contentLength}</param> <!-- 파일 크기 -->
            <param name="contentDisposition">${contentDisposition}</param> <!--파일의 이름을 설정하기 위한 컨텐츠 헤더값 지정-->
           <param name="bufferSize">4096</param> <!-- 한번에 다운로드 할 수 있는 버퍼 사이즈 -->

          </result> 
     </action>


3. jsp 만들기

list.jsp

<%@ page contentType="text/html;charset=euc-kr"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<html>
  <head>
    <script type="text/javascript">
      function query(num){
      var v = document.listform;
      v.num.value=num;
      v.action="query.action";
      v.submit();  
      }
     
      function download(fn){
        var v = document.listform;
        v.filename.value=fn;
        v.submit();
      }
    </script>
 
 <style type="text/css">
     a:active  {font-size: 10pt; text-decoration: none; color: #000000}
  a:link    {font-size: 10pt; text-decoration: none; color: #000000}
  a:visited {font-size: 10pt; text-decoration: none; color: #000000}
  a:hover   {font-size: 10pt; text-decoration: none; color: #000000}
  td     {font-size: 10pt;}
    </style> 
  </head>  
  <body>
    <center><br />
    <h3><b>Struts2 Upload_Download(list)</b></h3>
    <form method="POST" name="listform" action="download.action">
     <input type="hidden" name="num">
     <input type="hidden" name="filename">
     <table border=0 cellpadding=0 cellspacing=1 bgcolor="#000000">
      <tr height=30 bgcolor="#f0f0f0">
        <td width=50 align="center"><b>번호</b></td>
        <td width=100 align="center"><b>회원명</b></td>
        <td width=60 align="center"><b>성별</b></td>
        <td width=120 align="center"><b>연락처</b></td>
  <td width=120 align="center"><b>가입일자</b></td>
  <td width=250 align="center"><b>첨부파일(크기)</b></td>   
      </tr>
     <s:iterator value="list">
      <tr height=30 bgcolor="#ffffff">
        <td align="center">&nbsp;<s:property value="num"/></td>
        <td align="center">
           <a href="javascript:query('${num}')">&nbsp;${name}</a> 
      </td>
      <td align="center">&nbsp;<s:property value="sex" /></td>
      <td align="center">&nbsp;${tel}</td>
      <td align="center">&nbsp;${wdate}</td> 
      <td align="left">&nbsp;
        <c:if test="${fileSize > 0}">
           <a href="javascript:download('${fileName}')">${fileName}</a>
            <span style="font-size:10pt; color:#90a087">
             (<fmt:formatNumber value="${fileSize/1024.}"
                                type="number"
                                pattern="#,##0.00"/>KB)
            </span> 
        </c:if> 
      </td>
      </tr>
     </s:iterator>
      <tr height=30 bgcolor="#f0f0f0">
        <td align="center" colspan=6>
          <input type="button" value="등록하기"
              onclick="javascript:location.href='index.action'">
        </td>
     </tr>
     </table>
    </form> 
   </center>
  </body>
</html>

struts2를 이용한 다운로드 끝!

Struts2 에서 upload & download 하기 3에서 파일 참조.

+ Recent posts