Archivi tag: Java

JSF2 SelectOneRadio e DataTable

Spesso capita di dover utilizzare in una colonna di una DataTable i radiobutton. Ovviamente non appartenendo allo stesso container (essendo contenuti uno in ogni cella diversa), non sono raggruppabili, e, in html, agiscono come entità separate e svincolate.

Utilizzando le Java Server Faces, ci vengono in aiuto i valueChangeListeners.

Innanzitutto, mettiamo il selectoneradio nella datatable, impostando come listener un metodo sul nostro backingBean.

1
2
3
4
5
6
7
8
<h:dataTable value="#{bean.elementi}" var="elemento">
  <h:column>
    <f:facet name="header">Seleziona:</f:facet>
      <h:selectOneRadio id="radioSeleziona" value="#{bean.selezione}" valueChangeListener="#{bean.doSeleziona}" onclick="dataTableSelectRadio(this);">
        <f:selectItem itemValue="#{elemento.id}"></f:selectItem>
      </h:selectOneRadio>
  </h:column>
</h:dataTable>

Non essendo un radioButton multiplo (non è un insieme), per deselezionare gli altri radioButton quando si clicca su quello scelto,utilizziamo una funzione javascript agganciata nell’evento onclick.

1
2
3
4
5
6
7
8
9
10
11
12
  <h:outputScript library="js">
    function dataTableSelectRadio(radio) {
       var id = radio.name.substring(radio.name.lastIndexOf(':'));
       var element = radio.form.elements;
       for (var i = 0; i < element.length; i++) {
         if (element[i].name.substring(element[i].name.lastIndexOf(':')) == id) {
           element[i].checked = false;
         } 
       }
       radio.checked = true;
    }
  </h:outputScript>

Sul nostro backingBean poi , andiamo ad implementare il ValueChangeListener:

1
2
3
4
  public void doSeleziona(ValueChangeEvent event){
    elementoSelezionato= (String)event.getNewValue();
    internalDoQualcosa();
  }

Ovviamente potete sostituire lo script javascript con qualcosa di piu semplice utilizzando JQuery, ma la sostanza rimane questa.

Check Utente Loggato in JSF2 tramite PhaseListener

Verificare che vi siano determinate condizioni, affinche sia possibile mostrare pagine della nostra webapp realizzata tramite jsf, è relativamente facile.
Normalmente è bene verificare lo stato dell’autenticazione, tramite un servlet filter, in grado di processare tutte le risorse.
In questo esempio realizzeremo invece un listener JSF in ascolto sulla fase di RESTORE_VIEW.

Non essendo possibile effettuare operazioni di CDI sui listener prima della versione 2.2, al posto dell’injection delle classi necessarie, utilizziamo delle espressioni EL per ottenere ad esempio il controllerBean di sessione in cui è mantenuta la classe utente dopo l’autenticazione.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class UserLoggedPhaseListener implements PhaseListener{

    /**
     *
     */

    private static final long serialVersionUID = -2062847364596874153L;

    /* (non-Javadoc)
     * @see javax.faces.event.PhaseListener#afterPhase(javax.faces.event.PhaseEvent)
     */

    @Override
    public void afterPhase(PhaseEvent event) {
       
        FacesContext facesContext = event.getFacesContext();
        String currentPage = facesContext.getViewRoot().getViewId();
         
        boolean isLoginPage = currentPage.lastIndexOf("login.xhtml")>-1;
        if (isLoginPage) return;
       
        AuthController auth = facesContext.getApplication().evaluateExpressionGet(facesContext, "#{auth}", AuthController.class);
        if (auth==null || auth.getUser()==null){
            NavigationHandler nh = facesContext.getApplication().getNavigationHandler();
            nh.handleNavigation(facesContext, null, "LOGOUT");
        }
         
    }

    /* (non-Javadoc)
     * @see javax.faces.event.PhaseListener#beforePhase(javax.faces.event.PhaseEvent)
     */

    @Override
    public void beforePhase(PhaseEvent arg0) {
       
    }
   
   
    /* (non-Javadoc)
     * @see javax.faces.event.PhaseListener#getPhaseId()
     */

    @Override
    public PhaseId getPhaseId() {
         return PhaseId.RESTORE_VIEW;
    }
   
}

Come prima cosa, nell’AfterPhase, andiamo a identificare la pagina richiamata. Se stiamo mostrando la pagina di login, non eseguiamo nessuna attività.
Altrimenti, tramite EL andiamo a cercare un @ManagedBean chiamato “auth”, tramite l’espressione #{auth} .
Nel caso il bean non fosse esistente e/o il suo contenuto nullo, utilizzamo il FacesContext, per accedere al NavigationHandler e richiedere la gestione dell’outcome “LOGOUT”. In questo caso, nelle navigation-rule del faces-config, dobbiamo aver definito una regola che da qualsiasi view-id (view-id=*) permette il redirect alla pagina di login.

1
2
3
4
5
6
7
<navigation-rule>
        <from-view-id>*</from-view-id>
        <navigation-case>
            <from-outcome>LOGOUT</from-outcome>
            <to-view-id>/login.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>

Fatto questo, non dimentichiamo di registrare nel faces-config.xml il nostro listener:

1
2
3
<lifecycle>
        <phase-listener>com.metalide.test.jsf.UserLoggedPhaseListener</phase-listener>
    </lifecycle>

Buon divertimento.

JBoss As 7.1 e SL4J e Log4J

Problemi a loggare dalla nostra applicazione web, utilizzando jboss as 7.1?
Dopo diversi tentativi di gestire le risorse, il file di property , classloader e quanto altro, l’unica soluzione che ho trovato è la seguente.
Jboss utilizza e configura in fase di startup log4j e quindi tutti i nostri messaggi sono intercettati e gestiti dalla sua configurazione. Per bloccare questo comportamento dobbiamo usare le jboss-deployment-structure, ovvero mettere delle direttive nel nostro ear o nel nostro war, tramite file di configurazione, per indicare di escludere i moduli di jboss inerenti il logging, sull’applicazione che stiamo deployando.
Questo sistema evita che jboss in automatico inietti le dipendenze e le responsabilità del logging dei suoi moduli di logging.
il seguente file va messo nella meta-inf dell’Ear o del War.
il seguente esempio è riferito al deploy di un ear, con un war al suo interno.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
   <deployment>
     <exclusions>
       <module name="org.apache.log4j" />
       <module name="org.slf4j"/>
     </exclusions>
   </deployment>
   <sub-deployment name="miaappweb.war">
     <exclusions>
       <module name="org.apache.log4j" />
       <module name="org.slf4j"/>
     </exclusions>
   </sub-deployment>
</jboss-deployment-structure>

Spero sia chiaro.

Aggiunta per Spring:
se si utilizza anche Spring Framework, allora nella lista delle esclusioni va aggiunta anche la librera delle Commons logging, in quanto spring utilizza l’astrazione di Apache per la gestione del logging interno.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
   <deployment>
     <exclusions>
       <module name="org.apache.log4j" />
       <module name="org.slf4j"/>
       <module name="org.apache.commons.logging"/>
     </exclusions>
   </deployment>
   <sub-deployment name="miaappweb.war">
     <exclusions>
       <module name="org.apache.log4j" />
       <module name="org.slf4j"/>
       <module name="org.apache.commons.logging"/>
     </exclusions>
   </sub-deployment>
</jboss-deployment-structure>