Java Struts檔案上傳和下載詳解

偶my耶的部落格發表於2015-03-31

Struts2檔案上傳

Struts 2框架提供了內建支援處理檔案上傳使用基於HTML表單的檔案上傳。上傳一個檔案時,它通常會被儲存在一個臨時目錄中,他們應該由Action類進行處理或移動到一個永久的目錄,以確保資料不丟失。

請注意,伺服器有一個安全策略可能會禁止寫到目錄以外的臨時目錄和屬於web應用的目錄。

在Struts中的檔案上傳是通過預先定義的攔截檔案上傳攔截器這是可通過org.apache.struts2.interceptor.FileUploadInterceptor類的defaultStack中的一部分。仍然可以使用在struts.xml中設定各種引數,我們將在下面看到。

檢視檔案index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>My JSP 'index.jsp' starting page</title>

    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->

  </head>

  <body>
 <form action="Upload.action" method="post" enctype="multipart/form-data">
      <label for="myFile">你要上傳的檔案</label>
      <input type="file" name="myFile" /><br>

      <input type="submit" value="上傳"/>
   </form>
  </body>
</html>

在上面的例子中值得注意幾點說明。首先,表單的enctype屬性設定為multipart/ form-data。這應該是設定為使得處理檔案上傳檔案上傳。下一個點值得注意的是表單的 action方法上傳和檔案上傳欄位的名稱 – myFile。我們需要這些資訊建立操作方法和struts配置。

接下來讓我們建立一個簡單的 jsp 檔案的success.jsp 結果顯示我們的檔案上傳的情況下成功。

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>檔案上傳</title>
</head>
<body>
成功
</body>
</html>

建立action類: 處理上傳檔案

package com.oumyye.FileUpload;

import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import com.opensymphony.xwork2.ActionSupport;

public class FileUploadAction extends ActionSupport{
        private File myFile;
       private String myFileContentType;
       private String myFileFileName;
       private String destPath;
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    @Override
    public String execute() throws Exception {
        // TODO Auto-generated method stub
         destPath = "e:/upload/"; 
          try{
              System.out.println("Src File name: " + myFile);  
              System.out.println("我的檔名"+myFileFileName);
              System.out.println("我的檔案型別"+ myFileContentType);
              File destFile  = new File(destPath, myFileFileName);
             FileUtils.copyFile(myFile, destFile);
          }catch(IOException e){
             e.printStackTrace();
             return ERROR;
          }
        return SUCCESS;
    }
    public File getMyFile() {
        return myFile;
    }
    public void setMyFile(File myFile) {
        this.myFile = myFile;
    }
    public String getMyFileContentType() {
        return myFileContentType;
    }
    public void setMyFileContentType(String myFileContentType) {
        this.myFileContentType = myFileContentType;
    }
    public String getMyFileFileName() {
        return myFileFileName;
    }
    public void setMyFileFileName(String myFileFileName) {
        this.myFileFileName = myFileFileName;
    }
    public String getDestPath() {
        return destPath;
    }
    public void setDestPath(String destPath) {
        this.destPath = destPath;
    }
    public static long getSerialversionuid() {
        return serialVersionUID;
    }
}

配置檔案:

可以使用恆定的標籤在應用程式 struts.xml檔案,像我一樣改變要上傳的檔案的最大大小。讓我們有我們的在struts.xml如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
    <constant name="struts.devMode" value="false" />
    <!-- 指定每次請求到達,重新載入資原始檔 -->
    <constant name="struts.i18n.reload" value="true" />
    <!-- 指定每次配置檔案更改後,自動重新載入 -->
    <constant name="struts.configuration.xml.reload" value="true" />
    <!-- 把主題配置為simple -->
    <constant name="struts.ui.theme" value="simple" />

    <!-- 指定允許上傳的檔案最大位元組數。預設值是2097152(2M) -->
    <constant name="struts.multipart.maxSize" value="10701096" />
<!--檔案上傳-->
    <package name="upload" namespace="/" extends="struts-default">
        <action name="Upload" class="com.oumyye.FileUpload.FileUploadAction">
            <result name="success">/success.jsp</result>
            <result name="input">/index.jsp</result>
        </action>

<!--檔案下載-->
         <action name="FileDownload" class="com.oumyye.action.FileDownload">  
           <result name="success" type="stream">  
               <param name="contentType">text/plain</param>  
               <param name="contentDisposition">attachment;fileName="${fileName}"</param>  
               <param name="inputName">downloadFile</param>  
               <param name="bufferSize">1024</param>  
           </result>  
       </action>  
    </package>
</struts>

以下是web.xml檔案中的內容,與Struts2的基本配置一樣

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>Struts2_1000_FileUpload</display-name>
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>
</web-app>

上述程式碼即可完成檔案上傳

檔案下載

檢視檔案filedownload.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>檔案下載</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>
  <body>
    <h2>檔案下載內容:</h2><br/>
    Dream.jpg:<a href="FileDownload.action">點選下載</a><br/>
  </body>
</html>

建立action類: 處理上傳檔案,

package com.oumyye.action;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;

//檔案下載
public class FileDownload extends ActionSupport{
    private String fileName;
    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
    //返回一個輸入流,作為一個客戶端來說是一個輸入流,但對於伺服器端是一個 輸出流
    public InputStream getDownloadFile() throws Exception
    {

           this.fileName = "hello.jpg" ;
           //獲取資源路徑
           return ServletActionContext.getServletContext().getResourceAsStream("upload/"+this.fileName) ;
        }
    @Override
    public String execute() throws Exception {   
        return SUCCESS;
    }

}

配置檔案同上

下載時可能會出現錯誤

Can not find a java.io.InputStream with the name [downloadFile] in the invocation stack. Check the <param name="inputName"> tag specified for this action.

可能的原因:

1.檔案路徑不對,根本就沒有取到檔案。這種情況下,可以將獲得InputStream的那條語句放在system.out.println()中輸出一下,若為null,那就是路徑不對了,或者說得準確些就根本沒有找到檔案。

2.在action中沒有寫配置檔案中”<param name=”inputName”>”後面屬性的那個get方法.

相關文章