Black Friday je tu! Využij jedinečnou příležitost a získej až 80 % znalostí navíc zdarma! Více zde
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Úvod do Context Dependency Injection (CDI)

V minulé lekci, Úvod do JavaServer Faces (JSF), jsme si vytvořili náš první JSF projekt

Aplikace v JEE skládáme z tzv. beanů, které budeme chápat jako komponenty.

Managed bean

Vytvoříme si tzv. managed bean. To je třída, jejíž instance spravuje JSF, vytváří je podle potřeby a hlavně jejich vlastnosti a metody propojuje s komponentami na webové stránce. Z tohoto důvodu označení managed. JSF řídí životní cyklus těchto beanů a stejně tak na nich volá metody.

Předtím, než vytvoříme novou třídu do našeho projektu, musíme vytvořit složku java/ ve složkách main/:

Struktura projektu

Všimněte si, že jsme v pohledu Files (horní záložka).

Konečně si v projektu vytvoříme nový package s názvem beans a do něj přidáme novou Java Class s názvem GeneratorBean.

Přidání anotací

Vytvořené třídě přidáme dvě anotace: @Named() a @RequestScoped(), vzápětí si vysvětlíme proč:

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named()
@RequestScoped()
public class GeneratorBean {

}

NetBeans na nás zakřičí, že takovou anotaci nezná a ať přidáme do Maven tzv. "závislost" (odkaz na knihovnu). Klikněme na podtrženou anotaci a na žárovku vlevo, jak jsme zvyklí z automatických importů, a vyberme na "Search Dependency at Maven Repositories for Named". Vyberme javaee-api. Tento krok nám přidal do pom.xml odkaz na Java EE knihovny.

Pro zájemce, kteří nepoužívají NetBeans, vypadá závislost v souboru pom.xml takto:

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>8.0</version>
    <type>jar</type>
</dependency>

Už nám pouze zbývá přidat potřebný import, zas přes žárovku a NetBeans s námi už nebude mít problém.

Vidíme, že managed bean je běžná třída s bezparametrickým konstruktorem (aby ji mohlo JSF vytvořit) a s dvěma anotacemi.

CDI bean

Používáme mechanismus CDI bean, CDI označuje Contexts and Dependency Injection (kontexty a injekce závislostí), dále v kurzu si ukážeme, jaké další výhody tato technologie přináší.

Pojďme si přidané anotace vysvětlit:

  • První anotace @Named nám jednoduše pojmenuje naši třídu.
  • Druhá anotace @ReqeustScoped označuje, jak dlouho má instance beanu existovat. V našem případě to znamená, že se instance vytvoří po zaslání požadavku na stránku a po vygenerování stránky zanikne. Dále můžeme použít např. @SessionScoped, kde instance přežívá mezi požadavky pro jednoho klienta, nebo @ApplicationScoped, kde instance přežívá po celou dobu, co je aplikační server zapnutý (funguje jako návrhový vzor jedináček).

Anotace jsou z jmenných prostorů javax.inject.Named a javax.enterprise.context.RequestScoped. Je důležité, abyste používali právě anotace z těchto prostorů, ověřte si to.

Třídě přidáme jediný privátní atribut generator typu Random. Buď v konstruktoru nebo přímo v definici proměnné založíme novou instanci. Dále přidáme getter, který vrátí vždy další náhodné číslo z generátoru. Třída vypadá asi takto:

import java.util.Random;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named()
@RequestScoped()
public class GeneratorBean {
    private Random generator = new Random();

    public int getCislo() {
        return generator.nextInt(100);
    }
}

Možná si říkáte, proč metoda getCislo() vrací String? Je to z toho důvodu, že JSF EL, které budeme používat za chvilku, pracuje poněkud zvláštně s typy int (resp. museli bychom si hrát s konfiguračním souborem, a tomu se prozatím chceme vyhnout).

EL výrazy

Náhodné číslo vložíme z instance beanu do JSF šablony pomocí tzv. EL výrazu (Expression Language). Předtím, než začneme pracovat s EL výrazy, musíme dát vědět našemu aplikačnímu serveru, že má EL výrazy zpracovávat.

Nastavení ve web.xml

Do web.xml přidáme konfigurační XML kód, aby web.xml vypadal takto:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <!-- This is important -->
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <!-- This is important -->
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
</web-app>

Soubor web.xml je také znám jako tzv. deskriptor.

Přesuneme se do index.xhtml. Do této šablony nyní vypíšeme výsledek metody getCislo() na GeneratorBean. Za tímto účelem použijeme tedy EL výraz. Pomocí nich můžeme ze šablon přistupovat k datům z Java beans.

index.xhtml upravíme do následující podoby:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Náhodné číslo</title>
    </h:head>
    <h:body>
        <h1>Náhodné číslo</h1>
        <p style="font-size: 2em;">
            #{generatorBean.cislo}
        </p>
    </h:body>
</html>

V odstavci používáme EL výraz, který zapíšeme pomocí hash-kříže a složených závorek #{}. Vypisujeme vlastnost cislo na instanci generatorBean (s malým počátečním písmenem).

JSF výraz přeloží tak, že vytvoří instanci třídy GeneratorBean a na ni zavolá getter getCislo(), jehož výstup vloží do kódu výsledné HTML stránky. Vidíme, že nám JSF značně zjednodušuje život. Pokud znáte MVC architekturu, tak v podstatě zautomatizovalo kontroler, který propojuje šablony s logickými třídami. Staráme se tedy již jen o tyto 2 vrstvy a zbytek se děje automaticky.

Když aplikaci spustíme, uvidíme následující HTML stránku:

Webová aplikace náhodné číslo v Java Enterprise JSF

Po obnovení dostaneme vždy další náhodné číslo, jelikož je bean nastavený jako RequestScoped (žije jen v době vykonávání požadavku).

Projekt je níže ke stažení pro případ, že jste měli s jakýmkoli krokem problém.

Příště, v lekci Zpracování formulářů v JSF, si vytvoříme jednoduchou kalkulačku a naučíme se zpracovávat formuláře.


 

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 253x (19.52 kB)

 

Předchozí článek
Úvod do JavaServer Faces (JSF)
Všechny články v sekci
JEE - Java Enterprise Edition
Přeskočit článek
(nedoporučujeme)
Zpracování formulářů v JSF
Článek pro vás napsal Samuel Kodytek
Avatar
Uživatelské hodnocení:
6 hlasů
Autor se věnuje všem jazykům okolo JVM. Rád pomáhá lidem, kteří se zajímají o programování. Věří, že všichni mají šanci se naučit programovat, jen je potřeba prorazit tu bariéru, který se říká lenost.
Aktivity

 

 

Komentáře

Avatar
Jirka Stejskal:25.2.2021 11:57

Máš na stránce chybu. pises :

Předtím, než vytvoříme novou třídu do našeho projektu, musíme vytvořit složku java/ ve složkách webapp/main/:

Ale tu složku máš v main/webapp.

Taky mi chybí popisek, jak to sakra mám debugovat?. Hodně by to pomohlo.

 
Odpovědět
25.2.2021 11:57
Avatar
Samuel Kodytek
Člen IT Redactor Gang
Avatar
Odpovídá na Jirka Stejskal
Samuel Kodytek:3.3.2021 10:45

Cesta byla opravena :), děkuji za poznámku.

Jaký popisek? K čemu? asi potřebuji víc infa.

Odpovědět
3.3.2021 10:45
There is more than one way to screw it
Avatar
Lukáš
Člen
Avatar
Lukáš:16.10.2021 20:40

Našel jsem takový problém, nicméně s int mi to funguje:

public int getCislo()

Možná si říkáte, proč metoda getCislo() vrací String?

 
Odpovědět
16.10.2021 20:40
Avatar
Vaclav Pieter:13. března 21:17

Dobrý den,
Nemohu se dostat přes @RequestScoped(), mám pocit, jako by to již nebylo v mavenu k nalezeni. Prosím o radu děkuji.

 
Odpovědět
13. března 21:17
Avatar
Josef Šrámek:25. dubna 21:09

Ahoj. Podobně jako kolega v předchozím příspěvku mám problém s použitím anotace @RequestScoped. Když rozkliknu chybovou žárovičku a zvolím volbu Search Dependency at Maven Repositories for RequestScoped, tak už mi to dál nepustí.

Balíček tříd je: javax.enterpri­se.context.Re­questScoped

Problém bude asi v balíčku tříd. Zjistil jsem, že balíček javax u mne vůbec neobsahuje balíček enterprise, (mám JDK17).

Vypadá to, že tato knihovna už není podporovaná. Ale přitom projekt této lekce, který je možno stáhnout, funguje tak jak má.

Můžete mi prosím někdo poradit? Předem děkuji.

 
Odpovědět
25. dubna 21:09
Avatar
Josef Šrámek:26. dubna 20:56

Už jsem na to přišel. Nejdříve je nutné ještě před spuštěním NetBeansu pro jistotu zkontrolovat soubor pom.xml, jestli obsahuje příslušný kód (podle lekce 4) spustit aplikační server, stažení závislostí, nasazení na serveru vše dle lekce 4. Pak postupovat dle návodu z lekce 5 a neměl by být problém. Akorát, pokud by to přes tu žárovičku dle návodu nešlo, tak tam normálně naimportujte příslušné balíčky tříd a je to. Přeji hezký den.

 
Odpovědět
26. dubna 20:56
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 6 zpráv z 6.