2012-12-13 26 views
11

vì fileLimit không tồn tại trong các nguyên tố 3.4 nữa. Tôi đang thử một công việc xung quanh việc thực thi trình xác nhận hợp lệ, vấn đề là phương thức xác nhận hợp lệ sẽ không bao giờ được gọi. Đó là Validator của tôi:PrimeFaces <p: fileUpload mode = "advanced"> trình xác thực không được kích hoạt

@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"); 
      } 
     } 
    } 
} 

và trong facelet của tôi, tôi đã cố gắng:

<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> 

và:

<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> 

và:

<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> 

và:

<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> 

nhưng phương pháp xác thực không bao giờ được gọi. Cách chính xác để làm điều đó là gì?

+0

http://stackoverflow.com/questions/3523998/jsf-2-0-validation-controller Tôi nghĩ đó là cách nó có thể trông như thế nào. chúng tôi xem như là một trong những điều bạn đã thử :(), Hãy chắc chắn rằng bạn đang sử dụng đúng cách nhập khẩu. Sau đó, tôi sẽ bắt đầu nghi ngờ rằng thành phần này có thể không hỗ trợ nó –

+0

Tôi đã thử với h: inputText và phương thức được gọi. –

Trả lời

15

Theo mã nguồn FileUploadFileUploadRenderer, trình xác thực chỉ được gọi khi mode="simple" được sử dụng (lưu ý: điều này lần lượt yêu cầu ajax="false" trên lệnh). Chế độ nâng cao sẽ không đặt tập tin được tải lên làm giá trị đã gửi của thành phần, khiến cho nó vẫn giữ nguyên là null cho đến khi phương thức nghe được gọi. Miễn là giá trị đã gửi là null, trình xác thực không được gọi.

Tôi không chắc chắn nếu điều này là cố ý. Về mặt lý thuyết, có thể đặt UploadedFile làm giá trị đã gửi và yêu cầu trình xác thực dựa vào nó. Bạn có thể muốn tạo báo cáo nâng cao tại PrimeFaces issue tracker.

Trong khi đó, mặc dù nó là poor practice, đặt cược tốt nhất của bạn thực sự thực hiện xác thực theo phương pháp fileUploadListener. Bạn chỉ có thể kích hoạt xác nhận thất bại add phải đối mặt với tin nhắn thông qua FacesContext thích sau:

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

Nếu không, bạn sẽ cần phải tạo một renderer tùy chỉnh cho <p:fileUpload> đó đặt giá trị nộp trong decode() (Tôi tuy nhiên không đảm bảo rằng nó sẽ làm việc trong thực tế, bạn sẽ có thể vấp ngã khi một vấn đề đặc biệt mà có thể hóa ra là lý do tại sao PrimeFaces ban đầu không thực hiện nó như thế).

Nhân tiện, lần xác thực hợp lệ đầu tiên và thứ hai của bạn là chính xác. Lần thử thứ ba chỉ hoạt động nếu bạn đã sử dụng @ManagedBean thay vì @FacesValidator (which is often done when injection of an @EJB is mandatory — which isn't possible in a @FacesValidator). Nỗ lực thứ tư không hợp lệ.

+0

@BalusC, Để xác thực (ví dụ: tôi cần ít nhất một tệp được tải lên): Làm cách nào bạn có thể kích hoạt sự kiện tệpUploadListener đó, nếu tệp 'p: fileUpload' nằm trong biểu mẫu và chỉ có biểu mẫu' commandButton' hiện diện người dùng? – jacktrades

1

Đối với việc chứng thực một upload primefaces tập tin cần thiết trong chế độ tiên tiến (ajax) người ta có thể sử dụng này:

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

Trường hợp thực hiện của phương pháp bean.processValidations() sẽ là một cái gì đó dọc theo dòng:

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(); 
     } 
    } 

Trường hợp fileUploadsBean sẽ là một bean CDI phạm vi REQUEST (sẽ không hoạt động với JSF ManagedBeans chuẩn) mà bạn đưa vào bean của mình có phương thức processValidations() được xác định, phương pháp fileUploadsBean.getFileUploadComponent() trả về thành phần tải lên tệp gốc (bạn sẽ sử dụng <p:fileUpload binding="#{fileUploadsBean.fileUploadComponent}" ...> cho điều đó).Phương thức isFileUploaded() sẽ xác định xem tệp đã được tải lên hay chưa (có thể chỉ là một kiểm tra trống trên biến thành viên mà bạn điền từ tệp FileUploadListener).

Nếu bạn muốn làm nổi bật nút tải lên tệp, tất nhiên bạn có thể thêm styleClass có điều kiện, sau đó bạn có thể sử dụng để thêm đường viền màu đỏ chẳng hạn.

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

Kết quả là thông báo xác thực không thành công để tải lên tệp nội dung sẽ được hiển thị cùng với tất cả các thông báo xác thực jsf khác. Bạn có thể gặp vấn đề với việc duy trì thứ tự các thông báo xác nhận (sẽ luôn ở cuối), nhưng nó vẫn đánh bại việc hiển thị xác thực tệp tải lên không thành công sau khi người dùng xử lý tất cả các thông báo xác thực jsf chuẩn từ các trường khác nhau và hành động của bạn trong một bean sao lưu cuối cùng cũng đã đạt được.

+0

cách tiếp cận tốt nhất có thể để xác thực không chuẩn IMO – teejay

Các vấn đề liên quan