简体   繁体   English

使用JSF上载两个文件的结果是相同文件的两倍

[英]uploading two files with JSF results in two times the same file

I have a JSF page + Bean to upload a file and preview the result (it's for images). 我有一个JSF页面+ Bean,可以上传文件并预览结果(用于图像)。 In the bean the upload method puts the data ( base64 ) in a list and the JSF page loops through the list to display the images. 在bean中,上载方法将数据( base64 )放在列表​​中,而JSF页面循环遍历该列表以显示图像。

So far it works as expected for the first image. 到目前为止,它对第一张图片的效果令人满意。 But when I upload a second image there are two things that might go wrong: 但是,当我上传第二张图片时,可能会出错两件事:

  • the first image gets uploaded again instead 第一张图片会再次上传
  • Or, with a little change in the code the second image does not get uploaded at all until I reselect the file again and upload it. 或者,在代码中稍作更改,直到我再次重新选择文件并上传之前,第二张图片根本不会上传。

JSF page JSF页面

<h:form enctype="multipart/form-data" id="uploadForm" prependId="false">

    <!-- here I loop through the list to preview the images -->
    <c:forEach var="image" items="#{bean.imageList}">
        <h:graphicImage value="#{image}" />
    </c:forEach>

    <!-- that's the upload -->
    <h:inputFile id="file" value="#{bean.uploadedFile}" />
    <h:commandButton value="submit" action="#{bean.uploadFile}" />
</h:form>

bean 豆角,扁豆

private Part uploadedFile;                // the Part with the uploaded file
private ArrayList<String> imageList;      // the list of images (base64 encoded)

public void uploadFile() throws IOException{
    if(null != uploadedFile){
        String imageType = "data:" + uploadedFile.getContentType() + ";base64,";    // will be something like: "data:image/png;base64,"
        InputStream inputStream = uploadedFile.getInputStream();  // getting the inputStream from the Part
        byte[] imageData;                  // array to but the image data
        try(BufferedInputStream bis = new BufferedInputStream(inputStream)){          // converting the inputStream to a buffered one
            imageData = new byte[bis.available()];        // initializing the byte array with the right size
            bis.read(imageData);           // reading / writing the image data

            // HERE: if I comment out the next line, the second upload will upload the first image again.
            // but if I set the Part to null, the second upload will result in nothing (page reloads, no data uploaded) and I have to upload it again
            uploadedFile = null;
        }
        imageList.add(imageType + javax.xml.bind.DatatypeConverter.printBase64Binary(imageData));    // this adds the base64 image string to the list of images
    }
}

My bean is @ViewScoped (I need it to be that way for other things). 我的bean是@ViewScoped (对于其他事情,我需要这样)。

So my guess was that the Part uploadedFile just didn't get the new image data for the second file, but as I said, when setting it to null it just skips the second upload process. 所以我的猜测是, Part uploadedFile只是没有获得第二个文件的新图像数据,但是正如我所说的,当将其设置为null它会跳过第二个上传过程。

Does anyone see what I am doing wrong? 有人看到我在做什么错吗?

You might try the following. 您可以尝试以下方法。

    byte[] imageData = new byte[uploadedFile.getSize()];
    try (BufferedInputStream bis = new BufferedInputStream(inputStream)) {
        bis.read(imageData);
        uploadedFile.delete();
    }
  • Using Part.getSize() 使用Part.getSize()
  • Not relying on available() which makes no guarantee that all is available 不依赖available()不能保证所有内容都可用
  • Using delete() to clear the bean 使用delete()清除bean

(Not tried it myself.) (我自己没有尝试过。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM