我正在使用 <p:fileUpload>
上传图像如下。
<p:outputLabel for="txtCatImage" value="#{messages['category.image']}"/>
<p:fileUpload id="txtCatImage" mode="advanced"
dragDropSupport="true" required="true"
sizeLimit="1000000" fileLimit="1" multiple="false"
cancelLabel="#{messages['fileupolad.cancelLabel']}"
label="#{messages['fileupolad.label']}"
uploadLabel="#{messages['fileupolad.uploadLabel']}"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
invalidFileMessage="#{messages['fileupolad.invalidFileMessage']}"
invalidSizeMessage="#{messages['fileupolad.invalidSizeMessage']}"
fileLimitMessage="#{messages['fileupolad.fileLimitMessage']}"
fileUploadListener="#{categoryManagedBean.fileUploadListener}"/>
<p:message for="txtCatImage" showSummary="false"/>
<p:commandButton id="btnSubmit" update="panel messages"
actionListener="#{categoryManagedBean.insert}"
value="#{messages['button.save']}"/>
fileUploadListener
在相应的托管 bean 中用 @ViewScoped
装饰如下。
//This is just a utility method and can be placed anywhere in the application.
private static boolean validateImageDimensions(byte[] bytes) throws IOException {
BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(bytes));
return bufferedImage.getHeight()>=750 || bufferedImage.getWidth()>=650;
}
public void fileUploadListener(FileUploadEvent event) throws IOException {
UploadedFile uploadedFile = event.getFile();
byte[] bytes = IOUtils.toByteArray(uploadedFile.getInputstream());
if(!Utility.validateImageDimensions(bytes)) {
FacesContext context = FacesContext.getCurrentInstance();
context.validationFailed();
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_FATAL, "Message summary", "Error message");
FacesContext.getCurrentInstance().addMessage(event.getComponent().getClientId(context), message);
}
else {//Do something.}
}
<p:commandButton>
的监听者如果在 fileUploadListener()
中进行验证,则不应调用如下内容:失败。
public void insert() {
//Code to invoke an EJB to insert a new row along with the uploaded file.
}
如果if(!Utility.validateImageDimensions(bytes))
那么 <p:commandButton>
的 Action 监听器被评估为 true (上面的 insert()
方法)不应该不被调用,但是它被调用了,并且这种验证意味着根本没有效果。
As already stated , PrimeFaces 文件上传验证器不起作用。
我在这里做错了什么?如何验证上传图片的尺寸?
最佳答案
您的具体问题是由于上传操作发生在与保存操作不同的 HTTP 请求中而引起的。您首先选择了文件,然后按上传(请求#1),然后按保存按钮(请求#2),对吗?浏览器内置开发人员工具集中的网络监视器(按 F12)也应该确认这一点。 FacesContext#validationFailed()
本质上是请求范围,就像 FacesContext
本身。因此,当您在调用上传操作的请求期间设置它时,它只是在调用保存操作的请求期间“重置”。
这确实有些尴尬。作为<p:fileUpload mode="advanced">
不支持Validator
正如您已经发现的那样,这个问题并没有真正干净的解决方案。您应该摆弄 View 作用域 bean 属性,以维护同一 View 上请求之间的验证状态。
private boolean validationFailed;
public void fileUploadListener(FileUploadEvent event) throws IOException {
// ...
validationFailed = !Utility.validateImageDimensions(bytes);
if (validationFailed) {
// Add message.
}
else {
// Process upload.
}
}
public void insert() {
if (validationFailed) {
// Add message.
}
else {
// Process insert.
}
}
顺便说一句,我不想将这些消息设置为 FATAL
,但如ERROR
。最终用户能够自行修复所有问题。
关于validation - 在 PrimeFaces 的文件上传监听器中验证上传图像的尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22659268/