Pages

Thursday, May 23, 2013

How to map a State Pattern in Hibernate

Hi, in this post I will show how to map a class hierarchy that represents an implementation of the State Design Pattern in Hibernate.

This solution only applies when you already know beforehand the possible states of the Context role of the state pattern, so no states will be added in the future; otherwise another aproach would be more suitable that involves developing custom hibernate UserTypes


Class Diagram


Here is the picture of the basic class diagram that we'll use for mapping:




Hibernate Mapping


The ApplicationState object is mapped to the following SQL Table:

CREATE TABLE [APPLICATION_STATE](
[id] [int] NOT NULL,
[description] [nvarchar](50) NULL,
 CONSTRAINT [PK_APPLICATION_STATE] PRIMARY KEY CLUSTERED 
(
[id] ASC
)
)


Taking into account what we said about the fixed states that the Application can have, we'll suppose that the APPLICATION_STATE table is already populated with data and it will be a read-only entity.

The mapping file showed in the listing below, beside the two properties of the table, also includes reference to the subclasses.
It uses the id stored in the APPLICATION_STATE table as a discriminator value to identify and determine the apropiate concrete subclass at runtime.

<hibernate-mapping>
<class name="com.foo.ApplicationState" table="APPLICATION_STATE" polymorphism="implicit">    
    <cache usage="read-only"/>    
    <id name="id" column="id">
       <generator class="assigned" />
    </id>
    <discriminator insert="false" column="id" />
    <property name="description" column="description" />
    <subclass name="com.foo.PendingApplication" discriminator-value="0"/>
    <subclass name="com.foo.ApprovedApplication" discriminator-value="1"/>
    <subclass name="com.foo.RejectedApplication" discriminator-value="2"/>
</class>
</hibernate-mapping>


The Application mapping refers to the state as a simple "many-to-one" property.

<hibernate-mapping>
<class name="com.foo.Application" table="APPLICATION">
    ...
    <many-to-one
        name="state" column="stateId"
  outer-join="false"
  lazy="false"
  not-found="ignore"
        class="com.foo.ApplicationState" >
    </many-to-one>
    ...
</class>
</hibernate-mapping>


So when you load the Application object, hibernate automatically grabs the according concrete ApplicationState subclass, based on the stateId stored in the APPLICATION table.

Hope this is clear enough, comment if you any question.


References

Friday, March 1, 2013

How to use Google's guava library to filter and transform a collection

Guava library provides a very large and powerful set of functions over collections, caching, concurrency, annotations among other things.

In this post I will show you how to filter and transform ('map' in functional terms) a collection using guava. It's easy to understand and natural if you have experience in functional programming.

I'll start with a simple way to add items to a collection:

...
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
...
Iterables.addAll(dest, source);


This method simply adds all elements in source to dest. The signature of the addAll method is:

public static <T> boolean addAll(Collection<T> dest, Iterable<? extends T> source)

In this step I'll filter source:

Iterables.addAll(dest, Iterables.filter(source, Predicates.not(Predicates.containsPattern("\\.")));

I'm asuming that both dest and source are collections of Strings. In the previous line, I'm adding all elements in source that don't contain a ".".

Finally suppose you want to transform the source collection to add a suffix to each element before adding it to dest.

Iterables.addAll(dest, Iterables.transform(
    Iterables.filter(source, Predicates.not(Predicates.containsPattern("\\."))),
    new Function < String, String >() {
 public String apply(String input) {
     return input + ".xml";
 }
    }));

transform takes two arguments: the source Iterable and a Function that perform the transformation over each element in the source. Here I'm using String as both the type of the elements in the input collection and the elements in the returned collection, but transform can take a collection of some type and the function would return the collection of some other type, for example:

Iterables.addAll(dest, Iterables.transform(otherSource, new Function < Integer, String >() {
    public String apply(Integer input) {
 return input.toString();
    }
}));

That's it. Later I hope to post other uses's examples of this library.

Wednesday, January 23, 2013

Integration of Drools and spring to perform business logic validation in JSF

In a previous post I explained how to use AOP to perform custom validation in JSF. Here I will show how you can use the business logic framework Drools to perform validation based upon external (business) rules in conjunction with springframework.

In this example I will perform the bussiness rules validation inside an advice class, but you can implement the same mechanism to perform that validation inside a JSF backing bean or in a spring bean.

Inside your application-context.xml file add your advice in the following way:

<bean id="validatorAspect" 
   class="com.foo.aspects.BackingBeanValidatorAdvice" 
   factory-method="aspectOf">
<property name="resources">
<list>
<value>/com/foo/business/rules.drl</value>
</list>
</property>
</bean>

I'm assuming you have basic knowledge of Drool, I will not get into syntax details here, there is a lot of documentation in Drool's site; instead I will just present a simple validation rule file rules.drl:


package com.foo.business

import com.foo.model.ModelBean;
import com.foo.aspects.Error;

query "Error" ()
    error : Error()
end


rule "Rule 1"
when
   ModelBean( id == 32 && internalId not matches "(J|P|R) ([0-9]){6}")
then
   Error err = new Error();
   err.setSummary("Error in Model Bean. ");
   err.setDetail("Internal Id not matches format: (J, P o R) followed by whitespace and 6 digits");
   insert(err);
end

Error is just a simple Pojo containing two properties (summary and detail).

Then, you must fire the validation inside the advice class:
public aspect BackingBeanValidatorAdvice {

    private KnowledgeBase kbase;

    private StatefulKnowledgeSession ksession;
    
    private String[] resources;

    pointcut doSaveChanges() : execution(* com.foo.beans.BackingBean.saveChanges(..));

    void around() : doSaveChanges() {
        FacesContext context = FacesContext.getCurrentInstance();
        ModelBean mbean = context.getApplication().evaluateExpressionGet(context, "#{bBean.selected}", ModelBean.class); 

        this.init();
        this.getKsession().insert(mbean);
        this.getKsession().fireAllRules();

        QueryResults results = this.getKsession().getQueryResults("Error");
        if (results.size() > 0) {
            for (QueryResultsRow row : results) {
                Error err = (Error) row.get("error");
                context.addMessage("error", new FacesMessage(FacesMessage.SEVERITY_ERROR, err
                        .getSummary(), err.getDetail()));
            }
        }
        proceed();
    }

    public void init() {
        if (this.getKbase() == null) {
            KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
            for (int i = 0; i < this.getResources().length; i++) {
                String rule = this.getResources()[i];
                kbuilder.add(ResourceFactory.newInputStreamResource(this.getClass().getResourceAsStream(rule)),
                    ResourceType.DRL);
            }
    
            if (kbuilder.hasErrors()) {
                System.out.println(kbuilder.getErrors());
                return;
            }
            Collection < KnowledgePackage > kpkgs = kbuilder.getKnowledgePackages();
            KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
            kbase.addKnowledgePackages(kpkgs);
            this.setKbase(kbase);
        }
        this.setKsession(this.getKbase().newStatefulKnowledgeSession());       
    }
    
    public StatefulKnowledgeSession getKsession() {
        return ksession;
    }

    public void setKsession(StatefulKnowledgeSession ksessionToSet) {
        this.ksession = ksessionToSet;
    }

    public String[] getResources() {
        return resources;
    }

    public void setResources(String[] resourcesToSet) {
        this.resources = resourcesToSet;
    }

    public KnowledgeBase getKbase() {
        return kbase;
    }

    public void setKbase(KnowledgeBase kbase) {
        this.kbase = kbase;
    }    
}


That's it. In case the validation fails, a FacesMessage is added to the FacesContext and JSF is responsible for handling and showing the error in a jsf page, eg: <h:messages .../>

Wednesday, January 16, 2013

How to create a "Processing" panel in RichFaces

Supose you have a page with a form inside to edit some values, and you want to show a "Processing" or "Please Wait" message when you click on a "save" button on that form. In RichFaces you can use the popupPanel compoment to this purpose.

This article assumes you are using RichFaces 4, and JSF/Facelets

I've created this wait.xhtml file containing only the wait panel to favor reusability and maintainability.


<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j">

<a4j:status name="waitStatus" onstart="#{rich:component('wait')}.show();"
onstop="#{rich:component('wait')}.hide();" />
<rich:popupPanel id="wait" autosized="true"
modal="false" moveable="false" resizeable="false" zindex="2005">
<f:facet name="header">
<h:outputText value="Processing" />
</f:facet>
<h:outputText value="Please wait..." />
</rich:popupPanel>
</ui:composition>


In the page where you have the form, add the reference to that file:

...
<ui:include src="../wait.xhtml" />
</h:form>

Somewhere inside the form you'll have a "Save" button that processes the input:


<a4j:commandButton value="Save"
action="#{bBean.save}"
status="waitStatus"
oncomplete="if (#{facesContext.maximumSeverity==null}) #{rich:component('ap')}.hide(); return false;">
</a4j:commandButton>

The key part for the wait popup panel to appear only when the "Save" commandButton is clicked, is the status="waitStatus" that links the action of the commandButton to the a4j:status that opens the wait panel.

If you don't do it this way, the wait panel will popup upon every ajax call  in the editing form (autocomplete fields, a4j:ajax calls, etc).

Hope this helps, comment if you have problems with this approach.


Wednesday, January 9, 2013

Versioning a webapp using SVN revision as build number with maven

Versioning a webapp is useful for keeping track of bugs fixed, upgrades, libraries versions modifications, etc.

In this article I will show how to use SVN revision number as part of the version number of a webapp using the buildnumber-maven-plugin. Using that number makes things a lot easier in case you have to downgrade your application, reproduce a bug in a particular previous version, etc.

Here I will use the version format Major.Minor.SVNRevision. Major is a number manually assigned, Minor is a sequential number that is incremented automatically after every build, and SVNRevision is the revision number obtained from the SVN repository, you can easily modify this format to suit your needs. The whole number is generated by maven in the build process, ie when you execute mvn install on your project.

For this to work first of all you have to configure the scm section in your pom.xml:


<scm>
    <connection>scm:svn:https://svnserver/projectname/trunk</connection>
    <developerConnection>scm:svn:https://svnserver/projectname/trunk</developerConnection>
    <tag>HEAD</tag>
    <url>https://svnserver/projectname/trunk</url>
</scm>


Then, you must add the buildnumber plugin to the plugins section inside <build> tag

<plugin>

<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>generate-buildnumber</id>
<phase>prepare-package</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<doUpdate>true</doUpdate>
<providerImplementations>
<svn>javasvn</svn>
</providerImplementations> 
<useLastCommittedRevision>true</useLastCommittedRevision>
<buildNumberPropertyName>buildRevision</buildNumberPropertyName>
</configuration>
</execution>
<execution>
<id>generate-sequential</id>
<phase>prepare-package</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<buildNumberPropertiesFileLocation>src/main/resources/buildNumber.properties</buildNumberPropertiesFileLocation>
<format>{0,number,1'.'00}</format>
<items>
   <item>buildNumber0</item>
</items>
<buildNumberPropertyName>buildSequential</buildNumberPropertyName>
</configuration>
</execution>
</executions>
</plugin>

The plugin has two executions configured.

The first one is responsible for getting the svn revision number from the repository, the 
create goal is executed upon the prepare-package phase, that phase is reached automatically when you issue a build command on maven (install, package, release); the <buildNumberPropertyName> tag value creates a variable name that hold the revision number, later we'll see how it is used.

The second execution creates the sequential part of the version number, it references the
buildNumber.properties file that hold the last number used, which is automatically incremented by 1 after every build. The item tag indicates the name of the variable inside the properties file. The format of the generated number is 1.XX, where XX is the number obtained from the properties file, the plugin uses java.text.MessageFormat to format the number using {0,number,1'.'00} format in this case. Note that we use <buildNumberPropertyName> again to store the sequential number in a new variable.


Using the generated version number

Now that we already have the pom.xml configured to generate the version number, it's time to use it. I'll show you here how to put it in your application's home page but you can reference it elsewhere.

First, I'll declare two variables in the pom.xml that references the two variables created by the buildnumber plugin:

<properties>
    ...
    <webapp.version>${buildSequential}</webapp.version>
    <webapp.revision>${buildRevision}</webapp.revision>
</properties>

Then I'll add another plugin to my pom, maven-war-plugin that is responsible for the packaging and generation of the web application archive.

<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
<includes>
<include>index.html</include>
</includes>
</resource>
</webResources>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildRevision}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>

In the configuration of the plugin I indicate to filter index.html in order to replace variables included there by values computed from this pom. You can find more information about filtering in the plugin's site. I also added a default MANIFEST.MF file indicating the generated revision number as Implementation-Build value. That file is included inside the META-INF folder of the webapp.

Then, inside the index.html you can reference the variables declared earlier in the pom:

<html>
  <head>
    <title>Webapp's Name ${webapp.version} (Revision: ${webapp.revision})</title>
    ...
  </head>
  ...
</html>

That's all, when your application is packaged and deployed, you'll see in your home page the title indicating the version number, for example: Webapp's Name 1.23 (Revision: 4567)

Hope it helps. Comment if you have any problem using this approach.

Monday, January 7, 2013

Use aspectj-maven-plugin to perform custom validation in JSF

You can use AspectJ to do many things, but its potential arise when you use it in order to apply the SoC paradigm.
In this post I will show you how to use it to perform custom validation in the presentation layer of a JSF webapp. Later I will show how to use spring to define more generic pointcuts in your application.

Note: I'll asume you already have basic knowledge of AOP in general and AspectJ in particular. I will not get into syntax and terminology details here. You can consult AspectJ site for documentation and resources. You can also find some terms definitions used here in Captain Debug's Blog.

It is very straightforward to configure AspectJ when you are using maven in your project. All you have to do is to add the aspectj-maven-plugin in the build section of your pom.xml:

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
</plugin>

You have to add the aspectjrt and aspectjtools dependencies to the plugin in order to let maven find the necessary to compile the AspectJ source.


Then you can code the validation AspectJ advice BackingBeanValidatorAdvice.aj as a normal source file:

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
...

public aspect BackingBeanValidatorAdvice {

    pointcut doSaveChanges() : execution(* com.foo.beans.BackingBean.saveChanges(..));

    void around() : doSaveChanges() {
        FacesContext context = FacesContext.getCurrentInstance();
        BBean bbean = context.getApplication().evaluateExpressionGet(context, "#{bBean.selected}", BBean.class); 

        // perform custom validation

        // if validation fails
        if (..) {
         String sum = "...";
         String det = "...";
         context.addMessage("error", new FacesMessage(FacesMessage.SEVERITY_ERROR, sum, det);
         return;
        }
        proceed();
    }
}

Doing this, when your backing bean's saveChanges(..) method is invoked, the pointcut is reached and the advice performing the custom validation is executed. Then, back to the jsf page, you can show the error's custom message as usual using <h:messages ... />

As you can see, you can apply this mechanism also to perform logging, database audits, notifications, etc. That's precisely the potential of AspectJ used in conjunction with SoC design principle.


Automatic pointcut configuracion using Spring

In this article, you had to add the pointcut manually in your advice's source. If you are using springframework, you can configure the pointcuts in the application-context.xml. Here is an example of using AOP in spring to implement a database logging concern without modifying a single line of code in your existing application. In your application-context.xml file add the following:

...

<bean id="databaseAuditAutoProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
  <property name="beanNames">
<list>
<value>*Dao</value>
</list>
  </property>
  <property name="interceptorNames">
<list>
<value>regexpAdvisor</value>
</list>
  </property>
</bean>

<bean id="regexpAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice">
<ref local="databaseLoggerAuditAdvisor"/>
</property>
<property name="pointcut">
   <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="patterns">
<value>.*read.*,.*load.*,.*get.*,.*save.*,.*Username.*</value>
</property>
<property name="excludedPatterns">
<value>.*find.*,.*History.*</value>
</property>
   </bean>
</property>
</bean>

<bean id="databaseLoggerAuditAdvisor" class="com.foo.aspects.DatabaseLoggerAuditAdvice">
<property name="auditService" ref="auditService"/>
</bean>
...

The databaseAuditAutoProxy automatically create proxies for the beans names that match beanNames attribute. The regexpAdvisor references the advisor implementation itself and defines a pointcut that uses regular expressions to define method names to intercept.

Then you have to code the DatabaseLoggerAuditAdvice.aj class:

public class DatabaseLoggerAuditAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {

    private AuditService auditService;

    public LoggerAuditAdvice() {
    }

    /**
     * @see org.springframework.aop.MethodBeforeAdvice#before(java.lang.reflect.Method,
     *      java.lang.Object[], java.lang.Object)
     */
    public void before(Method method, Object[] args, Object target) throws Throwable {

        log = LogFactory.getLog(target.getClass());
        if (log.isInfoEnabled()) {
            Audit audit = new Audit();
            audit.setUsername(SecurityHelper.getUserName());
            audit.setTime(new Date());
            audit.setMethodName(method.getName());
            audit.setMethodArgumentsValue(ArrayUtils.toString(args, "null"));
            log.info(" [[[BEFORE]]] " + audit);
        }
    }

    /**
     * @see org.springframework.aop.AfterReturningAdvice#afterReturning(java.lang.Object,
     *      java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
     */
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {

        log = LogFactory.getLog(target.getClass());
        if (log.isInfoEnabled()) {
            Audit audit = new Audit();
            audit.setUsername(SecurityHelper.getUserName());
            audit.setTime(new Date());
            audit.setMethodName(method.getName());
            audit.setMethodArgumentsValue(ArrayUtils.toString(args, "null"));
            audit.setTarget(target.getClass().getSimpleName());
            log.info(" [[[AFTER]]] " + audit);
            this.getAuditService().save(audit);
        }
    }

    public void afterThrowing(Method m, Object[] args, Object target, Throwable ex) {
        log = LogFactory.getLog(target.getClass());
        log.error("Exception in method: " + m.getName() + " Exception is: " + ex.getMessage() + " for user "
            + SecurityHelper.getUserName());
    }

    public AuditService getAuditService() {
        return auditService;
    }

    public void setAuditService(AuditService auditServiceToSet) {
        this.auditService = auditServiceToSet;
    }
}

Hope it helps, comment and give feedback.

PS: If you get errors in your project, you have to make sure you have added  *.aj as source files, and to make the project as a "AspectJ Project", ie, add the AspectJ runtime. The method may vary depending on the IDE you are using. In Eclipse, you have to configure the project as an AspectJ Project (right click on the project, Configure > Convert to AspectJ Project..) and add *.aj fileset mapping to the source code in the Java Build Path of your project.


Monday, December 17, 2012

Solving character encoding issues in JSF

When developing a non-english webapp, you'll probably encounter some issues with special characters as "ñ", "á", etc, ie, when you input some of this characters in a text input field, you get those characters back from the server rendered as "Ö" or something similar.

The best approach is to use UTF-8 enconding all over the application so the response is not encoded differently depending of the place that handles that response.

This approach applies to:

  • Tomcat 6
  • Java 1.6
  • MyFaces 2.1.10
  • RichFaces 4.2.3-Final


The places to configure the encoding are:

  • server.xml in Tomcat

    It's neccesary to get Tomcat to encode GET parameters. This is done by adding the URIEncoding attribute to the HTTP connector.

          <Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8"
           .... />


  • Servlet Filter

    Implement a servlet filter to do the UTF-8 encoding of  the requests and responses:

    public class SetCharacterEncodingFilter implements Filter {
    
        protected String encoding = null;
        protected FilterConfig filterConfig = null;
        protected boolean ignore = true;
    
        /**
         * Take this filter out of service.
         */
        public void destroy() {
            this.encoding = null;
            this.filterConfig = null;
        }
    
        /**
         * Select and set (if specified) the character encoding to be used to
         * interpret request parameters for this request.
         * @param request The servlet request we are processing
         * @param result The servlet response we are creating
         * @param chain The filter chain we are processing
         * @exception IOException if an input/output error occurs
         * @exception ServletException if a servlet error occurs
         */
        public void doFilter(ServletRequest request, ServletResponse response,
                             FilterChain chain)
     throws IOException, ServletException {
    
            // Conditionally select and set the character encoding to be used
            if (ignore || (request.getCharacterEncoding() == null)) {
                String encoding = selectEncoding(request);
                if (encoding != null)
                    request.setCharacterEncoding(encoding);
            }
    
            response.setContentType("text/html; charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            // Pass control on to the next filter
            chain.doFilter(request, response);
        }
    
        /**
         * Place this filter into service.
         * @param filterConfig The filter configuration object
         */
        public void init(FilterConfig filterConfig) throws ServletException {
     this.filterConfig = filterConfig;
            this.encoding = filterConfig.getInitParameter("encoding");
            String value = filterConfig.getInitParameter("ignore");
            if (value == null)
                this.ignore = true;
            else if (value.equalsIgnoreCase("true"))
                this.ignore = true;
            else if (value.equalsIgnoreCase("yes"))
                this.ignore = true;
            else
                this.ignore = false;
        }
    
        /**
         * Select an appropriate character encoding to be used, based on the
         * characteristics of the current request and/or filter initialization
         * parameters.  If no character encoding should be set, return
         * null.
         * * The default implementation unconditionally returns the value configured
         * by the encoding initialization parameter for this
         * filter.
         *
         * @param request The servlet request we are processing
         */
        protected String selectEncoding(ServletRequest request) {
            return (this.encoding);
        }
    
    }
    
    

    Then you have to reference and map that filter in web.xml:

    <filter>
       <filter-name>SetCharacterEncodingFilter</filter-name>
       <filter-class>com.foo.filters.SetCharacterEncodingFilter</filter-class>
       <init-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
       </init-param>
    </filter>
    <filter-mapping>
       <filter-name>SetCharacterEncodingFilter</filter-name>
       <url-pattern>*.xhtml</url-pattern>
    </filter-mapping>


    Here I mapped only xhtml files because I'm also encoding the responses to UTF-8, so mapping images and other resources as UTF-8 will probably generate an encoding error.

  • .xhtml Files

    One final step is neccesary to ensure we have coherent encoding all across the webapp.

    The first line in the xhtml files must be:
    <?xml version="1.0" encoding="UTF-8"?>

         Then, inside the head tag of the xhtml, add the following meta tag:
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    This is a lot less painful if you are using facelet templating technique; if that is the case, you'd only have to add the line mentioned above in the master template instead of in every .xhtml file.





Hope this helps, comment if you have any problem using this aproach.