Jun 20, 2006

JSF - Πρόσβαση στα Managed Beans

Ένας από τους βασικούς στόχους των JSF, καθώς και κριτήριο επιτυχίας τους, είναι η ευκολία της παρουσίασης δεδομένων στο Web. Για την εμφάνιση στοιχείων στις σελίδες μας και τη διαχείριση τους γίνεται χρήση απλών Java κλάσεων, που ονομάζονται Managed Beans, γιατί ακριβώς η αρχικοποίηση, ενημέρωσή τους καθώς και ο χρόνος που θα συμβεί αυτή σύμφωνα με το scope που ανήκουν, αναλαμβάνονται από το ίδιο το πλαίσιο. Πάρτε για παράδειγμα μια οθόνη εισαγωγής στο σύστημα που περιλαμβάνει δυο πεδία, κωδικό και συνθηματικό. Τα δυο αυτά δεδομένα θα πρέπει να έχουν οριστεί σε μια κλάση (για παράδειγμα AuthenticationBean), κατόπιν να έχουν οριστεί στο αρχείο διαμόρφωσης του JSF σε κάποιο scope (πχ request ή session) και στο τέλος μπορούν να ενσωματωθούν σε μία σελίδα, για παράδειγμα ως text boxes, με την βοήθεια της Expression Language (EL) με μια μορφή όπως: #{authBean.username}

Αυτά λίγο ως πολύ είναι γνωστά σε όσους έχουν ξεκινήσει τους πειραματισμούς τους με JSF. Αυτό που όμως έχει περισσότερο ενδιαφέρον είναι πως μέσα από κώδικα, για παράδειγμα ενός συμβάντος όπως το click σε ένα κουμπί, μπορούμε να ανατρέξουμε στις τιμές των Managed Beans της εφαρμογής μας. Μια συνήθης απαίτηση είναι μετά από ένα click σε ένα κουμπί login, να γίνεται ανάθεση ορισμένων βασικών τιμών σε ένα session object (έστω UserBean) που θα τηρεί πληροφορία σχετικά με τις ιδιότητες και τα προνόμια του αυθεντικοποιημένου χρήστη.

Καταρχήν, ο κώδικας που πρέπει να ενεργοποιηθεί θα βρίσκεται πίσω από το κουμπί Login. Κάτι τέτοιο μπορεί να συμβεί απλά με το να κάνουμε διπλό click σε ένα command button στον JDeveloper, που θα μας παραπέμψει στο αρμόδιο Managed Bean (έστω backing_login.java για την περίπτωσή μας). Στις επόμενες παραγράφους, θα παραθέσουμε εναλλακτικές μεθόδους άντλησης και ανάθεσης τιμών από / σε ένα Managed Bean (εδώ μια μικρή παρένθεση για υπενθυμίσουμε πως όταν θα εκτελεστεί ένα συμβάν, έχει ήδη γίνει ενημέρωση του μοντέλου σε πρότερη φάση ώστε να είναι διαθέσιμες οι έγκυρες του τιμές κατά την διαδικασία επεξεργασίας του συμβάντος):

1) Χρησιμοποιώντας το external context της εφαρμογής. Για να έχουμε πρόσβαση είτε στο request scope της εφαρμογής είτε στο session, αρκεί να γράψουμε:

FacesContext.getCurrentInstance().getExternalContext().getSession(true);
FacesContext.getCurrentInstance().getExternalContext().getRequest();

οπότε μπορούμε να ανακτήσουμε σύνδεση στα low-level servlet APIs των HttpServletRequest και HTTPSession και να βρούμε ή να ενημερώσουμε τα αντικείμενα που μας ενδιαφέρουν (το authBean και το UserBean στην συγκεκριμένη περίπτωση)

2) Διαμέσου της Expression Language (EL) Την EL μπορούμε να την αξιοποιήσουμε όχι μόνο στις σελίδες μας, αλλά ακόμα και στον κώδικά μας. Για παράδειγμα στη μέθοδο που εκτελείται με το πάτημα ενός κουμπιού, μπορούμε να αντλήσουμε την τιμή ενός πεδίου ως εξής:

FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
String username = (String)app.createValueBinding("#{authBean.username}").getValue(context);

ή ακόμα καλύτερα ολόκληρου του object ως εξής:

FacesContext context = FacesContext.getCurrentInstance();
Application app = context.getApplication();
AuthenticationBean authBean = (AuthenticationBean)app.createValueBinding("#{authBean}").getValue(context);

και φυσικά με τα δεδομένα που πήραμε, μπορούμε να μεταβάλλουμε τιμές ανάλογα:

app.createValueBinding("#{userBean.username}").setValue(context, username);

3) Ενσωματώνοντας (encapsulate) το αντικείμενο που μας ενδιαφέρει μέσα στο Managed Bean που θα αναλάβει την διαχείριση του συμβάντος. Στην προκειμένη περίπτωση, δηλώνοντας αρχικά στο faces-config.xml για το backing_login.java (η κλάση που θα αναλάβει την διαχείριση του click του κουμπιού login) ότι θα περιλαμβάνει ως Managed Bean property, ένα αντικείμενο με όνομα ίδιο με το AuthenticationBean και με την αρχική τιμή: #{authBean} Ένα από τα ισχυρά χαρακτηριστικά του JSF είναι ότι επιτρέπεται η χρησιμοποίηση EL ακόμα και μέσα στο configuration file. Σε αυτήν την περίπτωση, δηλώσαμε ένα καινούργιο πεδίο στο managed bean, που θα έχει ως τιμή, την request τιμή του αντικειμένου authBean. Το μόνο που απομένει είναι να ορίσουμε στο backing_login.java τα getters/setters για το authBean και μετά είμαστε σε θέση να το αξιοποιήσουμε μέσα στην μέθοδο εκτέλεσης του συμβάντος ως:

authBean.getUsername();





Ο τελευταίος τρόπος είναι ιδιαίτερα χρήσιμος αν πρόκειται να αναφερθούμε εκτεταμένα σε ένα αντικείμενο, καθώς επίσης μας απαλλάσσει από λάθη στο όνομα του Managed Bean που θέλουμε να κάνουμε reference, όπως θα συνέβαινε στις περιπτώσεις 1) και 2)

No comments: