JavaServer Faces (JSF) con Spring

1. Panoramica

In questo articolo esamineremo una ricetta per accedere ai bean definiti in Spring dall'interno di un bean gestito da JSF e una pagina JSF, allo scopo di delegare l'esecuzione della logica di business ai bean Spring.

Questo articolo presume che il lettore abbia una conoscenza preliminare di JSF e Spring separatamente. L'articolo è basato sull'implementazione Mojarra di JSF.

2. In primavera

Facciamo definire il seguente fagiolo in primavera. Il bean UserManagementDAO aggiunge un nome utente a un archivio in memoria ed è definito dalla seguente interfaccia:

public interface UserManagementDAO { boolean createUser(String newUserData); }

L'implementazione del bean viene configurata utilizzando la seguente configurazione Java:

public class SpringCoreConfig { @Bean public UserManagementDAO userManagementDAO() { return new UserManagementDAOImpl(); } }

O utilizzando la seguente configurazione XML:

Definiamo il bean in XML e registriamo CommonAnnotationBeanPostProcessor per garantire che l' annotazione @PostConstruct venga selezionata.

3. Configurazione

Le sezioni seguenti spiegano gli elementi di configurazione che consentono l'integrazione dei contesti Spring e JSF.

3.1. Configurazione Java senza web.xml

Implementando il WebApplicationInitializer siamo in grado di configurare in modo programmatico il ServletContext. Quanto segue è l' implementazione di onStartup () all'interno della classe MainWebAppInitializer :

public void onStartup(ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.register(SpringCoreConfig.class); sc.addListener(new ContextLoaderListener(root)); }

L'AnnotationConfigWebApplicationContext bootstrap contesto Spring'g e aggiunge i fagioli registrando lo SpringCoreConfig di classe.

Allo stesso modo, nell'implementazione Mojarra c'è una classe FacesInitializer che configura FacesServlet. Per utilizzare questa configurazione è sufficiente estendere il FacesInitializer. L'implementazione completa di MainWebAppInitializer è ora la seguente:

public class MainWebAppInitializer extends FacesInitializer implements WebApplicationInitializer { public void onStartup(ServletContext sc) throws ServletException { AnnotationConfigWebApplicationContext root = new AnnotationConfigWebApplicationContext(); root.register(SpringCoreConfig.class); sc.addListener(new ContextLoaderListener(root)); } }

3.2. Con web.xml

Inizieremo configurando il ContextLoaderListener nel file web.xml dell'applicazione:

  org.springframework.web.context.ContextLoaderListener  

Questo listener è responsabile dell'avvio del contesto dell'applicazione Spring all'avvio dell'applicazione web. Questo listener cercherà un file di configurazione primaverile denominato applicationContext.xml per impostazione predefinita.

3.3. faces-config.xml

Ora configuriamo SpringBeanFacesELResolver nel file face-config.xml :

org.springframework.web.jsf.el.SpringBeanFacesELResolver

Un resolver EL è un componente collegabile supportato dal framework JSF, che ci consente di personalizzare il comportamento del runtime JSF durante la valutazione delle espressioni EL (Expression Language). Questo resolver EL consentirà al runtime JSF di accedere ai componenti Spring tramite espressioni EL definite in JSF.

4. Accesso a Spring Beans in JSF

A questo punto, la nostra applicazione web JSF è pronta per accedere al nostro bean Spring da un backing bean JSF o da una pagina JSF.

4.1. Da un Backing Bean JSF 2.0

È ora possibile accedere al bean Spring da un backing bean JSF. A seconda della versione di JSF in esecuzione, esistono due metodi possibili. Con JSF 2.0, si utilizza l' annotazione @ManagedProperty sul bean gestito JSF.

@ManagedBean(name = "registration") @RequestScoped public class RegistrationBean implements Serializable { @ManagedProperty(value = "#{userManagementDAO}") transient private IUserManagementDAO theUserDao; private String userName;
 // getters and setters }

Nota che il getter e il setter sono obbligatori quando si utilizza @ManagedProperty.

Ora, per affermare l'accessibilità di un bean Spring da un bean gestito, aggiungeremo il metodo createNewUser () :

public void createNewUser() { FacesContext context = FacesContext.getCurrentInstance(); boolean operationStatus = userDao.createUser(userName); context.isValidationFailed(); if (operationStatus) { operationMessage = "User " + userName + " created"; } } 

L'essenza del metodo sta usando il bean userDao Spring e accedendo alla sua funzionalità.

4.2. Da un Backing Bean in JSF 2.2

Un altro approccio, valido solo in JSF2.2 e versioni successive, consiste nell'utilizzare l' annotazione @Inject di CDI . Questo è applicabile ai bean gestiti JSF (con l' annotazione @ManagedBean ) e ai bean gestiti da CDI (con l' annotazione @Named ).

In effetti, con un'annotazione CDI, questo è l'unico metodo valido per iniettare il bean:

@Named( "registration") @RequestScoped public class RegistrationBean implements Serializable { @Inject UserManagementDAO theUserDao; }

Con questo approccio, il getter e il setter non sono necessari. Notare inoltre che l'espressione EL è assente.

4.3. Da una vista JSF

Il metodo createNewUser () verrà attivato dalla seguente pagina JSF:

Per eseguire il rendering della pagina, avviare il server e accedere a:

//localhost:8080/jsf/index.jsf

Possiamo anche usare EL nella vista JSF, per accedere al bean Spring. Per testarlo è sufficiente cambiare la riga numero 7 dalla pagina JSF precedentemente introdotta in:

Here, we call the createUser method directly on the Spring DAO, passing the bind value of the userName to the method from within the JSF page, circumventing the managed bean all together.

5. Conclusion

We examined a basic integration between the Spring and JSF contexts, where we’re able to access a Spring bean in a JSF bean and page.

It’s worth noting that while the JSF runtime provides the pluggable architecture that enables the Spring framework to provide integration components, the annotations from the Spring framework cannot be used in a JSF context and vice versa.

Ciò significa che non sarai in grado di utilizzare annotazioni come @Autowired o @Component ecc. In un bean gestito da JSF o utilizzare l' annotazione @ManagedBean su un bean gestito da Spring. È tuttavia possibile utilizzare l' annotazione @Inject sia in un bean gestito JSF 2.2+ sia in un bean Spring (poiché Spring supporta JSR-330).

Il codice sorgente che accompagna questo articolo è disponibile su GitHub.