[英]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.