Exemple pratique de l'utilisation SpEL

Présentation de la mise en place des expressions SpEL

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

Maintenant quand on connaît Spring Expression Language du côté théorique (article présentation du SpEL), on peut passer aux exemples pratiques, que l'on retrouvera d'ailleurs dans notre application.

Utiliser Spring Expression Language

Plusieurs endroits dans notre application sont accompagnés par les SpEL. Commençons par l'authentification, déjà abordé dans cet article :

@PreAuthorize("(#subscriber.login == principal.username) or hasRole('ROLE_ADMIN')")
public void updateEmail(Subscriber subscriber) {

Dans la dernière ligne on retrouve l'expression conditionnelle. Elle détermine si le login de l'utilisateur modifié correspond au login de l'utilisateur connecté. Après le "or", on vérifie à travers la méthode hasRole(), si l'utilisateur connecté possède un rôle ROLE_ADMIN. L'un des 2 tests doit être vrai pour que la méthode updateEmail puisse être exécutée.

<evaluate expression="currentUser != null ? newsletterPreferencyService.createPreferenciesForm(currentUser, conversationScope)  : newsletterPreferencyService.createPreferenciesForm(null, conversationScope)" result="viewScope.newsPreferenciesCredentialsForm" />

Cette expression est utilisée dans la définition des Spring Web Flow. Elle est une excellente représentation de l'implémentation de l'if-then-else. Au tout début on vérifie si currentUser (correspond à l'utilisateur connecté) n'est pas null. En fonction du résultat on appelle une méthode createPreferenciesForm avec des paramètres différents.

public class PaymentMethodServiceImpl implements PaymentMethodService {
    public List<PaymentMethod> getAllMethodsBySubscriber(Subscriber subscriber) {
        List<PaymentMethod> result = new ArrayList<PaymentMethod>();
        // get all PaymentMethod
        List<PaymentMethod> paymentMethods = paymentMethodRepository.getAllMethods();
        
        // construct subscriber criterion data
        long borrowed = borrowingService.countBorrowedBySubscriber(subscriber, null, null);
        BigDecimal spentMoney = subscriberService.getSpentMoney(subscriber, true);
        int activityPoints = subscriberService.getActivityPoints(subscriber, spentMoney);

        StandardEvaluationContext context = new StandardEvaluationContext();
        context.setVariable("borrowed", borrowed);
        context.setVariable("spentMoney", spentMoney);
        context.setVariable("activityPoints", activityPoints);
        ExpressionParser parser = new SpelExpressionParser();
        Iterator<PaymentMethod> methodsIterator = paymentMethods.iterator();
        while (methodsIterator.hasNext()) {
            PaymentMethod paymentMethod = (PaymentMethod) methodsIterator.next();
            if (!parser.parseExpression(paymentMethod.getValidity()).getValue(context, Boolean.class) == true) {
                methodsIterator.remove();
            }
        }
        return paymentMethods;
    }
}

Le code ci-dessus est utilisé lors de l'affichage des méthodes de paiement disponibles par l'utilisateur. Actuellement, on accepte 3 méthodes de paiement dont les critères sont définis par les expressions suivantes :
- PayPal : #borrowed >= 0 and #spentMoney >= 0 and #activityPoints >= 2
- Chèque : #borrowed > 80 and #spentMoney > 1000 and #activityPoints == 5
- Virement : #borrowed > 80 and #spentMoney > 1000 and #activityPoints == 5

Voici l'explication des variables utilisées dans les expressions :
- #borrowed : nombre de livres empruntés
- #spentMoney : montant dépensé
- #activityPoints : points d'activité

Sur la base de ces 3 critères on détermine si l'utilisateur peut prétendre à la méthode de paiement donnée. Pour ce faire, on utilise le parseur et le contexte, comme dans les exemples listés dans le premier paragraphe. En occurrence, il s'agit d'un cas de figure qui peut être utile lors de la manipulation des données (dans notre cas, les critères) par une personne non technique.

Bartosz KONIECZNY Spring Expression Language

Une question ? Une remarque ?

*

*

Un conseil JavaScript

Un scroll avec dialog box de jQuery UI ?

Si vous voyez une barre horizontale qui apparaît après l'ouverture d'un dialog box sous IE8, il peut s'agit d'un problème de ce module pour le navigateur en question. Pour y remedier, on peut utiliser la méthode open() et forcer le navigateur à cacher cette bare. Prenons un exemple vivant :

var dialogBox = $(href).dialog({ autoOpen: false, closeOnEscape: true,
  open: function() {  
        $('body').css('overflow-x', 'hidden');
  },
  close: function() {
        $('body').css('overflow-x', 'auto');  
  }
});  
dialogBox.dialog("open");