好吧,我做错了什么?我尝试使用图像预览创建简单的图像上传器。我的数据库中有一个产品,带有一些名称、描述等。还有图像。我的目标是为经理用户创建编辑(然后添加)表单。我创建了一个bean:
package pl.jedenpies.sklep.beans;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.imageio.ImageIO;
import org.primefaces.event.FileUploadEvent;
import pl.jedenpies.sklep.dto.Image;
import pl.jedenpies.sklep.utils.ImageUtil;
@ViewScoped @ManagedBean(name = "editProductForm")
public class NewEditProductForm {
private Image currentThumbnail;
private Image uploadedImage;
private Image uploadedThumbnail;
public void save() {
System.out.println("Saved");
}
public void handleFileUpload(FileUploadEvent event) throws IOException {
BufferedImage originalImage = ImageIO.read(event.getFile().getInputstream());
BufferedImage thumbnail = ImageUtil.makeThumbnail(originalImage);
setUploadedImage(originalImage);
setUploadedThumbnail(thumbnail);
}
public Image getCurrentThumbnail() {
return currentThumbnail;
}
public void setCurrentThumbnail(BufferedImage currentThumbnail) {
this.currentThumbnail = new Image(currentThumbnail);
}
public Image getUploadedImage() {
return uploadedImage;
}
public void setUploadedImage(BufferedImage uploadedImage) {
this.uploadedImage = new Image(uploadedImage);
}
public Image getUploadedThumbnail() {
return uploadedThumbnail;
}
public void setUploadedThumbnail(BufferedImage uploadedThumbnail) {
this.uploadedThumbnail = new Image(uploadedThumbnail);
}
}
其中 Image 是一个包装 BufferedImage 并允许创建 StreamedContent 对象的类:
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.primefaces.model.DefaultStreamedContent;
public class Image {
private BufferedImage image;
public Image() {}
public Image(BufferedImage image) {
this.image = image;
}
public DefaultStreamedContent stream() throws IOException {
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
return new DefaultStreamedContent();
}
if (image == null) return null;
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "png", os);
ByteArrayInputStream bais = new ByteArrayInputStream(os.toByteArray());
return new DefaultStreamedContent(bais, "image/png");
}
}
我的 xhtml 页面是:
<h:form id="editProductForm">
<div class="form" style="width: 830px;">
<p:panel id="imageUploader">
<c:if test="#{editProductForm.currentThumbnail != null}">
<p:graphicImage
styleClass="thumbnail"
id="currentThumbnail" value="#{editProductForm.currentThumbnail.stream()}" cache="false" />
</c:if>
<c:if test="#{editProductForm.currentThumbnail == null}">
<p:graphicImage
value="/resources/images/logo-plaskie-duze.png"
styleClass="thumbnail" />
</c:if>
<c:if test="#{editProductForm.uploadedThumbnail != null}">
<p:graphicImage
styleClass="thumbnail"
id="uploadedThumbnail" value="#{editProductForm.uploadedThumbnail.stream()}" cache="false" />
</c:if>
<c:if test="#{editProductForm.uploadedThumbnail == null}">
<p:graphicImage
styleClass="thumbnail empty"
id="uploadedThumbnail" />
</c:if>
<p:fileUpload
style="border: 1px solid green;"
fileUploadListener="#{editProductForm.handleFileUpload}"
auto="true"
update=":editProductForm:imageUploader"
mode="advanced"
dragDropSupport="true"
sizeLimit="20000000" allowTypes="/(\.|\/)(gif|jpe?g|png)$/">
</p:fileUpload>
</p:panel>
</div>
</h:form>
当我尝试使用我的新表单时,没有显示新上传的图像。当我将范围更改为@SessionScoped 时,它可以工作。但我对使这个 bean 会话的范围不感兴趣。它甚至可以与视图范围一起使用吗?或者也许我只需要以这种或另一种方式保持图像在会话中?
正如@BalusC 建议的那样,我尝试了“特殊的getter 方法”(我之前也尝试过),但没有结果。当我将范围设置为查看时,方法stream()
会被调用一次,PhaseId.RENDER_RESPONSE
然后我就会22:10:22,816 SEVERE [org.primefaces.application.resource.StreamedContentHandler] (default task-58) Error in streaming dynamic resource. null
进入我的日志。