JSF+Bean Validation, Groups – switch

Bean Validation (JSR 380) und Jave Server Faces sind inzwischen ein eingespieltes Team und werden in den meisten Projekte eingesetzt. Ein nettes Features welches wir schon in einem älteren Blog-Beitrag beleuchtet haben ( hier ) sind Validierungs-Gruppen mit denen wir unterschiedliche Regel-Sets zusammenstellen können

Wie schon im angesprochenen Artikel erläutert arbeiten wir bei den BeanValidation Groups mit einem Marker-Interface:

public class DemoModel {

    @NotNull(groups = OnTransmit.class)
    @Size(min = 4, groups = OnTransmit.class)
    private String firstname;

    @NotNull(groups = {Default.class, OnTransmit.class})
    @Size(min = 4, groups = {Default.class, OnTransmit.class})
    private String lastname;
}

Diese Gruppen lassen sich dann entwede programmatisch bei der Validierung heranziehen oder seit JSF 2.1 mittels f:validateBean in unserem JSF Template referenzieren. Doch was tun wenn wir dynamisch entscheiden wollen welche Gruppen zur Validierung heran gezogen werden sollen? Sagen wir auf Basis des verwendeten Buttons? Das macht die Sache hier schon etwas schwieriger. JSF bietet hier allerdings eine Möglichkeit, in der faces-config.xml registrieren wir einen globalen Validator:

    <application>
        <default-validators>
            <validator-id>ConditionalBeanValidator</validator-id>
        </default-validators>
        <validator>
            <validator-id>ConditionalBeanValidator</validator-id>
            <validator-class>de.gedoplan.blog.jsf.validation.ConditionalBeanValidator</validator-class>
        </validator>
    </application>
public class ConditionalBeanValidator extends BeanValidator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value) {
        setValidationGroups(retrieveValidationGroup(context));
        super.validate(context, component, value);
    }

    private String retrieveValidationGroup(FacesContext context) {
        if (context.getExternalContext().getRequestParameterValuesMap().containsKey("GEDTRANSMIT")) {
            return OnTransmit.class.getName();
        }

        return null;

    }
}

Dieser Validator ( implementiert javax.faces.validator.BeanValidator ) kann nun entscheiden/festlegen welche Bean Validation Gruppen verwendet werden sollen, ganz global, ohne das wir jedes einzelne Eingabefeld mit einem entsprechenden Binding versehen müssen. Idealerweise dient dafür ein fachliches Statusfeld, sollte so etwas nicht vorhanden sein ist auch folgendes Vorgehen über einen entsprechenden HTTP Parameter der beim Button angegeben wird denkbar:

                <h:commandButton action="#{demoController.submit()}" value="submit" id="submit"/>
                <h:commandButton action="#{demoController.transmit()}" value="transmit" id="transmit">
                    <f:param name="GEDTRANSMIT" />
                </h:commandButton>

Achtung! An dieser Stelle ist vorsicht geboten = in diesem Beispiel wird die Auswahl der Validierungs-Gruppe über einen Request-Parameter gesteuert, technisch wäre es durch Manipulation des HTTP Requests also möglich die transmit() Methode auf zu rufen ohne das die korrekte Validierung abläuft. Bei kritischen Prozessen sollte hier in der „transmit“ Methode (bzw. in einem entsprechenden Service) die korrekte Validierung (nocheinmal) durchgeführt werden oder zumindest das Vorhandensein des Parameters geprüft werden.

Github? Klaro

https://github.com/GEDOPLAN/jsf-custom-validator

Werbeanzeigen

Über Dominik Mathmann
Dominik Mathmann arbeitet als Berater, Entwickler und Trainer bei der GEDOPLAN GmbH. Auf Basis seiner langjährigen Erfahrung in der Implementierung von Java-EE-Anwendungen leitet er Seminare, hält Vorträge und unterstützt Kunden bei der Konzeption und Realisierung von Webanwendungen vom Backend bis zum Frontend. Sein derzeitiger Schwerpunkt liegt dabei auf der Entwicklung von JSF-Anwendungen. Er sieht die stärker werdende Position von JavaScript-Frameworks jedoch positiv und beschäftigt sich darüber hinaus mit Webframeworks wie AngularJS.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden /  Ändern )

Google Foto

Du kommentierst mit Deinem Google-Konto. Abmelden /  Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s

%d Bloggern gefällt das: