2012-12-13 89 views
11

因爲fileLimit不存在於primefaces 3.4中了我正在嘗試圍繞實現驗證器的工作,問題是驗證方法不會被調用。這是我的驗證:PrimeFaces <p:fileUpload mode =「advanced」>驗證器未被觸發

@FacesValidator(value ="fileLimitValidator") 
public class FileLimitValidator implements Validator { 

    @Override 
    public void validate(final FacesContext context, final UIComponent component, 
      final Object value) throws ValidatorException { 

     final String fileLimit = (String)component.getAttributes().get("fileLimit"); 
     final String size = (String)component.getAttributes().get("size"); 

     if (fileLimit!=null && size!=null) { 
      if (Integer.valueOf(size) >= Integer.valueOf(fileLimit)) { 
       FacesUtils.throwErrorExceptionFromComponent(component,"fichero_confidencialidad_error"); 
      } 
     } 
    } 
} 

,並在我的facelet我已經試過:

<p:fileUpload id="#{id}FileUpload" 
     fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced" 
     multiple="true" allowTypes="#{allowTypes}" showButtons="false" 
     update="#{id}ListaDocs #{id}MsgError" auto="true" 
     label="#{fileuploadmsg.label_boton}" 
     invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}" > 

     <f:validator validatorId="fileLimitValidator"/> 
     <f:attribute name="fileLimit" value="#{fileLimit}"/> 
     <f:attribute name="size" value="#{listaDocumentos.size}"/> 
    </p:fileUpload> 

和:

<p:fileUpload id="#{id}FileUpload" 
     fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced" 
     multiple="true" allowTypes="#{allowTypes}" showButtons="false" 
     update="#{id}ListaDocs #{id}MsgError" auto="true" 
     label="#{fileuploadmsg.label_boton}" 
     invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}" 
     validator="fileLimitValidator"> 

     <f:attribute name="fileLimit" value="#{fileLimit}"/> 
     <f:attribute name="size" value="#{listaDocumentos.size}"/> 
    </p:fileUpload> 

和:

<p:fileUpload id="#{id}FileUpload" 
     fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced" 
     multiple="true" allowTypes="#{allowTypes}" showButtons="false" 
     update="#{id}ListaDocs #{id}MsgError" auto="true" 
     label="#{fileuploadmsg.label_boton}" 
     invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}" 
     validator="#{fileLimitValidator}"> 

     <f:attribute name="fileLimit" value="#{fileLimit}"/> 
     <f:attribute name="size" value="#{listaDocumentos.size}"/> 
    </p:fileUpload> 

和:

<p:fileUpload id="#{id}FileUpload" 
     fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced" 
     multiple="true" allowTypes="#{allowTypes}" showButtons="false" 
     update="#{id}ListaDocs #{id}MsgError" auto="true" 
     label="#{fileuploadmsg.label_boton}" 
     invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}" 
     validator="#{fileLimitValidator.validate}"> 

     <f:attribute name="fileLimit" value="#{fileLimit}"/> 
     <f:attribute name="size" value="#{listaDocumentos.size}"/> 
    </p:fileUpload> 

但驗證方法永遠不會被調用。什麼是正確的方法來做到這一點?

+0

http://stackoverflow.com/questions/3523998/jsf-2-0-validation-controller我認爲這是它的樣子。我們看起來像你試過的東西:(),確保你使用的是正確的輸入。然後我會開始懷疑這個組件可能不支持它 –

+0

我試着用h:inputText和方法調用。 –

回答

15

按照FileUploadFileUploadRenderer源代碼,驗證程序僅當mode="simple"是被用來調用(注意:這又需要ajax="false"上命令)。高級模式將不會將上傳的文件設置爲組件的提交值,導致它保持爲null,直到調用偵聽器方法。只要提交的值是null,驗證器不會被調用。

我不確定這是故意的。理論上,應該可以將UploadedFile設置爲提交的值,並讓驗證器依賴它。您可能需要在PrimeFaces issue tracker創建增強報告。

與此同時,儘管這是一個poor practice,你最好的選擇是真正執行fileUploadListener方法的驗證。你可以只觸發驗證失敗附加面臨通過FacesContext消息像如下:

if (fail) { 
    context.validationFailed(); 
    context.addMessage(event.getComponent().getClientId(context), new FacesMessage(
     FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail)); 
} 

否則,你需要爲它在decode()(但我沒有設置提交的值的<p:fileUpload>定製呈現保證它在實踐中可行,你可能會遇到一個奇怪的問題,這可能是PrimeFaces沒有像最初那樣執行它的原因)。

順便說一下,您的第一次和第二次驗證器嘗試是正確的。第三次嘗試僅在您使用@ManagedBean而不是@FacesValidatorwhich is often done when injection of an @EJB is mandatory — which isn't possible in a @FacesValidator)時有效。第四次嘗試是無效的。

+0

@BalusC,爲了驗證(例如我至少需要一個上傳的文件):如果'p:fileUpload'在一個表單中,並且只有'commandButton'形式存在,那麼如何觸發fileUploadListener事件用戶? – jacktrades

1

對於模式驗證所需的primefaces文件上傳先進(阿賈克斯),可以使用:

<f:metadata> 
    <f:event listener="#{bean.processValidations()}" type="postValidate" /> 
</f:metadata> 

bean.processValidations()方法的實現將是沿着線的東西:

public void processValidations() { 
     FacesContext context = FacesContext.getCurrentInstance(); 
     UIInput fileUploadComponent = fileUploadsBean.getFileUploadComponent(); 
     if (fileUploadComponent!=null && !isFileUploaded()) { 
      fileUploadComponent.setValid(false); 
      context.addMessage(fileUploadComponent.getClientId(context), new FacesMessage(FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail)); 
      context.validationFailed(); 
     } 
    } 

其中fileUploadsBean將是一個請求範圍的CDI bean(不會與標準JSF ManagedBeans一起使用),它向您的Bean注入,其中定義了processValidations()方法,方法fileUploadsBean.getFileUploadComponent()返回primefaces文件上傳組件(您將使用<p:fileUpload binding="#{fileUploadsBean.fileUploadComponent}" ...>)。方法isFileUploaded()將確定文件是否已被上傳(可能只是您從fileUploadListener填充的成員變量上的空檢查)。

如果你想突出顯示文件上傳按鈕,你當然可以有條件地添加一個styleClass,然後你可以用它來添加一個紅色邊框。

styleClass="#{fileUploadsBean.fileUploadComponent.valid ? '' : 'validationFailed'}" 

因此,primefaces文件上傳的驗證失敗消息將與其他所有jsf驗證消息一起顯示。您可能在維護驗證消息的順序方面有問題(總是在最後),但在用戶處理來自不同字段的所有標準jsf驗證消息以及您在支持bean中的操作之後,仍然會顯示失敗的上傳文件驗證。已經終於達成了。

+0

通過非標準驗證IMO的最佳方法 – teejay