U většiny problémů s ověřením platnosti EL lze upravit závažnost na jednu z možností chyba, varování nebo žádná. Závažnost žádná chybu pro účely vytváření zpráv de facto ignoruje.
Následující tabulka uvádí jednotlivé problémy, u kterých lze upravit závažnost, a vysvětluje jejich efekty:
Popis | Příklad | Vysvětlení |
---|---|---|
Obecné chyby syntaxe | #{* x} | Chyby syntaxe jsou obecným porušením jazyka EL. Operátor násobení '*' v příkladu očekává dva operandy, ale uveden je pouze jeden (x). |
Prázdný výraz EL | #{} | Označuje, že nebyl uveden žádný výraz. |
Ve výrazu chybí pravá závorka | #{x + 5 | Označuje, že je třeba doplnit pravou (uzavírací) závorku '}', například takto: "#{x + 5}". |
Použití operátoru k vazbě metody | #{bean.action * 5} | Pokud text bean.action označuje metodu "action()" objektu typu bean, není v EL povoleno její výsledek považovat za hodnotu. V uvedeném příkladu se násobení pěti pokouší považovat výsledek za hodnotu. |
Názvy vlastností v tečkové notaci by měly používat syntaxi pole ([]). | #{property.name.foo} | Je-li name.foo klíčem hodnoty v indexu balíku vlastností pro vlastnost property, specifikace EL doporučuje (ale nevyžaduje), abyste jej namísto toho vyjádřili jako property['name.foo'], abyste zdůraznili skutečnost, že name.foo je klíčem v mapování a nikoli například vlastností objektu bean. |
Proměnná nebyla nalezena | #{bean property} | Nelze-li bean vyřešit jako proměnnou, bude tento problém označen. Protože v době návrhu nejsou známy všechny proměnné, které mohou být aktivní za běhu, může být občas užitečné tento problém potlačit, aby se omezila falešná označení problémů. |
Člen nebyl nalezen | #{bean property} | Nelze-li property vyřešit jako vlastnost objektu bean, bude tento problém označen. Například v situaci, kdy bean je třída bez metod getProperty/setProperty. I když je mnohem méně pravděpodobné, že toto ověření způsobí falešné označení problému, může být užitečné jej ignorovat, pokud používáte mnoho různých možných zdrojů proměnných, např. značky. |
Vlastnost je intermediační | #{property.name} | K problému dochází, protože EL umožňuje použít znak '.' v názvech klíčů (například bean['x.y']), ale také jej umožňuje použít jako operátor členu (např. bean.property). To může být příčinou zmatení uživatele, zejména v případech podobných příkladu, kde property představuje mapování podložené balíkem prostředků (např. soubor vlastností). V situaci navozené příkladem předpokládejme, že existuje klíč pro name.foo. Příkaz property.name pak může vypadat smysluplně, i když v balíku nemá klíč a povede buď k hodnotě null, nebo k výjimce za běhu. |
Problémy s vynuceným přetypováním číselné hodnoty dvouargumentové operace | #{5 * true} | Některé binární operátory (např. '+', '-', '*', '/' a mod, které přijímají dva operandy, jako ve výrazu x + y), očekávají, že oba operandy lze před provedením operace implicitně přetypovat na čísla. V příkladu je true literálem typu Boolean, pro který neexistuje povolené implicitní přetypování na číselnou hodnotu (i když některé implementace vynucují implicitní přetypování podobně jako v jazyce C). Takovéto chyby implicitního přetypování obvykle způsobují výjimky za běhu. Všimněte si, že stejné problémy s implicitním přetypováním se vyskytují i u proměnných (např. bean.booleanProperty), nejen u literálů. |
Problémy s vynuceným přetypováním logické hodnoty dvouargumentové operace | #{myBean.integerProperty && true} | Některé binární operátory (např. &&, ||) očekávají, že oba operandy lze před provedením operace implicitně přetypovat na hodnoty Boolean. V uvedeném příkladu je myBean.integerProperty vlastností objektu bean s typem Integer. EL umožňuje implicitní přetypování z číselných typů na hodnoty Boolean (i když některé implementace mohou vynutit implicitní přetypování podobně jako v jazyce C). |
Není k dispozici implicitní přetypování v binární operaci | #{myBean.stringArrayProperty >= myBean.booleanProperty} | Má-li binární operátor, jako např. >=, operandy, z nichž žádný nelze smysluplně implicitně přetypovat za účelem odvození typu operandů, zobrazí se tento problém. V uvedeném příkladu není stringArrayProperty ani booleanProperty platnou hodnotou porovnatelnou pomocí operátoru ">=". |
Vynucené přetypování literálu na číselnou hodnotu pro dvouargumentovou operaci | #{'a' + 'b'} | EL někdy umožňuje implicitní přetypování řetězcových hodnot na čísla. Například #{'5' + '6'} je povoleno, protože '5' i '6' lze převést na čísla pomocí Long.valueOf(). Podobná implicitní přetypování však nejsou povolena, pokud takové převody nelze provést. V době návrhu si můžeme být neplatnými převody jisti pouze v případě, že závadná hodnota je literálem (pokud je proměnnou, obecně se o problému dozvíme až za běhu). V uvedeném příkladu s určitostí víme, že 'a' ani 'b' nelze převést na číselný typ, který operátor + očekává. |
Problém s implicitním přetypováním číselné hodnoty v unární operaci | #{-myBean.mapProperty} | Unární operátor minus očekává, že jeho operand lze před provedením operace implicitně převést na číselný typ. V uvedeném příkladu je myBean.mapProperty typu java.util.Map, pro který neexistuje žádné platné implicitní přetypování na číslo. |
Problém s implicitním přetypováním hodnoty Boolean v unární operaci | #{!myBean.mapProperty} | Unární operátor not očekává, že jeho operand lze před provedením operace implicitně převést na typ Boolean. V uvedeném příkladu je myBean.mapProperty typu java.util.Map, pro který neexistuje žádné platné implicitní přetypování na Boolean. |
Není zaručeno vynucené přetypování řetězce jednoargumentové operace | #{-myBean.stringProperty} | Implicitní přetypování řetězce na číslo, které očekává unární minus, není zaručeno, protože závisí na hodnotě řetězce. Tento problém označuje možné problémy tohoto druhu. |
Oba operandy mají hodnotu null | #{null + null} | Mají-li oba operandy hodnotu null, výsledná hodnota je konstantní a lze ji ručně složit (nahradit literálovou konstantou), aby se zmenšil kód. |
Vyhodnocení binárního výrazu poskytuje vždy tutéž hodnotu | #{x + 5 * 4} | Když jsou oba argumenty binárního výrazu literály, lze operaci v době návrhu složit. Například tento výraz lze zjednodušit na #{x+20}. |
Test rovnosti s hodnotou null vždy vrací tutéž hodnotu | #{myBean.integerProperty == null} | V EL mají testy rovnosti a relační porovnání ('==', '!=', '>=' atd.) s hodnotou null za výsledek vždy tutéž hodnotu. Obecně má nerovnost za výsledek true, rovnost a všechny relační operátory mají za výsledek false. |
Porovnání výčtu vždy poskytuje tutéž hodnotu | #{myBean.coins == 'notAValue'} | Vzhledem k tomu, že možné hodnoty výčtu (Java 5 a novější) jsou známy při kompilaci, můžeme vyloučit porovnání, o kterých víme, že budou mít za výsledek vždy tutéž hodnotu. V uvedeném příkladu hodnota notAValue není členem výčtu Coins, takže víme, že rovnost nikdy nemůže mít hodnotu true. |
Jednoargumentový výraz vždy poskytuje tutéž hodnotu | #{empty 'notEmpty'} | Unární operátory mají operandy, u kterých lze v době návrhu zjistit, že se vždy vyhodnotí na tutéž hodnotu. V operátor empty v uvedeném příkladu má vždy za výsledek hodnotu false, pokud se použije na řetězec, který nemá hodnotu null a není prázdný. |
Prázdný operátor pro daný typ vždy poskytuje hodnotu false | #{empty myBean.integerProperty} | Operátor empty se vždy vyhodnotí na hodnotu false, pokud operandem není hodnota null, prázdný řetězec (String), pole nebo typ Map nebo Collection. |
Znaménko minus přidané k hodnotě null je vždy vyhodnoceno jako nula | #{-null} | Hodnota null se při použití operátoru minus de facto implicitně přetypuje na 0. |
První argument zkracuje výraz. | #{false && someFunc()} | Podmíněné operátory EL "zkracují výrazy", což znamená, že pokud první operand poskytne dostatek informací, aby byl výsledek jistý, druhý operand se nevyhodnotí. V uvedeném příkladu se funkce someFunc() nikdy nezavolá, protože logický součin operandu 'false' s jakoukoli hodnotou má vždy za výsledek hodnotu false. Protože to lze zjistit v době návrhu, označuje to pravděpodobně zbytečný nebo složitelný výraz. |
Druhý argument je vždy vyhodnocen jako tatáž hodnota | #{myBean.booleanProperty && false} | Toto se podobá problému uvedenému výše, až na to, že výraz není zkrácený. V uvedeném příkladu se výraz vždy vyhodnotí na hodnotu false. |
Použití operátoru '.' (tečka) s hodnotou null je vždy vyhodnoceno jako null | #{map[null]} | Použití hodnoty null jako přistupujícího objektu k členu má vždy za výsledek hodnotu null. |
Možné dělení nulou | #{x mod 0} | Dělení nulou a zbytek po dělení nulou mohou vyvolat výjimku za běhu. |
Možný index mimo rozsah | #{myBean.stringArrayProperty[-1]} | Indexy pole musejí být větší nebo rovny nule a menší než velikost pole nebo kolekce (stejně jako v jazyce Java). Když lze v době návrhu zjistit, že tato omezení mohou být narušena, označí se varování. |
Porovnání nekompatibilních výčtů | #{myBean.coins >= myBean.colors} | Porovnání dvou výčtových hodnot, které nejsou stejného výčtového typu (Java 5 a novější), může způsobit výjimku za běhu. |
Očekává se výraz metody | <h:commandButton action="#{bean.property}"/> | Pokud má validátor EL informaci, že atribut značky očekává výraz metody (vazbu metody před JSF 1.2), pak v případě, že se výraz EL vyhodnotí na výraz hodnoty, označí se chyba. V uvedeném příkladu je bean.property výraz hodnoty, který se vyřeší na vlastnost objektu bean pro objekt bean. |
Nekompatibilní typ výrazu hodnoty | <h:inputText rendered="#{bean.foo}/> | Pokud má validátor EL informaci, že atribut značky očekává určitý typ hodnoty, pak označí problém v případě, že výraz nelze implicitně přetypovat na tento typ. V uvedeném příkladu je bean.foo vlastností objektu bean typu Foo objektu bean. Typy tříd obecně nelze implicitně přetypovat na Boolean (rendered musí být typu Boolean). |
Očekává se výraz hodnoty | <h:inputText value="#{bean.action}/> | Pokud je o atributu značky známo, že očekává hodnotu, bude označen problém, jestliže je místo něj uveden výraz metody. V uvedeném příkladu atribut value očekává výraz hodnoty, ale místo něj je zadán výraz metody. Všimněte si, že pouhým pohledem na něj nelze nijak zjistit, že se jedná o výraz metody. Abychom si byli jisti, je nutné vyhodnotit action na objektu bean. |
Nekompatibilní signatura výrazu metody | <h:commandButton action="#{bean.actionTakesArg}" | Pokud je známa očekávaná signatura výrazu metody, validátor ji porovná s poskytnutým výrazem a v případě neshody označí problém. V tomto případě atribut action očekává metodu, která nemá žádné argumenty, ale je poskytnuta metoda s argumenty. |
Očekává se, že vlastnost bude možné číst, nemá však metodu getter | <h:outputText value="#{bean.writeOnlyProperty}/> | Pokud je o atributu značky známo, že vyžaduje čitelnou vlastnost, ale je poskytnuta vlastnost nečitelná, validátor označí problém. |
Očekává se, že do vlastnosti bude možné zapisovat, nemá však metodu setter | <h:inputText value="#{bean.readOnlyProperty}/> | Pokud je o atributu značky známo, že očekává zapisovatelnou vlastnost, ale je poskytnuta vlastnost jen pro čtení, validátor označí problém. |