a także nie widzisz żadnych błędów i / lub ostrzeżeń w przeglądarce w konsoli JavaScript przeglądarki (naciśnij F12 w Chrome / Firefox23 + / IE9 +, aby otworzyć zestaw narzędzi dla programistów, a następnie otwórz konsolę kartę ), a następnie zapoznaj się z poniższą listą możliwych przyczyn.
UICommand
a UIInput
komponenty muszą być umieszczone wewnątrz UIForm
komponentu, np. <h:form>
(a więc nie zwykły HTML <form>
), w przeciwnym razie nic nie zostanie wysłane na serwer. UICommand
komponenty również nie mogą mieć type="button"
atrybutu, w przeciwnym razie będzie to martwy przycisk przydatny tylko w JavaScript onclick
. Zobacz także Jak wysyłać wartości wejściowe formularza i wywoływać metodę w komponencie bean JSF, a <h: commandButton> nie inicjuje postback .
Nie można zagnieżdżać UIForm
w sobie wielu komponentów. Jest to nielegalne w HTML. Zachowanie przeglądarki nie jest określone. Uważaj z dołączonymi plikami! Możesz używać UIForm
komponentów równolegle, ale nie będą się one przetwarzać podczas przesyłania. Powinieneś także uważać z antypatternem „God Form”; upewnij się, że nie przypadkowo przetwarzasz / weryfikujesz wszystkie inne (niewidoczne) dane wejściowe w tej samej formie (np. mając ukryte okno dialogowe z wymaganymi danymi wejściowymi w tej samej formie). Zobacz także Jak używać <h: formularz> na stronie JSF? Pojedynczy formularz? Wiele formularzy? Zagnieżdżone formularze?.
Nie UIInput
powinien wystąpić błąd sprawdzania poprawności / konwersji wartości. Można użyć <h:messages>
do wyświetlenia dowolnych komunikatów, które nie są pokazywane przez <h:message>
komponenty specyficzne dla danych wejściowych . Nie zapomnij zawierać id
od <h:messages>
w <f:ajax render>
, jeśli w ogóle, tak, że będzie on aktualizowany w miarę dobrze na ajax żądań. Zobacz także h: wiadomości nie wyświetla wiadomości po naciśnięciu przycisku p: polecenie .
Jeśli UICommand
lub UIInput
składniki są umieszczone wewnątrz komponentu iteracji jak <h:dataTable>
, <ui:repeat>
itp, to trzeba upewnić się, że dokładnie to samo value
składnika iteracji jest zachowały się podczas zastosowania żądania wartości fazę formie przedstawienia żądania. JSF powtórzy to, aby znaleźć kliknięty link / przycisk i przesłał wartości wejściowe. Umieszczenie komponentu bean w zakresie widoku i / lub upewnienie się, że ładujesz model danych @PostConstruct
do komponentu bean (a zatem nie w metodzie gettera!) Powinno to naprawić. Zobacz także Jak i kiedy powinienem załadować model z bazy danych dla h: dataTable .
Jeśli UICommand
lub UIInput
komponenty są zawarte w dynamicznym źródle, takim jak <ui:include src="#{bean.include}">
, musisz upewnić się, że dokładnie ta sama #{bean.include}
wartość zostanie zachowana w czasie kompilacji widoku żądania przesyłania formularza. JSF ponownie go wykona podczas budowania drzewa komponentów. Umieszczenie komponentu bean w zakresie widoku i / lub upewnienie się, że ładujesz model danych @PostConstruct
do komponentu bean (a zatem nie w metodzie gettera!) Powinno to naprawić. Zobacz także Jak odświeżyć dynamicznie ajax dołączyć zawartość według menu nawigacji? (JSF SPA) .
rendered
Atrybut elementu i wszystkich jego rodziców i test
atrybut każdego rodzica <c:if>
/ <c:when>
nie należy oceniać na false
czasie zastosować wartości żądania fazę formie przedstawienia żądania. JSF sprawdzi to ponownie w ramach zabezpieczenia przed sfałszowanymi / zhakowanymi żądaniami. Przechowywanie zmienne odpowiedzialne za stan w @ViewScoped
fasoli lub upewniając się, że jesteś właściwie preinitializing stanu w @PostConstruct
z @RequestScoped
fasoli powinien to naprawić. To samo dotyczy disabled
atrybutu komponentu, którego nie należy oceniać true
podczas fazy stosowania wartości żądania. Zobacz także Nie akcji JSF CommandButton , Prześlij formularz w warunkowo renderowanym komponencie nie jest przetwarzany ih: commandButton nie działa, gdy zawinę go w <h: panelGroup renderowane> .
onclick
Atrybutem UICommand
elementu i onsubmit
atrybut UIForm
elementu nie powinna powrócić false
lub spowodować błąd JavaScript. Tam w przypadku powinny <h:commandLink>
lub <f:ajax>
też nie ma JS błędy widoczne w konsoli JS przeglądarki. Zwykle wyszukiwanie go w dokładnym komunikacie o błędzie daje już odpowiedź. Zobacz także Ręczne dodawanie / ładowanie wyników jQuery za pomocą PrimeFaces w Uncaught TypeErrors .
Jeśli używasz Ajax przez JSF 2.x <f:ajax>
lub np. PrimeFaces <p:commandXxx>
, upewnij się, że masz <h:head>
szablon główny zamiast <head>
. W przeciwnym razie JSF nie będzie w stanie automatycznie dołączyć niezbędnych plików JavaScript, które zawierają funkcje Ajax. Spowodowałoby to błąd JavaScript, taki jak „mojarra nie jest zdefiniowany” lub „PrimeFaces nie jest zdefiniowany” w konsoli JS przeglądarki. Zobacz także h: commandLink actionlistener nie jest wywoływany, gdy jest używany z f: ajax i ui: repeat .
Jeśli używasz Ajax, a przesłane wartości są w końcu null
, upewnij się, że UIInput
i UICommand
komponenty będące przedmiotem zainteresowania są objęte przez <f:ajax execute>
np. W <p:commandXxx process>
przeciwnym razie nie zostaną wykonane / przetworzone. Zobacz także Przesłane wartości formularza niezaktualizowane w modelu podczas dodawania <f: ajax> do <h: commandButton> oraz Zrozumienie procesu / aktualizacji PrimeFaces i JSF f: ajax atrybuty wykonania / renderowania .
Jeśli przesłane wartości nadal się kończą null
, a używasz CDI do zarządzania komponentami bean, to upewnij się, że importujesz adnotację zakresu z właściwego pakietu, w przeciwnym razie CDI domyślnie, do @Dependent
którego skutecznie odtwarza komponent bean przy każdej pojedynczej ocenie EL wyrażenie. Zobacz także @SessionScoped bean traci zakres i cały czas jest odtwarzany, pola stają się puste i jaki jest domyślny zakres Bean Managed w aplikacji JSF 2?
Jeśli element nadrzędny <h:form>
z UICommand
przyciskiem jest wcześniej renderowany / aktualizowany przez żądanie ajax pochodzące z innego formularza na tej samej stronie, wówczas pierwsza akcja zawsze zakończy się niepowodzeniem w JSF 2.2 lub starszym. Drugie i kolejne działania będą działać. Jest to spowodowane błędem w obsłudze stanu widoku, który jest zgłaszany jako problem ze specyfikacją JSF 790 i obecnie naprawiony w JSF 2.3. Dla starszych wersji JSF, trzeba wyraźnie określić identyfikator <h:form>
w render
z <f:ajax>
. Zobacz także h: commandButton / h: commandLink nie działa przy pierwszym kliknięciu, działa tylko przy drugim kliknięciu .
Jeśli <h:form>
został enctype="multipart/form-data"
ustawiony w celu przesyłania plików wsparcie, to trzeba się upewnić, że używasz przynajmniej JSF 2.2, lub że filtr serwletu, który jest odpowiedzialny za analizowanie wniosków wieloczęściowy / form-data jest poprawnie skonfigurowany, w przeciwnym razie FacesServlet
wolę ostatecznie nie otrzyma żadnych parametrów żądania, a zatem nie będzie w stanie zastosować wartości żądania. Sposób skonfigurowania takiego filtra zależy od używanego komponentu do przesyłania plików. W przypadku Tomahawk <t:inputFileUpload>
sprawdź tę odpowiedź, aw przypadku PrimeFaces <p:fileUpload>
sprawdź tę odpowiedź . Lub, jeśli w ogóle nie przesyłasz pliku, usuń atrybut całkowicie.
Upewnij się, że ActionEvent
argumentem actionListener
jest, javax.faces.event.ActionEvent
a zatem nie java.awt.event.ActionEvent
, co sugeruje większość IDE jako pierwsza opcja autouzupełniania. Brak argumentu jest również błędny, jeśli używasz actionListener="#{bean.method}"
. Jeśli nie chcesz argumentu w swojej metodzie, użyj actionListener="#{bean.method()}"
. A może faktycznie chcesz użyć action
zamiast actionListener
. Zobacz także Różnice między akcją a listą akcji .
Upewnij się, że żaden PhaseListener
lub żaden EventListener
w łańcuchu żądania-odpowiedzi nie zmienił cyklu życia JSF, aby pominąć fazę działania invoke, na przykład wywołując FacesContext#renderResponse()
lub FacesContext#responseComplete()
.
Upewnij się, że żaden Filter
lub Servlet
w tym samym łańcuchu żądanie-odpowiedź w FacesServlet
jakiś sposób nie zablokował żądania . Na przykład filtry logowania / bezpieczeństwa, takie jak Spring Security. Zwłaszcza w żądaniach ajax, które domyślnie nie miałyby żadnej informacji zwrotnej z interfejsu użytkownika. Zobacz także Obsługa żądań AJAX Spring Security 4 i PrimeFaces 5 .
Jeśli używasz PrimeFaces <p:dialog>
lub a <p:overlayPanel>
, upewnij się, że mają swoje własne <h:form>
. Ponieważ te składniki są domyślnie przenoszone przez JavaScript na koniec HTML <body>
. Tak więc, jeśli pierwotnie siedzieli w środku <form>
, to nie mogliby już więcej siedzieć w <form>
. Zobacz także akcja przycisku p: polecenie nie działa w oknie dialogowym p:
Błąd w ramach. Na przykład RichFaces ma „ błąd konwersji ” podczas używania rich:calendar
elementu interfejsu użytkownika z defaultLabel
atrybutem (lub, w niektórych przypadkach, rich:placeholder
podelementem). Ten błąd uniemożliwia wywołanie metody komponentu bean, gdy dla daty kalendarzowej nie jest ustawiona żadna wartość. Śledzenie błędów frameworka można osiągnąć, zaczynając od prostego działającego przykładu i budując stronę z powrotem do momentu wykrycia błędu.
Jeśli nadal utkniesz, czas na debugowanie. Po stronie klienta naciśnij klawisz F12 w przeglądarce, aby otworzyć zestaw narzędzi dla programistów. Kliknij kartę Konsola , aby zobaczyć plik JavaScript. Powinien być wolny od błędów JavaScript. Poniższy zrzut ekranu to przykład z Chrome, który pokazuje przypadek przesłania <f:ajax>
włączonego przycisku bez jego <h:head>
zadeklarowania (jak opisano w punkcie 7 powyżej).
Po stronie serwera upewnij się, że serwer jest uruchomiony w trybie debugowania. Umieść punkt przerwania debugowania w metodzie interesującego komponentu JSF, który ma zostać wywołany podczas przetwarzania formularza przesyłania. Np. W przypadku UICommand
komponentu byłoby to, UICommand#queueEvent()
aw przypadku UIInput
komponentu, byłoby UIInput#validate()
. Wystarczy wykonać wykonanie kodu i sprawdzić, czy przepływ i zmienne są zgodne z oczekiwaniami. Poniższy zrzut ekranu przedstawia przykład z debugera Eclipse.
Jeśli Twój
h:commandLink
jest w środku,h:dataTable
istnieje inny powód, dla któregoh:commandLink
może nie działać:Podstawowe źródło danych, które jest powiązane z
h:dataTable
musi, musi być również dostępne w drugim cyklu życia JSF, który jest uruchamiany po kliknięciu łącza.Więc jeśli podstawowe źródło danych ma zasięg zapytania,
h:commandLink
to nie działa!źródło
Chociaż moja odpowiedź nie ma zastosowania w 100%, ale większość wyszukiwarek uważa ją za pierwsze trafienie, postanowiłem jednak opublikować:
Jeśli używasz PrimeFaces (lub podobny API)
p:commandButton
lubp:commandLink
istnieje szansa, że zapomniałeś jawnie dodaćprocess="@this"
do swoich komponentów poleceń.Jako przewodnik w PrimeFaces użytkownika stwierdza w punkcie 3.18, domyślne dla
process
iupdate
to zarówno@form
, który dość dużo sprzeciwia domyślne można oczekiwać od zwykłego JSFf:ajax
lub RichFaces, które sąexecute="@this"
irender="@none"
odpowiednio.Długo mi to zajęło, żeby się dowiedzieć. (... i myślę, że raczej niewygodne jest używanie wartości domyślnych innych niż JSF!)
źródło
process
to@form
. Więc jeśli akcja nie jest wywoływana w ten sposób, ale dzieje się to podczas używania@this
, najprawdopodobniej ma zastosowanie punkt 3 mojej odpowiedzi.p:commandButton
metodę, która nie wywołała metody actionListener, dopóki nie dodałemprocess="@this"
. Ponadto Podręcznik użytkownika PrimeFaces wyraźnie wymienia wartości domyślne, o których wspomniałem w sekcjach 3.18 i 3.19. Jest tutaj: primefaces.googlecode.com/files/primefaces_users_guide_3_4.pdf ... może zmieniono ustawienia domyślne?process="@this"
i dodaj<p:messages autoUpdate="true">
(lub po prostu przeczytaj dziennik serwera dla wiadomości w kolejce, ale nie wyświetlanych), a zobaczysz, że faktycznie wystąpił błąd konwersji / weryfikacji.Wspomnę jeszcze o jednej rzeczy, która dotyczy Primefaces
p:commandButton
!Kiedy używasz a
p:commandButton
do akcji, która musi zostać wykonana na serwerze, nie możesz jej użyć,type="button"
ponieważ dotyczy to przycisków Push, które są używane do wykonywania niestandardowego javascript bez powodowania do serwera żądania ajax / non-ajax.W tym celu możesz zrezygnować z
type
atrybutu (wartość domyślna to"submit"
) lub możesz użyć jawnietype="submit"
.Mam nadzieję, że to komuś pomoże!
źródło
p:commandButton
ma on kilka wartościtype
atrybutu ibutton
jest jednym, który dotyczy wszystkiego po stronie klienta. Trochę trudno to znaleźć wPrimefaces
dokumencie, ale tutaj jest jeden link: developer.am/primefaces/…Sam utknąłem z tym problemem i znalazłem jeszcze jedną przyczynę tego problemu. Jeśli nie masz metod ustawiających w komponencie bean backing dla właściwości używanych w pliku * .xhtml, akcja po prostu nie jest wywoływana.
źródło
PropertyNotWritableException
. Jeśli go nie widziałeś, być może uruchomiłeś żądanie ajax bez odpowiedniej procedury obsługi wyjątków ajax, ale powinieneś zobaczyć je w logach serwera.Niedawno napotkałem problem z tym, że UICommand nie wywołuje aplikacji JSF 1.2 przy użyciu komponentów IBM Extended Faces Components.
Miałem przycisk polecenia w wierszu bazy danych (wersja rozszerzona, więc
<hx:datatable>
tabeli danych ( ), a UICommand nie uruchamiał się z niektórych wierszy z tabeli (wiersze, które nie uruchamiałyby się, były wiersze większe niż domyślny rozmiar wyświetlania wiersza).Miałem rozwijany komponent do wyboru liczby wierszy do wyświetlenia. Wartość podana w tym polu była
RequestScope
. Dane, na których opiera się sama tabela, były w pewnym sensieViewScope
(w rzeczywistości tymczasowo włączoneSessionScope
).Jeśli wyświetlanie wiersza zostało zwiększone za pomocą kontrolki, która wartość była również powiązana z
rows
atrybutem bazy danych, żaden z wierszy wyświetlanych w wyniku tej zmiany nie mógł uruchomić UICommand po kliknięciu.Umieszczenie tego atrybutu w tym samym zakresie, co same dane tabeli, rozwiązało problem.
Myślę, że wspomniano o tym w BalusC # 4 powyżej, ale nie tylko wartość tabeli musiała mieć zakres View lub Session, ale także atrybut kontrolujący liczbę wierszy wyświetlanych w tej tabeli.
źródło
Miałem też ten problem i dopiero po otwarciu konsoli internetowej przeglądarki zacząłem doskonalić główną przyczynę. Do tego czasu nie mogłem uzyskać żadnych komunikatów o błędach (nawet z
<p:messages>
). Konsola internetowa pokazała kod stanu HTTP 405 wracający z<h:commandButton type="submit" action="#{myBean.submit}">
.W moim przypadku mam połączenie waniliowego HttpServleta zapewniającego uwierzytelnianie OAuth za pomocą faset Auth0 i JSF oraz fasoli realizujących moje widoki aplikacji i logikę biznesową.
Po ponownym przeredagowaniu pliku web.xml i usunięciu serwletu pośredniego, działało ono „magicznie”.
Podsumowując, problem polegał na tym, że serwlet pośredni używał RequestDispatcher.forward (...) do przekierowania ze środowiska HttpServlet do środowiska JSF, podczas gdy wywoływany wcześniej serwlet przekierowywał za pomocą HttpServletResponse.sendRedirect (.. .).
Zasadniczo użycie sendRedirect () pozwoliło „kontenerowi” JSF przejąć kontrolę, podczas gdy RequestDispatcher.forward () oczywiście nie.
Nie wiem, dlaczego facelet był w stanie uzyskać dostęp do właściwości fasoli, ale nie mógł ich ustawić, a to wyraźnie krzyczy za rezygnację z mieszanki serwletów i JSF, ale mam nadzieję, że pomoże to komuś uniknąć wielu godzin głowy walenie w stół.
źródło
Świetnie się bawiłem debugowaniem problemu, w którym
<h:commandLink>
akcjarichfaces
datatable
odmawiała strzału. Tabela kiedyś działała, ale zatrzymała się bez wyraźnego powodu. Nie zostawiłem żadnego kamienia obróconego, tylko po to, aby dowiedzieć się, że użyłemrich:datatable
zła,rowKeyConverter
które zwróciło wartości zerowe, które richfaces chętnie wykorzystywał jako klucze wierszy. Zapobiegło to<h:commandLink>
wywołaniu mojego działania.źródło
Jeszcze jedna możliwość: jeśli symptomem jest to, że pierwsze wywołanie działa, ale kolejne nie, możesz używać PrimeFaces 3.x z JSF 2.2, jak wyszczególniono tutaj: Nie wysyłane jest ViewState .
źródło
Rozwiązałem problem z umieszczeniem:
W:
źródło
To jest rozwiązanie, które dla mnie działa.
W tym przypadku atrybut process = „userGroupSetupForm” jest obowiązkowy dla wywołania Ajax. actionListener wywołuje metodę z @ViewScope Bean. Aktualizujemy również komunikat warczenia, Datatable: userGroupList i Form: userGroupSetupForm.
źródło
Rozwiązać;
źródło