2012-12-13 8 views
11

od fileLimit już nie istnieje w pakietach 3.4 3.4 Próbuję pracować nad implementacją walidatora, problem polega na tym, że metoda validate nigdy nie jest wywoływana. To mój Validator:PrimeFaces <p: fileUpload mode = "advanced"> walidator nie został zwolniony

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

iw moim facelet Próbowałem:

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

oraz:

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

oraz:

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

oraz:

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

, ale metoda sprawdzania poprawności nigdy nie jest wywoływana. Jaki jest prawidłowy sposób to zrobić?

+0

http://stackoverflow.com/questions/3523998/jsf-2-0-validation-controller Myślę, że tak to może wyglądać. wyglądamy jak jedna z rzeczy, które wypróbowałeś :(), Upewnij się, że używasz poprawnego importu. Wtedy zacznę podejrzewać, że ten komponent może go nie obsługuje –

+0

Próbowałem z h: inputText i metoda zostaje wywołana. –

Odpowiedz

15

Według kodu FileUpload i FileUploadRenderer źródłowego, walidator jest wywoływana tylko wtedy, gdy jest stosowany mode="simple" (uwaga: to z kolei wymaga ajax="false" na komendę). Tryb zaawansowany nie ustawi przesłanego pliku jako przesłanej wartości komponentu, co spowoduje, że pozostanie on niezmieniony aż do wywołania metody detektora. Dopóki przesłana wartość to null, walidatory nie są wywoływane.

Nie jestem pewien, czy jest to zamierzone działanie. Teoretycznie powinno być możliwe ustawienie wartości UploadedFile jako przesłanej wartości i użycie walidatora, aby się na niej powoływał. Możesz utworzyć raport ulepszeń pod numerem PrimeFaces issue tracker.

W międzyczasie, pomimo tego, że jest to poor practice, Twój najlepszy zakład faktycznie wykonuje walidację w metodzie fileUploadListener. można po prostu wywołać niewydolność walidacji add twarze wiadomości za pośrednictwem FacesContext lubię następująco:

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

W przeciwnym razie trzeba by utworzyć niestandardowy mechanizm renderujący dla <p:fileUpload> który ustala wartość złożonej podczas decode() (ja jednak nie zagwarantować, że zadziała w praktyce, może natkniesz się na specyficzny problem, który może okazać się powodem, dla którego PrimeFaces początkowo go nie wdrożyło).

Przy okazji, twoja pierwsza i druga próba walidatora są poprawne. Trzecia próba działa tylko wtedy, gdy użyłeś @ManagedBean zamiast @FacesValidator (which is often done when injection of an @EJB is mandatory — which isn't possible in a @FacesValidator). Czwarta próba jest nieważna.

+0

@BalusC, W celu sprawdzenia poprawności (np. Potrzebuję co najmniej jednego przesłanego pliku): Jak wyzwolić zdarzenie fileUploadListener, jeśli 'p: fileUpload' jest w formularzu, a tylko forma' commandButton' jest obecna w formularzu użytkownik? – jacktrades

1

Do potwierdzania wymaganej przesyłanie plików primefaces w trybie zaawansowanym (Ajax) jest możliwe, aby korzystać z tego:

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

Jeżeli wdrożenie metody bean.processValidations() byłoby coś wzdłuż linii:

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

Gdzie fileUploadsBean byłby zasięgiem komponentu bean CDI ZAPYTAŃ (nie będzie działać ze standardowymi JSF ManagedBeans), który można wstrzyknąć do komponentu bean, który ma zdefiniowaną metodę processValidations(), metoda fileUploadsBean.getFileUploadComponent() zwraca element ładujący plik primefaces (do tego użyjesz <p:fileUpload binding="#{fileUploadsBean.fileUploadComponent}" ...>).Metoda ta określa, czy plik został przesłany czy nie (prawdopodobnie po prostu zerowa kontrola zmiennej składowej, którą wypełnia się z fileUploadListener).

Jeśli chcesz podświetlić przycisk przesyłania plików, możesz oczywiście dodać klasę stylu, którą możesz następnie wykorzystać do dodania czerwonego obramowania.

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

W rezultacie komunikat o sprawdzeniu poprawności nie powiodła się dla przesłania pliku głównego zostanie wyświetlony wraz z wszystkimi innymi komunikatami sprawdzania jsf. Możesz mieć problem z utrzymaniem porządku komunikatów sprawdzania poprawności (będzie zawsze na końcu), ale nadal będzie wyświetlał komunikat o niepowodzeniu sprawdzania poprawności plików przesłanych po tym, jak użytkownik zajął się wszystkimi standardowymi komunikatami sprawdzania poprawności jsf z różnych pól i działaniem w komponencie bean został wreszcie osiągnięty.

+0

najlepsze możliwe podejście do niestandardowych zatwierdzeń IMO – teejay

Powiązane problemy