根据这篇文章Show progress percentage of h:inputFile upload,我想创建包含多个文件的上传页面。
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head>
<title>About</title>
<script type="text/javascript">
function progressBar(data) {
if (data.status == "begin") {
document.getElementById("progressBarId").style.display = "block";
}
else if (data.status == "complete") {
document.getElementById("progressBarId").style.display = "none";
}
}
function updateProgressBar(percent) {
var emptyColor = "#cccccc";
var progressColor = "#3333cc";
document.getElementById("progressBarId").style.background = "linear-gradient(to right, " + progressColor + " 0%, " + progressColor + " " + percent + "%, " + emptyColor + " " + percent + "%, " + emptyColor + " 100%)";
}
</script>
</h:head>
<h:body>
<f:websocket channel="uploadProgress" scope="view" onmessage="updateProgressBar" />
<h:messages id="uploadMsgId" globalOnly="true" showDetail="false" showSummary="true" style="color:red"/>
<h:form id="uploadFormId" enctype="multipart/form-data">
<h:inputFile id="fileToUpload" required="true" requiredMessage="No file selected ..." value="#{uploadBean.file}"/>
<h:message showDetail="false" showSummary="true" for="fileToUpload" style="color:red"/>
<h:commandButton value="Upload" action="#{uploadBean.upload()}">
<f:ajax execute="fileToUpload" onevent="progressBar" render=":uploadMsgId @form"/>
</h:commandButton>
</h:form>
<div>
<div id="progressBarId" style="display: none; width: 250px; height: 23px; border: 1px solid black;" width="250px;" height="23"/>
</div>
</h:body>
</html>
豆:
package com.crm.web.accounts;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.push.Push;
import javax.faces.push.PushContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.http.Part;
@Named
@RequestScoped
public class UploadBean
{
@Inject
@Push
private PushContext uploadProgress;
private static final Logger logger = Logger.getLogger(UploadBean.class.getName());
private Part file;
public Part getFile()
{
return file;
}
public void setFile(Part file)
{
this.file = file;
}
public void upload()
{
if (file != null)
{
logger.info("File Details:");
logger.log(Level.INFO, "File name:{0}", file.getName());
logger.log(Level.INFO, "Content type:{0}", file.getContentType());
logger.log(Level.INFO, "Submitted file name:{0}", file.getSubmittedFileName());
logger.log(Level.INFO, "File size:{0}", file.getSize());
try (InputStream inputStream = file.getInputStream(); FileOutputStream outputStream = new FileOutputStream("C:" + File.separator + "jsf_files_test_for_delete" + File.separator + file.getSubmittedFileName()))
{
long lastTimestamp = System.currentTimeMillis();
int pushInterval = 1000;
long totalRead = 0;
long size = file.getSize();
int bytesRead = 0;
final byte[] chunck = new byte[1024];
while ((bytesRead = inputStream.read(chunck)) != -1)
{
outputStream.write(chunck, 0, bytesRead);
totalRead += bytesRead;
if (System.currentTimeMillis() > lastTimestamp + pushInterval)
{
lastTimestamp = System.currentTimeMillis();
uploadProgress.send(100.0 * totalRead / size); // Make sure this isn't sent more often than once per second.
}
}
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Upload successfully ended!"));
}
catch (IOException e)
{
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Upload failed!"));
}
}
}
}
例如,当我选择带有“浏览”按钮的文件并单击“上传”按钮时,我希望能够上传其他几个。用JSF 2.3实现这个的正确方法是什么?