繁体   English   中英

在 p:graphicImage 预览中显示 p:fileupload 图像而不保存

[英]Display p:fileupload image in p:graphicImage preview without saving it

我正在使用 PrimeFaces 5.3 <p:fileUpload>上传 PNG 图像,我想在保存到数据库之前在<p:graphicImage>显示它的预览。

这是一个 MCVE:

<h:form enctype="multipart/form-data">
    <p:fileUpload value="#{bean.uploadedFile}" mode="simple" />
    <p:graphicImage value="#{bean.image}" />
    <p:commandButton action="#{bean.preview}" ajax="false" value="Preview" />
</h:form>

private UploadedFile uploadedFile;

public UploadedFile getUploadedFile() {
    return uploadedFile;
}

public void setUploadedFile(UploadedFile uploadedFile) {
    this.uploadedFile = uploadedFile;
}

public void preview() {
    // NOOP for now.
}

public StreamedContent getImage() {
    if (uploadedFile == null) {
        return new DefaultStreamedContent(); 
    } else {
        return new DefaultStreamedContent(new ByteArrayInputStream(uploadedFile.getContents()), "image/png"); 
    }
}

backing bean 没有发生错误,图像不会在前端加载和显示。 客户端提到图像返回了 404 not found 错误。

你的问题有两个方面。 它失败是因为上传的文件内容是请求范围的,并且图像是在不同的 HTTP 请求中请求的。 为了更好地理解内部工作,请仔细阅读以下相关问答的答案:

解决第一个问题,需要在表单提交关联的action方法中立即读取上传的文件内容。 在您的具体情况下,这看起来像:

private UploadedFile uploadedFile;
private byte[] fileContents;

public void preview() {
    fileContents = uploadedFile.getContents();
}

// ...

要解决第二个问题,最好的办法是使用数据 URI 方案。 这使得可以在完全相同的响应中直接渲染图像,因此您可以安全地使用@ViewScoped bean,而不会面临“上下文不活动”问题或将byte[]保存在会话或磁盘中以便在不同的请求。 浏览器对数据 URI 方案的支持目前非常好。 将整个<p:graphicImage>替换为以下内容:

<ui:fragment rendered="#{not empty bean.uploadedFile}">
    <img src="data:image/png;base64,#{bean.imageContentsAsBase64}" />
</ui:fragment>

public String getImageContentsAsBase64() {
    return Base64.getEncoder().encodeToString(imageContents);
}

注意:我假设您可以使用 Java 8,因为java.util.Base64仅在该版本中引入。 如果您使用的是较旧的 Java 版本,请改用DatatypeConverter.printBase64Binary(imageContents)

如果您碰巧使用 JSF 实用程序库OmniFaces ,您也可以只使用它的<o:graphicImage>组件代替,这与能够直接引用byte[]InputStream bean 属性并呈现数据的<p:graphicImage>相反URI。

<o:graphicImage value="#{bean.imageContents}" dataURI="true" rendered="#{not empty bean.imageContents}">

暂无
暂无

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

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