Jsf 流关闭异常

Jsf 流关闭异常,jsf,primefaces,filestream,graphicimage,Jsf,Primefaces,Filestream,Graphicimage,当我要保存上传的图像时,我得到了流关闭异常。 我正在尝试在保存之前预览上传图像的graphicImage。此操作正在运行。但我无法保存图像。这是我的密码: private InputStream in; private StreamedContent filePreview; // getters and setters public void upload(FileUploadEvent event)throws IOException { // Folder Creation f

当我要保存上传的图像时,我得到了流关闭异常。 我正在尝试在保存之前预览上传图像的
graphicImage
。此操作正在运行。但我无法保存图像。这是我的密码:

private InputStream in;
private StreamedContent filePreview;
// getters and setters

public void upload(FileUploadEvent event)throws IOException { 
    // Folder Creation for upload and Download
    File folderForUpload = new File(destination);//for Windows
    folderForUpload.mkdir();
    file = new File(event.getFile().getFileName());
    in = event.getFile().getInputstream();
    filePreview = new DefaultStreamedContent(in,"image/jpeg");
    FacesMessage msg = new FacesMessage("Success! ", event.getFile().getFileName() + " is uploaded.");  
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

public void setFilePreview(StreamedContent fileDownload) {
    this.filePreview = fileDownload;
}

public StreamedContent getFilePreview() {
    return filePreview;
}

public void saveCompanyController()throws IOException{
    OutputStream out  = new FileOutputStream(getFile());
    byte buf[] = new byte[1024];
    int len;
    while ((len = in.read(buf)) > 0)
        out.write(buf, 0, len);
    FileMasterDO fileMasterDO=new FileMasterDO();
    fileMasterDO.setFileName(getFile().getName());
    fileMasterDO.setFilePath(destination +file.getName());
    fileMasterDO.setUserMasterDO(userMasterService.findUserId(UserBean.getUserId()));
    fileMasterDO.setUpdateTimeStamp(new Date());
    in.close();
    out.flush();
    out.close();
    fileMasterService.save(filemaster);
}

bean在会话作用域中。

您试图读取
InputStream
两次(第一次是在upload方法的
DefaultStreamContent
构造函数中,第二次是在save方法的复制循环中)。这是不可能的。它只能读取一次。您需要首先将其读入
字节[]
,然后将其分配为bean属性,以便可以将其用于
流内容和保存

确保您从不将外部资源(如
InputStream
OutputStream
)作为bean属性持有。在适用的情况下,将它们全部从当前bean和其他bean中删除,并使用
byte[]
将图像的内容作为属性保存

在您的特定情况下,您需要按如下方式修复它:

private byte[] bytes; // No getter+setter!
private StreamedContent filePreview; // Getter only.

public void upload(FileUploadEvent event) throws IOException {
    InputStream input = event.getFile().getInputStream();

    try {
        IOUtils.read(input, bytes);
    } finally {
        IOUtils.closeQuietly(input);
    }

    filePreview = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/jpeg");
    // ...
}

public void saveCompanyController() throws IOException {
    OutputStream output = new FileOutputStream(getFile());

    try {
        IOUtils.write(bytes, output);
    } finally {
        IOUtils.closeQuietly(output);
    }

    // ...
}

注意:
IOUtils
来自ApacheCommons IO,您应该已经在类路径中拥有它,因为它是

的依赖项,您正在尝试读取
输入流两次(第一次在upload方法的
DefaultStreamedContent
构造函数中,第二次在save方法的复制循环中)。这是不可能的。它只能读取一次。您需要将其读入
字节[]
首先,然后将其指定为bean属性,以便您可以将其用于
流内容和保存

请确保您从不将外部资源(如
InputStream
OutputStream
)作为bean属性保存。如果适用,请将它们全部从当前和其他bean中删除,并使用
byte[]
将图像内容作为属性保存

在您的特定情况下,您需要按如下方式修复它:

private byte[] bytes; // No getter+setter!
private StreamedContent filePreview; // Getter only.

public void upload(FileUploadEvent event) throws IOException {
    InputStream input = event.getFile().getInputStream();

    try {
        IOUtils.read(input, bytes);
    } finally {
        IOUtils.closeQuietly(input);
    }

    filePreview = new DefaultStreamedContent(new ByteArrayInputStream(bytes), "image/jpeg");
    // ...
}

public void saveCompanyController() throws IOException {
    OutputStream output = new FileOutputStream(getFile());

    try {
        IOUtils.write(bytes, output);
    } finally {
        IOUtils.closeQuietly(output);
    }

    // ...
}

注意:
IOUtils
来自Apache Commons IO,您应该已经在类路径中拥有它,因为它是

的依赖项。我不打算将图像保存在数据库中。我只需要保存路径。我不确定此注释与问题和答案有什么关系。您了解具体问题吗?正在阅读g一个
InputStream
两次(一次在
upload()
方法中,一次在
saveCompanyController()
方法中)。这是不可能的。只能读取一次。将其读入
字节[]
然后您可以阅读/重复使用任意次数。我用一个具体的启动示例扩展了答案,说明了如何正确修复。我不打算将图像保存在数据库中。只需保存路径。我不确定此注释与问题和答案有何关系。您了解具体问题吗?您正在阅读
InputStream
两次(一次在
upload()
方法中,一次在
saveCompanyController()
方法中)。这是不可能的。只能读取一次。将其读入
字节[]
然后您可以根据需要多次读取/重用它。我用一个具体的启动示例扩展了答案,说明了如何正确修复它。