From: Polin Wei

經實作測試,可以正常運作。故記錄之.....

環境:

struts2: 2.3.16.3

freemarker: 2.3.19

Bootstrap: 3.2.0

commons-fileupload: 1.3.1

commons-io:2.4

jQuery-File-Upload: 9.10.0

 

上傳前劃面

 upload-1.png  

上傳後劃面

upload2.png

 

Struts2 結合 jQuery-File-Upload 的實作如下:

step 01: pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gu</groupId>
  <artifactId>GUSSH</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>gussh</name>
  <dependencies>
          <dependency>
              <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
          </dependency>
          <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.2.15.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.2.15.Final</version>
        </dependency>
        
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>2.3.16.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-spring-plugin</artifactId>
            <version>2.3.16.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-json-plugin</artifactId>
            <version>2.3.16.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-config-browser-plugin</artifactId>
            <version>2.3.16.3</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.0</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>commons-digester</groupId>
            <artifactId>commons-digester</artifactId>
            <version>1.7</version>
        </dependency>
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>p6spy</groupId>
            <artifactId>p6spy</artifactId>
            <version>1.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.0.1-FINAL</version>
        </dependency>
        <dependency>
            <groupId>quartz</groupId>
            <artifactId>quartz</artifactId>
            <version>1.5.2</version>
        </dependency>
        
        <dependency>
            <groupId>stax</groupId>
            <artifactId>stax</artifactId>
            <version>1.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml</groupId>
            <artifactId>saaj-impl</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.stream</groupId>
            <artifactId>sjsxp</artifactId>
            <version>1.0.1</version>
        </dependency>
        
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>wsdl4j</groupId>
            <artifactId>wsdl4j</artifactId>
            <version>1.5.1</version>
        </dependency>
        <dependency>
            <groupId>oro</groupId>
            <artifactId>oro</artifactId>
            <version>2.0.8</version>
        </dependency>
        <dependency>
            <groupId>jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>1.3.4</version>
        </dependency>
        <dependency>
            <groupId>jfree</groupId>
            <artifactId>jfreechart</artifactId>
            <version>1.0.9</version>
        </dependency>
        <dependency>
            <groupId>jfree</groupId>
            <artifactId>jfreechart-experimental</artifactId>
            <version>1.0.9</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>
        
        <dependency>
            <groupId>net.sf.barcode4j</groupId>
            <artifactId>barcode4j</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>net.sf.morph</groupId>
            <artifactId>morph</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils-bean-collections</artifactId>
            <version>1.7.0</version>
        </dependency>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.5.3</version>
        </dependency>
        <dependency>
            <groupId>axis</groupId>
            <artifactId>axis</artifactId>
            <version>1.4</version>
        </dependency>
        
        <dependency>
            <groupId>com.keypoint</groupId>
            <artifactId>png-encoder</artifactId>
            <version>1.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib-nodep</artifactId>
            <version>2.1_3</version>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>jsr250-api</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>1.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>jta</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>javax.mail</artifactId>
            <version>1.5.2</version>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.jexcelapi</groupId>
            <artifactId>jxl</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>commons-javaflow</groupId>
            <artifactId>commons-javaflow</artifactId>
            <version>20060411</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/commons-javaflow-20060411.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>net.sourceforge.barbecue</groupId>
            <artifactId>barbecue</artifactId>
            <version>1.1</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/barbecue-1.1.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>lotus.sametime</groupId>
            <artifactId>STComm</artifactId>
            <version>1.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/STComm.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>lotus.sametime</groupId>
            <artifactId>NCSO</artifactId>
            <version>1.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/NCSO.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>lotus.sametime</groupId>
            <artifactId>CommRes</artifactId>
            <version>1.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/CommRes.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>com.wnjsoft.dlp</groupId>
            <artifactId>ds-orgimport</artifactId>
            <version>1.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/ds-orgimport.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>com.wnjsoft.dlp</groupId>
            <artifactId>ds-userimport</artifactId>
            <version>1.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/ds-userimport.jar</systemPath>
        </dependency>

        <dependency>
            <groupId>com.ds.globeunion.wfclient</groupId>
            <artifactId>ds-wf-client</artifactId>
            <version>1.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/ds-wf-client.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>jasperreports</groupId>
            <artifactId>ireport</artifactId>
            <version>2.0.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/iReport.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc14</artifactId>
            <version>10.2.0.3.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/ojdbc14.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc14_g</artifactId>
            <version>10.2.0.3.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/ojdbc14_g.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.sun.xml</groupId>
            <artifactId>saaj-coms</artifactId>
            <version>1.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/saaj-coms.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.gu.apps</groupId>
            <artifactId>gu-taglibs</artifactId>
            <version>1.0.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/gu-taglibs-1.0.0.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>javax.sql</groupId>
            <artifactId>jdbc-stdext</artifactId>
            <version>2.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/webapp/WEB-INF/lib/jdbc2_0-stdext.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.jgeppert.struts2.bootstrap</groupId>
            <artifactId>struts2-bootstrap-plugin</artifactId>
            <version>2.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.jgeppert.struts2.jquery</groupId>
            <artifactId>struts2-jquery-plugin</artifactId>
            <version>3.7.1</version>
        </dependency>
        <dependency>
            <groupId>com.ckeditor</groupId>
            <artifactId>ckeditor-java-core</artifactId>
            <version>3.5.3</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
  </dependencies>
</project>

 

step 02: struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
      
<struts>

     <!-- devMode is helpful when you want some extra logs for debugging -->
     <constant name="struts.devMode" value="false" />
     <constant name="struts.i18n.encoding" value="UTF-8" />
     <!-- Global message resource;
         Otherwise you will have seperate message resource for each Action
     -->
     <constant name="struts.custom.i18n.resources" value="com.gussh.sc.messages.messages" />
     <constant name="struts.enable.DynamicMethodInvocation" value="true" />
     <constant name="struts.multipart.maxSize" value="1048576000" />
             
     <package name="gussh-default" namespace="/" extends="struts-default,json-default">
     
       <interceptors>
            <interceptor name="authInterceptor" class="com.gussh.AuthInterceptor"></interceptor>
            
               <interceptor-stack name="gussh-stack">
                <interceptor-ref name="fileUpload">
                    <param name="maximumSize">104857600</param>
                </interceptor-ref>
                <interceptor-ref name="authInterceptor" />                    
                <interceptor-ref name="defaultStack"/>
               </interceptor-stack> 
               
       </interceptors>
       <default-interceptor-ref name="gussh-stack"/>
       <default-action-ref name="UnderConstruction"/>
                       
       <global-results>
          <result name="json-output">/gussh/common/json-output.jsp</result>
          <result name="error">/error.jsp</result>
        </global-results>
         
        <global-exception-mappings>
            <exception-mapping exception="java.lang.Exception" result="error"/>            
        </global-exception-mappings>
        
       <action name="UnderConstruction">
           <result>/templates/SSO/GUSSO.jsp</result>
       </action>        
 
        <action name="FileOutput" class="com.gussh.common.utils.FileOutput" >              
            <result name="success" type="stream">
                <param name="contentType">application/octet-stream;charset=ISO8859-1</param>
                <param name="inputName">inputStream</param>
                <!-- 使用經過轉碼的檔名作為下載檔案名,downloadFileName屬性  對應action類中的方法 getDownloadFileName() -->  
                <param name="contentDisposition">attachment;filename="${downloadFileName}"</param>
                <param name="bufferSize">4096</param>                
            </result>  
        </action>        
            
     </package>
    
     <!-- Add addition packages and configuration here. -->
      
</struts>

 

Step03: jsp 頁面

<s:form cssClass="fileupload" name="UsersTagAction" action="UsersTagAction" enctype="multipart/form-data">

...

...

<div class="row fileupload-buttonbar">
    <div class="col-lg-7">
        <!-- The fileinput-button span is used to style the file input field as button -->
        <span class="btn btn-success btn-sm fileinput-button">
            <i class="glyphicon glyphicon-plus" style="font-size: 14px"></i>
            <span><s:text name="common.upload.select" /></span>
            <input type="file" name="file" multiple>                    
        </span>           
        <button type="submit" class="btn btn-primary btn-sm start">
            <i class="glyphicon glyphicon-upload" style="font-size: 14px"></i>
            <span><s:text name="common.upload" /></span>
        </button>
        <button type="reset" class="btn btn-warning btn-sm cancel">
            <i class="glyphicon glyphicon-ban-circle" style="font-size: 14px"></i>
            <span><s:text name="common.upload.cancel" /></span>
        </button>
        <button type="button" class="btn btn-danger btn-sm delete">
            <i class="glyphicon glyphicon-trash" style="font-size: 14px"></i>
            <span><s:text name="common.btn.delete" /></span>
        </button>
        <input type="checkbox" class="toggle">
        <!-- The global file processing state -->
        <span class="fileupload-process"></span>
    </div>
</div>
<!-- The table listing the files available for upload/download -->
<table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>

 

...</s:form>

 

step 04: freemarker(ftl) 頁面, 放在 html 最下面, 以便所有頁面共用

<!-- The template to display files available for upload -->
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-upload fade">
        <td>
            <span class="preview"></span>
        </td>
        <td>
            <p class="name">{%=file.name%}</p>
            <strong class="error text-danger"></strong>
        </td>
        <td class="title"><input name="fileDescription" placeholder="File Description"></td>    
        <td>
            <p class="size">Processing...</p>
            <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="progress-bar progress-bar-success" style="width:0%;"></div></div>
        </td>
        <td>
            {% if (!i && !o.options.autoUpload) { %}
                <button class="btn btn-primary btn-sm start" disabled>
                    <i class="glyphicon glyphicon-upload" style="font-size: 14px"></i>
                    <span style="font-size: 12px">${action.getText('common.upload.select')}</span>
                </button>
            {% } %}
            {% if (!i) { %}
                <button class="btn btn-warning btn-sm cancel">
                    <i class="glyphicon glyphicon-ban-circle" style="font-size: 14px"></i>
                    <span style="font-size: 12px">${action.getText('common.upload.cancel')}</span>
                </button>
            {% } %}
        </td>
    </tr>
{% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-download fade">
        <td>
            <span class="preview">
                {% if (file.thumbnailUrl) { %}
                    <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a>
                {% } %}
            </span>
        </td>
        <td>
            <p class="name">                
                {% if (file.url) { %}
                    <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?'data-gallery':''%}><img src="${request.contextPath}/webTemplate/themes/gussh/images/Download-icon.png"/>{%=file.name%}</a>
                {% } else { %}
                    <span>{%=file.name%}</span>
                {% } %}
            </p>
            {% if (file.error) { %}
                <div><span class="label label-danger">Error</span> {%=file.error%}</div>
            {% } %}
        </td>
        <td>
            <span class="size">{%=o.formatFileSize(file.size)%}</span>
        </td>
        <td>
            {% if (file.deleteUrl) { %}
                <button class="btn btn-danger btn-sm delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
                    <i class="glyphicon glyphicon-trash" style="font-size: 12px"></i>
                    <span>${action.getText('common.btn.delete')}</span>
                </button>
                <input type="checkbox" name="delete" value="1" class="toggle">
            {% } else { %}
                <button class="btn btn-warning btn-sm cancel">
                    <i class="glyphicon glyphicon-ban-circle" style="font-size: 12px"></i>
                    <span>${action.getText('common.upload.cancel')}</span>
                </button>
            {% } %}
        </td>
    </tr>
{% } %}
</script>
    
</body>
</html>

 

Step 05: 處理 file upload 的 class

package com.gussh;


import java.lang.reflect.Method;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.mapper.ActionMapping;

import com.gussh.common.utils.BA_TOOLS;
import com.gussh.common.utils.BA_Validate;
import com.gussh.sc.model.UserInfo;
import com.gussh.spfs.SPFS_TOOLS;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.validator.annotations.DateRangeFieldValidator;
import com.opensymphony.xwork2.validator.validators.EmailValidator;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class BaseSupport extends ActionSupport implements Preparable {
    
    Logger logger = Logger.getLogger(BaseSupport.class);
    private static final long serialVersionUID = 1L;
    
    // 網頁會使用的 request, response, session
    public HttpServletRequest request = ServletActionContext.getRequest();
    public HttpServletResponse response = ServletActionContext.getResponse();
    public Map<String, Object> session = ActionContext.getContext().getSession();


    //處理檔案上傳, 因 jQuery-File-Upload 一次處理一個檔案上傳, 所以不需使用 MultipleFileUploadUsingListAction
    protected File file ;
    protected String fileFileName ;
    protected String fileContentType ;
    protected String fileDescription ;
    
    @Resource(name="BA_TOOLS")
    protected BA_TOOLS baTools;    
    
    public BaseSupport() {
        // TODO Auto-generated constructor stub
    }

    public void prepare() throws Exception {
        // TODO Auto-generated constructor stub
        
    }    


    @Override
    public String execute() throws Exception {
        String reqCode="fileUpload";
            String reqResult="";
            reqResult=doReqCode(reqCode);        
        return reqResult;
    }

    public String fileUpload() {
        String filePath="/upload/";
        try {
            baTools.uploadFileToServer(response, filePath, file, fileFileName, fileContentType, fileDescription);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return super.fileUpload();
    }


    //執行其它自定的 reqCode Function
    public String doReqCode(String reqCode) {
        reqResult=INPUT;
        boolean result = false;
        Method[] methods = this.getClass().getMethods();
        for (int i = 0; i < methods.length; i++) {
            Method method = methods[i];
            if (reqCode.equals(method.getName())) {
                try {
                    reqResult=method.invoke(this).toString();
                    result=true;
                } catch (Exception e) {
                    this.addActionError(reqCode+": "+  getText("msg.system.methodExecuteError"));
                    logger.info(e);                
                }
            }
        }
        if (!result){
            this.addActionError(reqCode+": "+  getText("msg.system.methodNotFound"));
        }
        
        return reqResult;
    }


    //處理檔案上傳
    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 String getFileContentType() {
        return fileContentType;
    }

    public void setFileContentType(String fileContentType) {
        this.fileContentType = fileContentType;
    }

    public String getFileDescription() {
        return fileDescription;
    }

    public void setFileDescription(String fileDescription) {
        this.fileDescription = fileDescription;
    }
    
}

 

Step 06: 公共程式的 class: BA_TOOLS

@Service
@Component("BA_TOOLS")
public class BA_TOOLS extends BaseDataSource {

    static Logger loger = Logger.getLogger(BA_TOOLS.class.getName());
    
    private static final ActionSupport actionSupport = new ActionSupport();
    
    /**
     * 上傳檔案到主機上,並且變更原始檔名為 new Date().getTime() + extension
     * @param filePath 檔案路徑
     * @param file     上傳的實體檔案來源
     * @param fileFileName 上傳的實體檔案檔名
     * @param fileContentType 上傳的實體檔案型態
     * @param fileDescription 上傳的實體檔案說明
     * @return
     * @throws IOException
     */
    public String uploadFileToServer(HttpServletResponse response,String filePath, File file, String fileFileName, String fileContentType, String fileDescription) throws IOException{
        
        String saveFileName = "";
        String showFileDescript = fileDescription.isEmpty()?fileFileName:fileDescription;
        String uploadFileGson="";
        InputStream is = null;
        OutputStream os = null;
        int BUFFER_SIZE = 8 * 1024;
        int fileSize=0;
        
        
        Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();
        Map<String,Object> rowAttribute = new HashMap<String,Object>();
        List<Map<String,Object>> fileAttribute = new ArrayList<Map<String,Object>>();
        Map<String,Object> itemCategory = new HashMap<String,Object>();
        
        String osName = System.getProperty("os.name");
        if (!osName.equals("Linux")) {
            filePath = "C:" + filePath;
        }
        try{
            //檢查是否有此Folder:filePath, 若無則建立
            File filePathIsFolder = new File(filePath);
            if (!filePathIsFolder.isDirectory())
                filePathIsFolder.mkdirs();
            //取得上傳檔案的附檔名
            String extension = "";
            if (fileFileName.indexOf('.') > -1){
                String[] tmp = fileFileName.split("\\.");
                extension = "." + tmp[tmp.length - 1];
            }
            saveFileName = new Date().getTime() + extension;
            
            //開始將檔案讀出並寫入主機            
            is = new FileInputStream(file);
            fileSize=is.available();
            File destFile = new File(filePath, saveFileName);
            os = new FileOutputStream(destFile);
            byte[] buffer = new byte[BUFFER_SIZE];
            while(is.read(buffer)>0){
                os.write(buffer);
            }
            is.close();
            os.close();
            
            //組成 jquery-file-upload 需要的 gson 格式
            itemCategory.put("name", showFileDescript);
            itemCategory.put("size", fileSize);
            itemCategory.put("type", fileContentType);
            itemCategory.put("url", "FileOutput?name="+saveFileName);
            itemCategory.put("deleteUrl", "Index?reqCode=fileDelete&fileFileName="+saveFileName);
            itemCategory.put("deleteType", "POST");
            fileAttribute.add(itemCategory);
            rowAttribute.put("files", fileAttribute);
            
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            if (null!=is){
                is.close();
            }
            if (null!=os){
                os.close();
            }
        }
        //產生 gson 字串
        uploadFileGson=gson.toJson(rowAttribute);
        //回傳 gson 至前端
        gsonOutput(response,uploadFileGson);
        
        return saveFileName;
    }
    
    /**
     * 在前端產生 Gson String
     * @param response
     * @param gsonString
     */
    public void gsonOutput(HttpServletResponse response, String gsonString){
        PrintWriter writer=null;
        response.setContentType("text/html;charset=UTF-8");
        try {
            writer = response.getWriter();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        writer.print(gsonString);
        writer.flush();
        writer.close();        
    }
}       

 

Step 07: 檔案下載的 class: FileOutput

package com.gussh.common.utils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class FileOutput extends ActionSupport {
    
    static Logger logger = Logger.getLogger(FileOutput.class);
    
    @Resource(name="BA_TOOLS")
    protected BA_TOOLS baTools;
    public HttpServletRequest request = ServletActionContext.getRequest();
    public HttpServletResponse response = ServletActionContext.getResponse();
    
    private InputStream inputStream ;
    private String name;    
    
    public InputStream getInputStream() {        
        
        String filenamedownload = "";
        String filePath="/upload/";        
        String osName = System.getProperty("os.name");
        
        if (!osName.equals("Linux")) {
            filePath = "C:" + filePath;
        }
        
        filenamedownload = filePath+ "/" + this.getName();
        
         try{
             File file = new File(filenamedownload);
             if(file.length()>0)
                 inputStream = new FileInputStream(filenamedownload);
             else
                 inputStream = new ByteArrayInputStream("No Files".getBytes());
         }catch(Exception e){
             e.printStackTrace();
         }
        
        
         //return ServletActionContext.getServletContext().getResourceAsStream(filenamedownload);
         return inputStream;
    }
    
    public String execute() throws Exception {    
        return "success";
    }

    public String getDownloadFileName() {   
          
        String downFileName = name;  
        try {  
            downFileName = new String(downFileName.getBytes(), "ISO8859-1");
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        }  
        return downFileName;   
 
    }    
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }       
    
}

 

Step 08: file upload 的 javascript

$(document).ready(function () {
    
    // Initialize the jQuery File Upload widget:
    $('.fileupload').each(function (e, data) {    
        $(this).fileupload({
            dropZone: $(this)            
        });        
        $('#reqCode').val('fileUpload');
    });
    
    /*處理每一個檔案上傳前, 加入單一 fileDescription 的值*/
    $('.fileupload').bind('fileuploadsubmit', function (e, data) {
       
        // 剔除欄位:fileDescription 後, 取得所有要上傳的值
        var allInputs = $( ":input[name!='fileDescription']"  );
        // 抓取 id="template-upload" 裡新增加單一的 input 欄位: fileDescription
        var fileUploadInputs = data.context.find(':input');
        // 兩個 array 再 merge , 就是所有欄位要上傳的所有值
        var inputs = $.merge(allInputs,fileUploadInputs);
        
        if (inputs.filter(function () {
                return !this.value && $(this).prop('required');
            }).first().focus().length) {
            data.context.find('button').prop('disabled', false);
            return false;
        }
        // 上傳的欄位值需要序列化, 才會逐一上傳
        data.formData = inputs.serializeArray();
    });

});

 

大致的作業如上.

 

參考網址:

Setting formData on upload start for each individual file upload

https://struts.apache.org/docs/file-upload.html

 

 

arrow
arrow
    文章標籤
    jQuery-File-Upload Struts2
    全站熱搜

    MIS 發表在 痞客邦 留言(0) 人氣()