If you – like me – have the problem, that you need to run Tomcat or Glassfish or any other Java Webserver on Port 80, this might come handy for you:

The problem:
Tomcat, Jetty, Glassfish, JBoss AS etc. .. they all run on unprivileged ports > 1024, defaulting to 8080.

If you want to run them on port 80, you have several choices:
– front them with Apache
– front them with Squid
– use some tools like authbind, etc.
– use IPTables magic (which we will describe here)

Primitive IPTables solution:
This solution comes from the blog entry ” Installing Tomcat on port 80 with iptables
You have to compile NAT support into your kernel and use an iptables rule like this one

iptables -t nat -I PREROUTING --src 0/0 --dst $yourip -p tcp --dport 80 -j REDIRECT --to-ports 8080

which redirects all incoming traffic on port 80 on $yourip (e.g. 74.125.39.99) to port 8080 on the local machine.
If your webserver listens only to 127.0.0.1 this is all you need to be save.

However, I have a bit a different setup:

– Two networks with different providers (4mbit e.g. 74.125.39.99, 12mbit e.g. 98.137.149.56 )
– Two servers, one of them quite small powered (pentium4 on the 4mbit line), the other quite strong (dual quad core 2ghz on the 12mbit line)
– Glassfish on the strong server
– DNS load balancing for the domain
– both servers should map to the same glassfish instance.
– the servers are connected through a direct link with private IP-addresses (10.x.x.x range)
– Glassfish binds only to the private IP-Address of the strong server, meaning 10.0.100.10:8080
– both 74.125.39.99:80 and 98.137.149.56:80 should redirect the traffic to 10.0.100.10:8080

Here’s how I’ve done it (I got some inspiration from this linux questions forum entry):

On the “strong” server

#this forwards traffic to the internal ip
iptables -A PREROUTING -t nat -d 74.125.39.99/32 -p tcp -m tcp --dport 80 -j DNAT --to 10.0.100.10:8080
#this allows traffic on the external interface on port 80
iptables -A INPUT -d 74.125.39.99/32 -p tcp -m tcp --dport 80 -j ACCEPT
#this allows traffic on the internal ip on port 8080
iptables -A INPUT -d 10.0.100.10/32 -p tcp -m tcp --dport 8080 -j ACCEPT

nearly the same on the “weaker” server

#this forwards traffic to the internal ip
iptables -A PREROUTING -t nat -d 74.125.39.99/32 -p tcp -m tcp --dport 80 -j DNAT --to 10.0.100.10:8080
#this allows traffic on the external interface on port 80
iptables -A INPUT -d 98.137.149.56/32 -p tcp -m tcp --dport 80 -j ACCEPT

That’s it!

Perfectly save, perfectly scalable glassfish v3 (no apache bottleneck in your comet apps!)

As I sometimes need these, I have compiled a list of the valid headers of the web.xml and web-fragment.xml file for servlet version 2.3 until 3.0.
Maybe you find them as handy as I do.

web.xml v2.3

1
2
3
4
5
6
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
 
<web-app>
 
</web-app>

web.xml v2.4

1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 
</web-app>

web.xml v2.5

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
 
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
 
version="2.5">
 
</web-app>

web.xml v3.0

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
 
<web-app
        version="3.0"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 
</web-app>

web-fragment.xml:

1
2
3
4
5
6
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="
        http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd" version="3.0">
 
</web-fragment>

If you like to construct complex & pretty urls with JSF2 & PrettyFaces, you might be interested in the following few lines of code.

In our example, we want to match a URL like this one

1
http://www.studyguru.eu/at/tuwien/184.153--Entwurfsmethoden-fuer-verteilte-Systeme

Previously I tried to match it with a PrettyFaces Pattern/Regex like this:

       <pattern value="/([a-z]{2})/([a-z0-9\-_]*)/([a-z0-9\-_\.]*)\-\-.*"/>

But thankfully, PrettyFaces >2.0.4 supports directly populating the RequestParams!

Configure your pretty-config like this:

1
2
3
4
5
6
7
8
9
10
11
<pretty-config xmlns="http://ocpsoft.com/prettyfaces/2.0.4"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://ocpsoft.com/prettyfaces/2.0.4
                http://ocpsoft.com/xml/ns/prettyfaces/ocpsoft-pretty-faces-2.0.4.xsd">
....
 
    <url-mapping id="coursePage">
        <pattern value="/#{countryCode}/#{uniShortName}/#{courseId}--.*"/>
        <view-id>/path/to/coursePage.xhtml</view-id>
    </url-mapping>
....

and use JSF2’s viewParams like this:

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
        PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:pretty="http://ocpsoft.com/prettyfaces"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:p="http://primefaces.prime.com.tr/ui"
        >
<body>
<f:metadata>
    <f:viewParam id="countryCodeId"
                 required="true"
                 requiredMessage="Kein Land spezifiziert"
                 name="countryCode" value="#{coursePageBean.countryCode}"
            >
        <f:validateRegex pattern="([a-z]{2})"/>
    </f:viewParam>
 
    <f:viewParam id="universityCodeId"
                 required="true"
                 requiredMessage="Keine Hochschule spezifiziert"
                 name="uniShortName" value="#{coursePageBean.universityCode}"
            >
        <f:validateRegex pattern="([a-z0-9\-_]*)"/>
    </f:viewParam>
    <f:viewParam id="courseIdId"
                 required="true"
                 requiredMessage="Keine KursId spezifiziert"
                 name="courseId" value="#{coursePageBean.courseId}"
            >
        <f:validateRegex pattern="([a-z0-9\-_\.]*)"/>
    </f:viewParam>
 
    <f:event type="preRenderView" listener="#{coursePageBean.populate}"/>
</f:metadata>
<h1>coursePage</h1>
 
countryCode #{ coursePageBean.countryCode} <br/>
courseId #{coursePageBean.courseId}<br/>
universityCode #{coursePageBean.universityCode}<br/>
</body>
</html>

Voila! You now can match complex urls with PrettyFaces and apply all your custom validators
to your Pretty URL 🙂

I’ve noticed that google indexed various pages of mine with appended “;jsessionid=somehash”
Thats not only ugly, but also a security risk.

But how to disable Session Tracking by URL? How to set it to Cookie only ?

Take this!

Update: Jan Luehe showed me a way, how to do this in web.xml only – without a listener

1
2
3
4
5
6
7
 <web-app ...>
    <session-config>
        <tracking-mode>COOKIE</tracking-mode>
        <tracking-mode>URL</tracking-mode>
       <tracking-mode>SSL</tracking-mode>
    </session-config>
 </web-app>

if you prefer to do it programmatically (e.g. when doing a custom web-app configuration wizzard or something like this), do it this way:

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
package com.dominikdorn.dc.listeners;
 
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.SessionTrackingMode;
import javax.servlet.annotation.WebListener;
import java.util.HashSet;
import java.util.Set;
 
/**
 * This Listener sets the tracking modes used by the servletContext
 */
@WebListener(value = "This listener sets the session tracking modes")
public class SetSessionTrackingModeListener implements ServletContextListener {
 
    // Public constructor is required by servlet spec
 
    public SetSessionTrackingModeListener() {
    }
 
    public void contextInitialized(ServletContextEvent sce) {
        Set<SessionTrackingMode> modes = new HashSet<SessionTrackingMode>();
        // modes.add(SessionTrackingMode.URL); // thats the default behaviour!
        modes.add(SessionTrackingMode.COOKIE);
//        modes.add(SessionTrackingMode.SSL); // this works only with client certs.       
        sce.getServletContext().setSessionTrackingModes(modes);
    }
 
    public void contextDestroyed(ServletContextEvent sce) {
    }
 
}

Questions? Comments? Post them here!

A User on the glassfish mailing list posted a question:

I would like to aks it. How must set up ie8 compatibility mode in glassfish?
This is the iis setting:

<system.webServer>
       <httpProtocol>
               <customHeaders>
                       <clear />
                       <add name="X-UA-Compatible" value="IE=EmulateIE7" />
               </customHeaders>
       </httpProtocol>
</system.webServer>

Well… how to do that?

Simply create a Servlet Filter!

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
package com.dominikdorn.dc.filters;
 
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.Logger;
 
 
@WebFilter(urlPatterns = {"/*"}, initParams = {@WebInitParam(name = "compatibilityMode", value = "IE=EmulateIE7")})
public class UserAgentCompatibleFilter implements javax.servlet.Filter {
    private Logger log = Logger.getLogger("UserAgentCompatibleFilter");
    private String compatibilityMode;
 
    public void destroy() {
    }
 
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        if (compatibilityMode != null) {
            HttpServletResponse res = (HttpServletResponse) resp;
            res.addHeader("X-UA-Compatible", compatibilityMode);
        }
        chain.doFilter(req, resp);
    }
 
    public void init(FilterConfig config) throws ServletException {
        compatibilityMode = config.getInitParameter("compatibilityMode");
        if (compatibilityMode == null) {
            log.warning("No CompatibilityMode set for UserAgentCompatibleFilter, thus disabling it");
        }
    }
}

If you’re not using Servlet 3.0, simply comment out the @WebServlet annotation. If you want to customize
the header, add this to your web.xml and modify it, so that it suit your needs.

1
2
3
4
5
6
7
8
9
10
11
12
13
    <filter>
        <filter-name>UserAgentCompatibleFilter</filter-name>
        <filter-class>com.dominikdorn.dc.filters.UserAgentCompatibleFilter</filter-class>
        <init-param>
            <param-name>compatibilityMode</param-name>
            <param-value>IE=EmulateIE7</param-value>
        </init-param>
    </filter>
 
    <filter-mapping>
        <filter-name>UserAgentCompatibleFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

To see if it works, compile and redeploy your app.. you can then test it, e.g. with curl:

curl -D - http://localhost:8080/info.xhtml
HTTP/1.1 200 OK
X-Powered-By: Servlet/3.0
Server: GlassFish v3
Set-Cookie: JSESSIONID=3afbe6498aa3f495e8340d8e67ef; Path=/
X-UA-Compatible: IE=EmulateIE7
X-Powered-By: JSF/2.0
Content-Type: text/html;charset=UTF-8
Content-Length: 2997
Date: Tue, 09 Mar 2010 16:09:03 GMT

Suggestions? Comment here!

The “ironic programmer” published an article, how to create a really basic file upload with jsf2. He has not created any custom tags, but simply added a file-input field in his view and made the server populate a byte-array in his bean.

His post was influenced by Uploading files with JSF 2.0 and Servlet 3.0 by BalusC.

He probably missed our JSF2 FileUpload-Github-Project where the taglib is ready for usage and really simple to integrate.

Still, thumbs up for the nice post!

In the second part of this series, we are going to understand some more terminology of JAAS and start creating our own authentication system.

A LoginContext Object is used by applications to authenticate users independently of the underlying authentication technology. Authentication technology in this context means stuff like “file based authentication”, “Database based authentication”, “LDAP authentication”, “CERTIFICATE authentication” and so on.

The LoginContext class is part of the javax.security.auth.login package and describes methods used to authenticate Subjects/user in the meaning of Part 1 of this series). The documentation states:

A subject is an identity in a system that you want to authenticate and assign access rights to. A subject can be a human user, a process, or a machine..

which is basically what I said before. Its still a little bit unclear to me, why they use “user” in one documentation and “subject” in the other, but as its the same thing, we know what to do.

The documentation further states, that a subject may interact with different authorities (applications) and may have different passwords (credentials) for each of them. To represent the subject/user in these applications, the java.security.Principal class is used.

Our own LoginContext now invokes various LoginModules ( these handle the different ways of authentication, like form based, HTTP-Basic, HTTP-Digest, etc.). The LoginModule interface is part of
the javax.security.auth.spi package. If one ever wants to integrate Facebook connect or something similar, this is where to look at!

But how does the LoginContext know, which LoginModules to invoke? This is done by a Configuration Object.

So, to sum this up:

  1. We have 1-n LoginModules, handling different form of authentication.. file, db, ldap and so on
  2. We have a LoginContext, taking users credentials and supplying them to the LoginModules
  3. We have configurations, specifying which LoginModules should be used by the LoginContext
  4. A client supplies its credentials to the LoginContext. The LoginContext looks up, which LoginModules to use in its Configuration and authenticates the client with the provided credentials against the LoginModules.

But why bother with all this stuff of LoginContext, LoginModules, Configuration and so on? Shouldn’t it be easy to use authentication, especially custom authentication in a web-app?

Because we’ve already got it in our AppServer!

Configuration:
We’re actually creating our Configuration object manually in our web.xml.

Here we define, how we gain the authentication data from the user. In this example, I used auth-method=FORM because no-one wants to use HTTP-Basic Authentication anymore today!

    
        FORM
        nameOfTheRealm
        
            /login.xhtml
            /loginError.xhtml
        
    

With this configuration, you can already create your own login form with your preferred style, like this:
login.xhtml

1
2
3
4
5
<form method="post" action="#{request.contextPath}/j_security_check">
<label for="username">Userid</label><input type="text" id="username" name="j_username">
<label for="password">Password</label><input type="password" id="password" name="j_password">
<input type="submit" value="Login">
</form>

In the next part of the series, we’ll see how you can do it with an jsf/facelets page.

Ok, we now got our form for login. To Logout simply make a link to /j_security_logout

We’ve now got login + logout, but they are not working yet. What we still have to do, is specify, what we’re authenticating against. In this post, we called it LoginModule, in Glassfishv3 its called Realm and we have already
configured it with our Login-Config above.

A post which explains how to configure the simply, build in Glassfish “File-Realm” is available at DevelopInJava.com.

In the next blog entry of this series, we’ll see how we can create our own realm, that really suits our needs.

We now got everything needed for a basic authentication, but we don’t yet have a group to role mapping, which we need for stuff like #{request.isUserInRole(‘ADMIN’)} or annotating our beans (see later for all of that).
So what we’re going to do is, map the given “groups” to roles. Before we do that, we should tell our application, which roles we have. Do it like that in your web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    <security-role>
        <description>all the users with the role Admin</description>
        <role-name>ADMIN</role-name>
    </security-role>
 
    <security-role>
        <description>all the users that are authenticated</description>
        <role-name>LOGGEDIN_USER</role-name>
    </security-role>
 
    <security-role>
        <description>all the users that are moderators/extended rights</description>
        <role-name>MODERATOR</role-name>
    </security-role>

Now we can map the groups we get from the realm to our roles. We have to put this in
/WEB-INF/sun-web.xml (if you’re using Glassfish v3). My file looks like this:

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-web-app PUBLIC '-//Sun Microsystems, Inc.//DTD 
Application Server 9.0 Servlet 2.5//EN'
    'http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd'>
<sun-web-app error-url="">
    <context-root>/</context-root>
    <security-role-mapping>
        <role-name>LOGGEDIN_USER</role-name>
        <group-name>default</group-name>
    </security-role-mapping>
    <security-role-mapping>
        <role-name>MODERATOR</role-name>
        <group-name>moderatoren</group-name>
    </security-role-mapping>
    <security-role-mapping>
        <role-name>ADMIN</role-name>
        <group-name>root</group-name>
    </security-role-mapping>
    <class-loader delegate="true"/>
    <jsp-config>
        <property name="keepgenerated" value="true">
            <description>Keep a copy of the generated 
                servlet class' java code.</description>
        </property>
    </jsp-config>
</sun-web-app>

Click here to view the general structure of the sun-web.xml file.

Our User -> Principal, Group -> Role mapping now works. We can start protecting resources in our app! Horray!

We’re doing this by specifying “security-constraints” like this in our web.xml

1
2
3
4
5
6
7
8
9
10
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>admin-area</web-resource-name>
            <url-pattern>/admin/</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <description>admins should be allowed to access this resources</description>
            <role-name>ADMIN</role-name>
        </auth-constraint>
    </security-constraint>

This should be quite self-explanatory, for a detailed explanation take a look at
Security Annotations and Authorization in GlassFish and the Java EE 5 SDK, which also explains how to secure beans with annotations
and has a nice matrix whats possible with annotations and whats not.

If you want to lock some stuff for everyone, simply leave the auth-constraint element empty, like this:

1
2
3
4
5
6
7
8
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>admin-area</web-resource-name>
            <url-pattern>/admin/</url-pattern>
        </web-resource-collection>
        <auth-constraint>
        </auth-constraint>
    </security-constraint>

If you’ve followed these instructions and the one on the blog-post Securing a Web Application on Glassfish using JAAS, you should now be able to authenticate different users with different roles in your app using the File-Realm.

In the next articles of the series, we will look how to create an own realm, how to replace the form-based login with a JSF-Based one and how to work with roles in your JSF-Pages.

References:

Ok, this will be a multi-part blog entry series.
What I want to do with this blog entries, is to document, how to make your JSF2 application use JAAS ( Java Authentication and Authorization Service ) to manage your/my users, authenticate them through a form with
the help of the server and use that security information in our JSF2 pages and our Java Beans.

In this first part of the series, I’ll try to cover the terminology used in easy to understand words.

These are the terms, you’ll need to know:

  • realm: A realm is basically a "user database", being it a flat file with user/pass + group info, database tables or even an ldap directory or something else you can imagine, like facebook connect or google authentication system. It may be used by n applications.
  • user: A user is a person or program wishing to authenticate against our server/app. If you only make your website for real persons, these are your users. If you also offer a webservice, other programs accessing that service are also users. A user belongs to a realm, so may be valid in n applications (see principal below)
  • role: Roles are assigned to users and/or groups in an application. E.g. GUEST for a not authenticated visitor, LOGGEDIN_USER for an authenticated user, MODERATOR or ADMIN for special people.
  • group: Groups are like roles, but they are used over multiple applications and mapped to specific ROLES on an per-application-basis
  • principal: A Principal is an authenticated user in the scope of an application. The same user may have different principals in different applications. A principal is identified by its name and authenticated using authentication data (credentials)
  • security policy domain: Also called security domain or realm. Basically, the database where you lookup users. But in this meaning, its where the realms are used, being it application1, application2, applicationN
  • Security attributes: are attributes associated with every principal, like " is allowed to access the admin area" or stuff like that.
  • credential: contains or references security attributes; are used to authenticate a Principal for a Java EE product service (your webapp)
  • If you want to get the original documentation, take a look at the Security chapter in the Java EE 6 Tutorial Volume I

    Further references, which I’ll probably be using in the next posts of these series:

If you happen to localize your JSF Web-Application to German, you’ll probably have problems displaying German Umlauts ( äÄ, ö Ö, ü Ü, ß) in your page.

How to resolve this? Encode the umlauts with their Unicode code in your message-bundle like this

  1. ä = \u00e4
  2. Ä = \u00c4
  3. ö = \u00f6
  4. Ö =\u00d6
  5. ü = \u00fc
  6. Ü = \u00dc
  7. ß = \u00df

So, e.g. just specify it like this in your bundle.properties

1
homework=Haus\u00fcbung

Specify the bundle itself in your faces-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version='1.0' encoding='UTF-8'?>
 
<faces-config version="2.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
 
    <application>
        <resource-bundle>
            <base-name>/bundle</base-name>
            <var>bundle</var>
        </resource-bundle>
    </application>
</faces-config>

and use it in your facelets page example.xhtml like this:

1
#{bundle.homework}

or like this

1
<h:outputText value="#{bundle.homework}" />

If you don’t want to convert all the Umlauts in your bundle by hand, simply use javas

1
native2ascii

command to automatically encode the Umlauts in your bundle.properties file.

Update:
I found this unicode chart, which I think is quite useful!

Recently, I was looking for a way, to validate Email-Addresses with JSF.
I came accross this blog post on java.net:

It shows, how this would have been done in the old JSF 1.1/1.2 ways… But we’re in 2010 and do it now the following way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
            <h:panelGroup id="loginRegisterBox" layout="block">
                <p>
                    <h:outputLabel for="userEmail" value="#{bundle['register.emailaddress']}"/>
                    <h:inputText id="userEmail" value="#{loginRegisterBean.email}"
                                 validatorMessage="#{bundle.register_invalidEmail}"
                                 required="true"
                                 requiredMessage="#{bundle.registration_please_enter_email}"
                                >
                        <f:ajax event="change" execute="@this userEmail authorBox" render="@this loginRegisterBox"
                                listener="#{loginRegisterBean.emailChanged}"/>
                        <f:validateRegex pattern=".+@.+\.[a-z]+"/>
                    </h:inputText>
                    <h:message for="userEmail"/>
                </p>
....
</h:panelGroup>
....

What does this code? It sets the email property of the bean loginRegisterBean after the user changed the value and clicked out of the field (through ajax). It automatically validates the email address through the f:validateRegex pattern and updates the message ( h:message ) if the validation failed.

The Bean looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Named(value = "loginRegisterBean")
@SessionScoped
public class LoginRegisterBean implements Serializable {
 
....
 
     // also apply these restrictions on the property itself!
    @Pattern(regexp = ".+@.+\\.[a-z]+")
    @NotNull
    private String email;
....
    public void emailChanged(AjaxBehaviorEvent event) {
// do something
    }
...
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
}
top