Istotność większości problemów dotyczących sprawdzania poprawności języka wyrażeń można dostosować tak, aby miała wartość błąd, ostrzeżenie lub brak. Istotność brak powoduje zignorowanie błędu na potrzeby raportowania.
W poniższej tabeli przedstawiono problemy, których istotność można dostosować, i wyjaśniono ich efekty:
Opis | Przykład | Objaśnienia |
---|---|---|
Ogólny błąd składni | #{* x} | Błędy składniowe to ogólne naruszenie języka wyrażeń. W przykładzie operator mnożenia (*) oczekuje dwóch operandów, ale podano tylko jeden (x). |
Puste wyrażenie języka wyrażeń | #{} | Wskazuje, że nie podano żadnego wyrażenia. |
Brak zamykającego nawiasu w wyrażeniu | #{x + 5 | Wskazuje, że należy dodać nawias zamykający }, jak w następującym wyrażeniu: "#{x + 5}". |
Stosowanie operatora do powiązania metody | #{bean.action * 5} | Jeśli wartość bean.action wskazuje metodę "action()" dla komponentu bean, traktowanie jej wyniku jako wartości nie jest dozwolone przez język wyrażeń. W przykładzie próba pomnożenia metody action przez 5 wskazuje traktowanie jej wyniku jako wartości. |
W nazwach właściwości z kropkami należy używać składni tablic ([]) | #{property.name.foo} | Jeśli name.foo jest kluczem wartości w indeksie pakunku właściwości property, w specyfikacji języka wyrażeń zaleca się (ale nie jest to wymagane) użycie składni property['name.foo'] w celu podkreślenia, że wartość name.foo jest kluczem w odwzorowaniu, a nie na przykład właściwością komponentu bean. |
Nie znaleziono zmiennej | #{bean property} | Jeśli wartości bean nie można rozstrzygnąć jako zmiennej, zostanie zgłoszony ten problem. Ponieważ w czasie projektowania nie są znane wszystkie zmienne, które mogą być aktywne w czasie wykonywania, w niektórych przypadkach można zablokować zgłaszanie tego błędu w celu zmniejszenia liczby fałszywych alarmów. |
Nie znaleziono składowej | #{bean property} | Jeśli wartości property nie można rozstrzygnąć jako właściwości elementu bean, zostanie zgłoszony ten problem. Na przykład jeśli element bean jest klasą bez metod getProperty/setProperty. Zgłoszenie fałszywych alarmów przez to sprawdzenie poprawności jest mało prawdopodobne, ale zignorowanie tego problemu może być użyteczne, jeśli używanych jest wiele różnych możliwych źródeł zmiennych, np. znaczniki. |
Właściwość jest pośrednia | #{property.name} | Problem występuje, ponieważ język wyrażeń zezwala na stosowanie znaku kropki (.) w nazwach kluczy (np. bean['x.y'], jak również jako operatora składowej (np. bean.property). Może to powodować pomyłki użytkownika, zwłaszcza w takich przypadkach, jak zaprezentowano w przykładzie, gdzie wartość property reprezentuje odwzorowanie oparte na pakunku zasobów (tzn. pliku właściwości). Jeśli dodatkowo istnieje klucz name.foo, instrukcja property.name może wydawać się poprawna, choć w pakunku nie istnieje klucz i jej wynikiem będzie wartość NULL lub wyjątek wykonawczy. |
Problemy z wymuszaniem typu liczbowego w operacji binarnej | #{5 * true} | Niektóre operatory binarne (takie jak +, -, *, / i mod, które przyjmują dwa operandy, np. x + y) oczekują, że dla obu operandów można wymusić typ liczbowy przed zastosowaniem operacji. W przykładzie wartość true jest literałem boolowskim, dla którego wymuszenie typu liczbowego nie jest możliwe (choć niektóre implementacje stosują wymuszenie podobnie jak w języku C). Takie błędy wymuszenia zwykle powodują wyjątki wykonawcze. Należy pamiętać, że te same problemy z wymuszaniem dotyczą także zmiennych (tzn. bean.booleanProperty) i nie są one ograniczone tylko do literałów. |
Problemy z wymuszaniem typu boolean w operacji binarnej | #{myBean.integerProperty && true} | Niektóre operatory binarne (np. &&, ||) oczekują, że dla obu operandów można wymusić wartości boolowskie przed zastosowaniem operacji. W przykładzie wartość myBean.integerProperty to właściwość komponentu bean typu Integer. Język wyrażeń zezwala na wymuszanie wartości boolowskich na podstawie wartości liczbowych (choć niektóre implementacje mogą stosować wymuszanie podobnie jak w języku C). |
Brak dostępnego wymuszenia w operacji binarnej | #{myBean.stringArrayProperty >= myBean.booleanProperty} | Ten problem jest zgłaszany, jeśli dla operatora binarnego takiego jak >= podano operandy, dla których nie można wykonać wymuszenia w celu uzyskania typu. W przykładzie ani wartość stringArrayProperty, ani booleanProperty nie jest poprawną wartością, którą można porównać za pomocą operatora ">=". |
Wymuszanie binarne z literału do liczby | #{'a' + 'b'} | Język wyrażeń czasem zezwala na wymuszenie z wartości łańcuchowych do liczby. Na przykład wyrażenie #{'5' + '6'} jest dozwolone, ponieważ zarówno wartość 5, jak i 6 można przekształcić w liczby przy użyciu metody Long.valueOf(). Jednak podobne wymuszenie jest niedozwolone, jeśli nie można wykonać takiego przekształcenia. W czasie projektowania niepoprawnego przekształcenia można być pewnym tylko wtedy, gdy wartością powodującą błąd jest literał (jeśli jest to zmienna, zwykle poprawność można określić dopiero w czasie wykonywania). W przykładzie wiadomo, że ani wartości a, ani b nie można przekształcić w typ liczbowy oczekiwany przez operator +. |
Problem z wymuszaniem typu liczbowego w operacji unarnej | #{-myBean.mapProperty} | Unarny operator minus oczekuje, że dla operandu można wymusić typ liczbowy przed zastosowaniem operacji. W przykładzie wartość myBean.mapProperty ma typ java.util.Map, dla którego nie można wymusić wartości liczbowej. |
Problem z wymuszaniem typu boolean w operacji unarnej | #{!myBean.mapProperty} | Unarny operator not oczekuje, że dla operandu można wymusić typ boolean przed zastosowaniem operacji. W przykładzie wartość myBean.mapProperty ma typ java.util.Map, dla którego nie można wymusić wartości boolowskiej. |
Brak gwarancji wymuszenia typu string w operacji unarnej | #{-myBean.stringProperty} | Wymuszenia łańcucha do wartości liczbowej oczekiwane przez unarny operator minus nie są gwarantowane w zależności od wartości łańcucha. Ten problem jest zgłaszany, jeśli wspomniana sytuacja jest możliwa. |
Oba operandy mają wartość NULL | #{null + null} | Jeśli oba operandy mają wartość NULL, wynikowa wartość jest stała i można ją ręcznie zawinąć (zastąpić stałą literału), aby zmniejszyć długość kodu. |
Wyrażenie binarne zawsze jest wartościowane do tej samej wartości | #{x + 5 * 4} | Jeśli oba argumenty wyrażenia binarnego są literałami, operację można zawinąć w czasie projektowania. Na przykład to wyrażenie można uprościć do postaci #{x+20}. |
Porównanie pod kątem równości z wartością NULL zawsze jest wartościowane do tej samej wartości | #{myBean.integerProperty == null} | W przypadku języka wyrażeń wynikiem porównań pod kątem równości i porównań relacyjnych (==, !=, >= itd.) z wartością NULL jest zawsze ta sama wartość. Zwykle wynikiem nierówności jest wartość true, a w przypadku równości i operatorów relacyjnych wartość false. |
Porównanie wyliczenia zawsze jest wartościowane do tej samej wartości | #{myBean.coins == 'notAValue'} | Ponieważ możliwe wartości wyliczenia (Java w wersji 5 lub nowszej) są znane w czasie kompilowania, można wykluczyć porównania, które zawsze będą miały tę samą wartość. W przykładzie wartość notAValue nie jest elementem wyliczenia Coins, więc wiadomo, że równość nigdy nie będzie mieć wartości true. |
Wyrażenie unarne zawsze jest wartościowane do tej samej wartości | #{empty 'notEmpty'} | Operatory unarne mają operandy, dla których w czasie projektowania można wykryć, że zawsze będą wartościowane do tej samej wartości. W przykładzie operator empty zawsze zwróci wartość false, jeśli zostanie zastosowany dla niepustego łańcucha o wartości innej niż NULL. |
Pusty operator zawsze jest rozstrzygany do wartości false dla typu | #{empty myBean.integerProperty} | Operator empty jest zawsze wartościowany do wartości false, chyba że jego operand ma wartość NULL, jest pustym łańcuchem lub ma typ Array, Map lub Collection. |
Operator minus zastosowany do wartości NULL zawsze jest wartościowany do wartości zero | #{-null} | Dla wartości NULL wymuszana jest wartość 0, jeśli zostanie zastosowany operator minus. |
Pierwszy argument powoduje niepełne wartościowanie wyrażenia | #{false && someFunc()} | Operatory warunkowe języka wyrażeń powodują "niepełne wartościowanie". Oznacza to, że drugi operand nie jest wartościowany, jeśli pierwszy operand dostarcza wystarczającą ilość informacji, aby wynik był pewny. W przykładzie metoda someFunc() nie zostanie nigdy wywołana, ponieważ wynikiem zastosowania operatora logicznego AND do wartości false i dowolnej innej wartości będzie wartość false. Ponieważ taką sytuację można wykryć w czasie projektowania, prawdopodobnie wskazuje to bezużyteczne wyrażenie lub wyrażenie, które można ręcznie zawinąć. |
Drugi argument zawsze jest wartościowany do tej samej wartości | #{myBean.booleanProperty && false} | Ten problem jest podobny do problemu poprzedniego, ale w tym przypadku nie powoduje on niepełnego wartościowania wyrażenia. Wynikiem wartościowania wyrażenia w przykładzie będzie zawsze wartość false. |
Zastosowanie operatora kropki ('.') do wartości NULL zawsze zwróci wartość NULL | #{map[null]} | W przypadku zastosowania wartości NULL jako akcesora elementów zawsze zostanie zwrócona wartość NULL. |
Potencjalne dzielenie przez zero | #{x mod 0} | Operacje dzielenia przez 0 i moduł z 0 mogą powodować wyjątek wykonawczy. |
Możliwe wykroczenie indeksu poza zakres | #{myBean.stringArrayProperty[-1]} | Indeksy tablic muszą być większe lub równe 0 i nie mogą być większe niż wielkość tablicy lub kolekcji (podobnie jak w przypadku języka Java). Jeśli w czasie projektowania można wykryć, że te ograniczenia mogą zostać naruszone, zgłaszane jest ostrzeżenie. |
Porównanie niezgodnych wyliczeń | #{myBean.coins >= myBean.colors} | Porównywanie dwóch wartości wyliczenia, które mają inny typ wyliczeniowy (Java w wersji 5 lub nowszej) może spowodować wyjątek w czasie wykonywania. |
Oczekiwane wyrażenie metody | <h:commandButton action="#{bean.property}"/> | Jeśli analizator poprawności języka wyrażeń określi, że atrybut znacznika oczekuje wyrażenia metody (powiązanie metody technologii JSF w wersji wcześniejszej niż 1.2), zostanie zgłoszony błąd w przypadku, gdy wyrażenie języka wyrażeń zostanie wartościowane do wyrażenia wartości. W przykładzie wartość bean.property to wyrażenie wartości rozstrzygane do właściwości komponentu bean w elemencie bean. |
Niezgodność typów wyrażenia wartości | <h:inputText rendered="#{bean.foo}/> | Jeśli analizator poprawności języka wyrażeń określi, że atrybut znacznika oczekuje konkretnego typu wartości, zostanie zgłoszony problem w przypadku, gdy dla wyrażenia nie można przeprowadzić wymuszenia do tego typu. W przykładzie wartość bean.foo oznacza właściwość komponentu bean typu beans Foo. Dla dowolnych typów klasy zwykle nie można wymusić wartości boolowskich (element rendered musi mieć wartość boolowską). |
Oczekiwane wyrażenie wartości | <h:inputText value="#{bean.action}/> | Jeśli wiadomo, że atrybut znacznika oczekuje wartości, w przypadku podania wyrażenia metody zostanie zgłoszony problem. W przykładzie atrybut value oczekuje wyrażenia wartości, ale podane jest wyrażenie metody. Należy zauważyć, że nie da się określić, czy jest to wyrażenie metody bez wykonania żadnych działań. Aby się upewnić, konieczne jest wartościowanie działania action względem komponentu bean. |
Niezgodność sygnatur wyrażenia metody | <h:commandButton action="#{bean.actionTakesArg}" | Jeśli oczekiwana sygnatura wyrażenia metody jest znana, analizator poprawności porówna ją z podanym wyrażeniem i zgłosi problem w przypadku niezgodności. W tym przypadku argument action oczekuje metody, która nie przyjmuje żadnych argumentów, ale podano metodę przyjmującą argumenty. |
Oczekiwano, że właściwość będzie dostępna do odczytu, ale nie ma ona procedury pobierającej | <h:outputText value="#{bean.writeOnlyProperty}/> | Jeśli wiadomo, że atrybut znacznika wymaga właściwości dostępnej do odczytu, ale podano właściwość niedostępną do odczytu, analizator poprawności zgłosi problem. |
Oczekiwano, że właściwość będzie dostępna do zapisu, ale nie ma ona procedury ustawiającej | <h:inputText value="#{bean.readOnlyProperty}/> | Jeśli wiadomo, że atrybut znacznika wymaga właściwości dostępnej do zapisu, ale podano właściwość tylko do odczytu, analizator poprawności zgłosi problem. |