java에서struts2 파일 업로드 다운로드 기능 실례 분석 실현

본고는 자바에서struts2가 파일 업로드 다운로드 기능을 실현하는 방법을 실례로 기술하였다.여러분에게 참고할 수 있도록 나누어 드리겠습니다.구체적인 분석은 다음과 같다.
1. 파일 업로드
우선 jsp 페이지 코드입니다.
jsp 페이지에서 업로드 탭 정의
 

     <td align="right" bgcolor="#F5F8F9"><b> :</b></td>
     <td bgcolor="#FFFFFF">
     <input type="file" name="upload" />
     </td>
     <td bgcolor="#FFFFFF">&nbsp;</td>
</tr>
그리고 BaseAction에서 정의한 관련 속성은 다른 것은 생략합니다(자신의 Action에서 정의할 수도 있고 액세스 수식자를 바꾸면 됩니다).
 
/**
*Action
**/
public class BaseAction extends ActionSupport {
    protected List<File> upload;
    protected List<String> uploadContentType; //
    protected List<String> uploadFileName;    //
    protected String savePath;                //
}
다음은 Action의 업로드 방법 중 하나입니다. 코드는 다음과 같습니다.
/**
  * 8.
  * @param upload
  */
  public void uploadAccess(List<File> upload){
        try {
            if (null != upload) {
                for (int i = 0; i < upload.size(); i++) {
                    String path = getSavePath() + ""+ getUploadFileName().get(i);
                    System.out.println(path);
                    item.setAccessory(getUploadFileName().get(i));
                   
                    FileOutputStream fos = new FileOutputStream(path);
                    FileInputStream fis = new FileInputStream(getUpload().get(i));
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = fis.read(buffer)) > 0) {
                        fos.write(buffer, 0, len);
                    }
                    fis.close();
                    fos.close();
                }
            }
        } catch (Exception e) {
            logger.error(" 。", e);
        }
}
다음은 저의 struts2.xml 파일

     <param name="savePath">e:upload</param>
     <interceptor-ref name="defaultStack">
           <param name="fileUpload.allowedTypes">
               application/octet-stream,image/pjpeg,image/bmp,image/jpg,image/png,image/gif,image/jpeg,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-excel
           </param>
           <param name="fileUpload.maximumSize">8000000</param>
     </interceptor-ref>
     <result name="show_item_rd_upd">  /WEB-INF/jsp/page_item/updItem_rd.jsp</result>
     <result name="show_item_rd_list"> /WEB-INF/jsp/page_item/listItem_rd.jsp</result>
     <result name="show_item_rd_push"> /WEB-INF/jsp/page_item/pushItem_rd.jsp</result>
</action>
savePath는 저장 경로, fileUpload입니다.allowedTypes는 파일 형식 파일 업로드를 제한하는 데 사용됩니다.최대 파일 크기 제한
2. 파일 다운로드
우선 페이지의 다운로드 링크입니다.

   <td width="20%" align="right" bgcolor="#F5F8F9"><b> :</b></td>
   <td width="40%" bgcolor="#FFFFFF">
   <div style="width:355px; float: left;">${item.accessory}</div>
       <c:if test="${!empty item.accessory}">
           <div class="btn_img" style="float: left;"><a style="color: black; text-decoration: none;" href="download.action?filename=${item.accessory}"> </a></div>
       </c:if>
   </td>
   <td width="40%" bgcolor="#FFFFFF">&nbsp;</td>
</tr>
다음은 DownloadAction 코드입니다.
/**
 * DownloadAction
 *
 * @author zhaoxz
 *
 */
@Controller("downloadAction")
@Scope("prototype")
public class DownloadAction extends BaseAction {
    /**
     *
     */
    private static final long serialVersionUID = -4278687717124480968L;
    private static Logger logger = Logger.getLogger(DownloadAction.class);
    private String filename;
    private InputStream inputStream;
    private String savePath;
    private String mimeType;
    public InputStream getInputStream() {
        try {
            String path = getSavePath() + "//"+ new String(filename.getBytes("ISO8859-1"), "utf-8");
            System.out.println(path);
            mimeType = ServletActionContext.getServletContext().getMimeType(path)+ ";charset=UTF-8";
            inputStream = new FileInputStream(path);
            String agent = request.getHeader("USER-AGENT");
            System.out.println(agent);
            if (null != agent) {
                if (-1 != agent.indexOf("Firefox")) {// Firefox
                    mimeType = mimeType.replace("UTF-8", "ISO8859-1");
                } else {// IE7+ Chrome
                    System.out.println("IE,Chrome");
                    filename = new String(filename.getBytes("ISO8859-1"),"utf-8");
                    filename = java.net.URLEncoder.encode(filename, "UTF-8");
                }
            }
        } catch (Exception e) {
            logger.error(" 。", e);
        }
        if (null == inputStream) {
            System.out.println("getResource error");
        }
        return inputStream;
    }
    public void setInputStream(InputStream inputStream) {
        this.inputStream = inputStream;
    }
    @Override
    public String execute() throws Exception {
        return SUCCESS;
    }
    /*************************** get set ******************************/
    public String getSavePath() {
        return this.savePath;
    }
    public void setSavePath(String savePath) {
        this.savePath = savePath;
    }
    public String getFilename() {
        return filename;
    }
    public void setFilename(String filename) {
        this.filename = filename;
    }
}
그리고 얘의struts2.xml 파일:
 

    <param name="savePath">E:/upload</param>
    <result type="stream">
          <param name="contentType">${mimeType}</param>
          <param name="contentDisposition">attachment;filename="${filename}"</param>
          <param name="inputName">inputStream</param>
    </result>
</action>
다운로드하면 인코딩 형식을 주의하면 기본적으로 아무런 문제가 없을 것이다.
업로드 과정에서 부딪힌 문제
1. 큰 파일을 올리면 오류 해결 방법 1
다음과 같은 오류가 발생했습니다.
1、2012-02-24 11:06:31,937 ERROR (org.apache.struts2.dispatcher.Dispatcher:512) - Could not find action or result
No result defined for action com.iman.portal.action.QuestionActionImpl and result problemPage - action - file:/E:/myeclipse/workspaces/portal/WebRoot/WEB-INF/classes/struts2/struts-question.xml:51:55
2、the request was rejected because its size (2973652) exceeds the configured maximum (2097152)
크기(2973652)가 구성의 최대치(2097152)를 초과하여 거부되었습니다.
사용자 경험을 고려하여 첨부 파일을 업로드할 때 이러한 이상을 차단해야 합니다. 해결 방법은 다음과 같습니다.
1. 업로드된 파일은 업로드 과정에서 캐시에 저장되고 안전하며 프로젝트의struts에 저장됩니다.properties 파일에 임시 저장 경로를 추가합니다. 프로젝트에 서버의 물리적 경로가 설정되어 있지만.
 
   struts.multipart.saveDir=/temp
2. 후기에 파일 업로드 크기를 수정할 수 있음을 고려하여 기본값이든 프로젝트의struts든.properties 파일에 다음과 같은 구성을 추가합니다.
    
    <constant name="struts.multipart.maxSize" value="2097152"/>
3、struts.xml 구성
 
   
    <action name="updateProblem" method="updateProblem">
      <interceptor-ref name="fileUpload"/>
      <interceptor-ref name="defaultStack" />
     <result name="input">/page/question/page/problemPage.jsp</result>
    </action>
4. 가장 중요하고 가장 중요한 단계
fileUpload 차단기는 파일이 서버에 업로드된 후에만 파일 형식과 크기를 판단합니다.Action에서 우리가 아무 조작도 하지 않으면 이상이 사용자 앞에 나타나기 때문에 이 이상 정보를 Action 단계의 오류 정보로 설정하는 방법을 생각해 봤습니다.addActionError 메서드를 다시 작성합니다.
 
@Override
   public void addActionError(String anErrorMessage) {
    // , ,
    if (anErrorMessage.startsWith("the request was rejected because its size")) {
        Pattern pattern = Pattern.compile("d+");
        Matcher m = pattern.matcher(anErrorMessage);
        //
        m.find();       
        String s1 =m.group();//
        //
        m.find();       
        String s2 =m.group();//            
        if(!s1.equals("") && !s2.equals("")){
            fileUploadErrorMessage=" (" +  Long.valueOf(s1)/1024 +" ) (" + Long.valueOf(s2)/1024/1024 + "M)";
            getRequest().setAttribute("fileUploadErrorMessage"," , ("+Long.valueOf(s2)/1024/1024+"M), !");
            //
            super.addActionError(fileUploadErrorMessage);
            }
        } else {//
            super.addActionError(anErrorMessage);
        }
}
네, 되돌아오는 페이지에서 를 사용하여addActionError의 오류 내용을 얻을 수 있습니다.
페이지에 오류가 발생한 이유를 표시하지 않으려고 알림 상자를 뜨려고 해서request 대상에 정보를 넣었습니다.
페이지를 불러올 때 다음과 같은 js 인증이 추가되었습니다.
//   
    var message="${request.fileUploadErrorMessage}";
        if(message!=null && ""!=trim(message) && message!="null"){
            self.parent.diag.close();
        alert(message);
        return;
}
다음은 몇 가지 참고로 동동을 이해한다.
struts.multipart.maxSize가 전체 프로젝트에 업로드된 파일을 제어하는 최대 크기
struts.multipart.maxSize와 fileUpload 차단기의 maximumSize 속성 분업은 다음과 같습니다.
1.struts.multipart.maxSize는 전체 프로젝트에 업로드된 파일의 최대 크기를 제어합니다.
이 크기를 초과하면 백그라운드에서 오류를 보고합니다. 프로그램은 이렇게 큰 파일을 처리할 수 없습니다.fielderror에는 다음과 같은 메시지가 표시됩니다.
  the request was rejected because its size (16272982) exceeds the configured maximum (9000000)
2.fileUpload 차단기의 maximumSize 속성은 struts보다 작아야 합니다.multipart.maxSize 값입니다.
  struts.multipart.maxSize 기본 2M, maximumSize가 2M보다 크면 struts를 설정해야 합니다.multipart.maxSize 값이 maximumSize 보다 큽니다.
3. 업로드된 파일이struts보다 크면.multipart.maxSize 시 시스템 오류 발생
업로드된 파일은struts에 있습니다.multipart.maxSize와 maximumSize 사이의 경우 다음 메시지가 표시됩니다.
File too large: file "MSF의 개념.ppt""upload__5133e516_129ce85285f__7ffa_00000005.tmp"6007104
업로드된 파일이 maximumSize보다 작으면 업로드에 성공했습니다.

            <result name="UploadFileResult">/pages/ShowOtherFiles.jsp</result>
            <result name="JGBsuccess">/pages/JGBdetail.jsp</result>
            <interceptor-ref name="fileUpload">
                <param name="savePath">/data</param> 
                <param name="maximumSize">52428800</param>
            </interceptor-ref>
            <interceptor-ref name="defaultStack"></interceptor-ref>
</action>
큰 파일을 업로드하면 오류 해결 방법 2:
문제: 큰 파일 업로드 오류...
해결:struts를 수정합니다.xml 파일의 매개 변수는 다음과 같습니다.

<action name="UploadFile" class="com.buptisc.srpms.action.UploadFileAction">
            <result name="UploadFileResult">/www.jb51.net/ ShowOtherFiles.jsp</result>
            <result name="JGBsuccess">/pages/JGBdetail.jsp</result>
            <interceptor-ref name="fileUpload">
                <param name="savePath">/data</param> 
                <param name="maximumSize">52428800</param>
            </interceptor-ref>
            <interceptor-ref name="defaultStack"></interceptor-ref>
</action>
struts.xml 파일의 크기와 실제 파일 크기의 관계: 1048576(Bytes) = 1024*1024 = 1M 실제 파일 크기.
struts.multipart.maxSize가 전체 프로젝트에 업로드된 파일을 제어하는 최대 크기
struts.multipart.maxSize와 fileUpload 차단기의 maximumSize 속성 분업은 다음과 같습니다.
1.struts.multipart.maxSize는 전체 프로젝트에 업로드된 파일의 최대 크기를 제어합니다.이 크기를 초과하면 백그라운드에서 오류를 보고합니다. 프로그램은 이렇게 큰 파일을 처리할 수 없습니다.fielderror에는 다음과 같은 메시지가 표시됩니다.
the request was rejected because its size (16272982) exceeds the configured maximum (9000000)
2.fileUpload 차단기의 maximumSize 속성은 struts보다 작아야 합니다.multipart.maxSize 값입니다.
struts.multipart.maxSize 기본 2M, maximumSize가 2M보다 크면 struts를 설정해야 합니다.multipart.maxSize 값이 maximumSize 보다 큽니다.
3. 업로드된 파일이struts보다 크면.multipart.maxSize 시 시스템 오류 발생
업로드된 파일은struts에 있습니다.multipart.maxSize와 maximumSize 사이의 경우 다음 메시지가 표시됩니다.
File too large: file "MSF의 개념.ppt""upload__5133e516_129ce85285f__7ffa_00000005.tmp"6007104
업로드된 파일이 maximumSize보다 작으면 업로드에 성공했습니다.
업로드 파일 형식 제한
fileupload 차단기 설정
struts2의 defaultStack에는 이미 fileupload 차단기가 포함되어 있습니다. allowedTypes 파라미터를 추가하려면 defaultstack을 새로 써야 합니다. 복사해서 수정하면 됩니다.
  
             <interceptor-stack name="myDefaultStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name=www.jb51.net/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="debugging"/>
                <interceptor-ref name="profiling"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload">
                  <param name="allowedTypes">
                     image/png,image/gif,image/jpeg
                  </param>
                </interceptor-ref>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="actionMappingParams"/>
                <interceptor-ref name="params">
                  <param name="excludeParams">dojo..*,^struts..*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
            </interceptor-stack>
</interceptors>
<default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
코드의

  <param name="allowedTypes">
     image/png,image/gif,image/jpeg
  </param>
</interceptor-ref>
 
차단기 창고는 탭에 탭 밖으로 설정되어 있습니다. 기본 차단기로 정의하면
탭에 도입, 없으면 차단기 도입

       <result name="input">/error/dbError.jsp</result>
       <interceptor-ref name="myDefaultStack"></interceptor-ref>
</action>
  
파일 업로드 형식 오류 액션은 input로 되돌아오기 때문에 액션에서 "input"를 되돌릴 필요가 없습니다.
 
또한 탭 밖에서 당신의 업로드 경로와 크기를 정의할 수 있습니다.

<constant name="struts.multipart.maxSize" value="1024"></constant>
가장 중요한 점: 파일을 업로드하는 폼에 enctype = "multipart/form-data"를 추가하지 않으면 input 오류가 발생합니다.
본 논문이 여러분의 자바 프로그램 설계에 도움이 되기를 바랍니다.

좋은 웹페이지 즐겨찾기