簡體   English   中英

在帶有struts2的同一頁面上用進度條上傳文件

[英]Upload file with progressbar in the same page with struts2

我需要上傳非常重的文件,這就是為什么進度條在同一頁面上。 我已經搜索了很多東西,但是execAndWait interceptor器對我不起作用,因為它將進度條放在中間頁面上。 因此,我提出了自己的想法,如下所示:

subirArchivoNomina.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sj" uri="/struts-jquery-tags" %>
<%@ taglib prefix="sb" uri="/struts-bootstrap-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <s:head />
    <sj:head jqueryui="true" jquerytheme="cupertino" />
    <sb:head/>
    <link rel="stylesheet" type="text/css" href="vista/css/subirArchivos.css">
    <script type="text/javascript" src="vista/js_libs/bootstrap-filestyle.js"></script>
    <script type="text/javascript" src="vista/js/subirArchivoNomina.js"></script>
    <title><s:property value="%{getText('conciliacion.de.nomina')}"/></title>
</head>
<body>
    <s:form id="form" action="procesarNomina" cssClass="form-horizontal" method="post" enctype="multipart/form-data">
    <div class="row">
        <div class="col-md-4">
            <s:file type="file" class="filestyle" data-buttonBefore="true" id="fileNomina" name="fileNomina" data-text="%{getText('examinar')}" ></s:file>
        </div>
        <div class="col-md-3">
            <sj:progressbar id="progressbarchange" value="21" onChangeTopics="mychangetopic"/> <br /> 
            <sj:a href="#" onClickTopics="myclicktopic" cssClass="buttonlink ui-state-default ui-corner-all">
            <span class="ui-icon ui-icon-refresh"></span>change value</sj:a>
        </div>
    </div>
    <div class="row">
        <div class="col-md-10">
            <s:submit id="btn_subir" button="true" value="%{getText('subir.archivos')}"  class="simple ui-button ui-corner-all ui-widget"   />
        </div>
    </div>
</body>
</html>

subirArchivoNomina.js

$(document).ready( function(){
    $(":file").filestyle();
    $("#btn_subir").on('click', function(event) {
        event.preventDefault();
        console.log("llegue");
        idInterval=setInterval(function(){
            $.ajax({
                url: "corriendo",
                //data: formData,
                type: "POST",
                processData: false,
                contentType: false
            }).done(function (data, textStatus, jqXHR) {
                console.log(data);//siempre es 0//always is 0
                $("#progressbarchange").progressbar( 'value' , parseInt( data ) );
            }).fail(function (jqXHR, textStatus, errorThrown) {
                //alert("error\njqXHR=" + jqXHR + "\nstatus=" + textStatus + "\nerror=" + errorThrown);
                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);
            }).always(function(dataORjqXHR, textStatus, jqXHR_ORerrorThrown) {
                //alert( "complete" );
            });
        }, 500*10);
        var formData = new FormData();
        var archivo = document.getElementsByName("fileNomina");
        formData.append("fileNomina", archivo[0].files[0]);
        console.log("action="+$("#form").attr("action"));
        $.ajax({
            url: $("#form").attr("action"),
            data: formData,
            type: "POST",
            processData: false,
            contentType: false
        }).done(function (data, textStatus, jqXHR) {
            clearInterval(idInterval);
            console.log(data);
        }).fail(function (jqXHR, textStatus, errorThrown) {
            alert("error\njqXHR=" + jqXHR + "\nstatus=" + textStatus + "\nerror=" + errorThrown);
        }).always(function(dataORjqXHR, textStatus, jqXHR_ORerrorThrown) {
            //alert( "complete" );
        });
    });
    $.subscribe('mychangetopic', function(event,data){
        console.log("progressbar= "+$("#progressbarchange").progressbar('option', 'value'));
    }); 
    $.subscribe('myclicktopic', function(event,data) {
        $("#progressbarchange").progressbar( 'value' , parseInt( Math.random() * ( 90 ) ) );
    });
});

這里是主要思想:從javascript我執行一個動作corriendo ,它會告訴我從文件上載了什么百分比(porcentaje),這就是為什么它在setInterval原因,因為它必須定期執行,然后使用另一個ajax上傳文件。

struts.xml

//...
<action name="procesarNomina" class="mx.unam.patronato.conciliacion.actions.SubirNominaAction">
            <interceptor-ref name="fileUpload">
                <param name="maximumSize">52428800</param><!--  50 MB por archivo-->
                <param name="allowedTypes">text/plain, application/rtf, application/msword</param>
            </interceptor-ref>
            <interceptor-ref name="defaultStack"/>
            <result name="success" type="tiles">.subirNominaSinMenu</result>
            <result name="input" type="tiles">.subirNominaSinMenu</result>
        </action>
        <action name="corriendo" class="mx.unam.patronato.conciliacion.actions.SubirNominaAction" method="getStreamPorcentaje">
            <result type="stream">
                <param name="contentType">text/plain</param>
            </result>
        </action>
//...

subirNominaAction.java

public class SubirNominaAction extends ActionSupport implements SessionAware,ServletRequestAware {
    private SessionMap<String, Object> sessionMap;
    private String fechaInicio,fechaFin;
    private HttpServletRequest request;
    private List<File> fileNomina=new ArrayList<File>();
    private List<String> fileNominaContentType=new ArrayList<String>();
    private List<String> fileNominaFileName=new ArrayList<String>();
    private Double porcentaje;
    private InputStream inputStream;
    public SubirNominaAction() {
        setPorcentaje(0.0);
    }
    //getters y setters
    public String getStreamPorcentaje() {
        inputStream = new ByteArrayInputStream(getPorcentaje().toString().getBytes(StandardCharsets.UTF_8));
        return SUCCESS;
    }
    @Override
    public String execute() throws Exception {
        //System.out.println("entre:"+fechaInicio);
        System.out.print("\n\n---------------------------------------");
        int i=0;
        for (File file : fileNomina){
            double tamanoArchivo=(int)file.length();
            double bytesLine=0;
            int k=0;
            try (Stream<String> lines = Files.lines(Paths.get(file.toURI()), StandardCharsets.ISO_8859_1)){
                for(String line : (Iterable<String>) lines::iterator){
                    bytesLine+=line.getBytes().length;
                    setPorcentaje(bytesLine/tamanoArchivo*100);
                    //System.out.println(getPorcentaje());
                    System.out.println(k+"\t"+line);
                    //System.out.println(line.getBytes().length);
                    k++;
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
            System.out.print("\nFile ["+i+"] ");
            System.out.print("; name:"         + fileNominaFileName.get(i));
            System.out.print("; contentType: " + fileNominaContentType.get(i));
            System.out.print("; length: "      + file.length());
            i++;
        }
        System.out.println("\n---------------------------------------\n");
        return SUCCESS;
    }
}

subirNominaAction.java我讀取了文件的總數,然后subirNominaAction.java讀取了該文件percentage(porcentaje) 通過控制台印象,文件可以正確上傳並且percentage(porcentaje)也可以正確計算。 問題在於,在 setInterval 中聲明它調用動作 corriendo 並依次調用 getStreamPercentaje它始終返回0 這就是我需要更新進度條的值:

console.log(data);//siempre es 0//always is 0
$("#progressbarchange").progressbar( 'value' , parseInt( data ) );

有誰知道如何糾正它? 似乎每次調用動作類都會創建一個新實例,並且它不會使用已經在運行的實例。

或者在他的缺陷中,有人舉了一個例子,說明如何使用interceptor execAndWait與同一頁面中的進度interceptor execAndWait一起使用它?

上傳進度條與strut無關。 您必須在瀏覽器端處理更多的JavaScript事情。 通常,struts將在服務器完全接收到完整的上傳文件后將其獲取。 因此您的方法將始終返回0,因為該文件尚不存在。

使用當前的ajax請求,您仍然可以一次上傳文件,並且在上傳過程中沒有任何反饋。

因此,您需要某種javascript,它可以告訴您有關上傳的當前狀態。 有像這樣的庫,甚至還有(一些新的)現代javascript函數(例如XMLHttpRequest高級功能)都可以為您提供幫助。 甚至可以對您希望上傳的文件( jquery plugin )進行分塊,但是我從未用struts對此進行過測試。

希望這些鏈接能對您有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM