Fighting with JSF Request charset: JBoss or Tomcat

After just spending a good amount of time troubleshooting an issue with character encoding in JSF + JBoss AS7 I thought I would throw up a few notes on the subject as there are lots of scattered bits floating around but no real clear explanation. Hopefully this does more than contribute to the scattered bits :-)

First lets start off with a little background on how servers and clients determine how to encode data for transfer

  • Server response to Client:

    • Server Encode: When a server is sending a response to a client with JSF it encodes the response based on the defined encoding of the file which is usually set at the top of a JSF XHTML file <?xml version="1.0" encoding="UTF-8"?> The server will also include a Content-Type in the response header sent to the client.

    • Client Decode: When the client receives a response it checks the Content-Type defined in the response headers to decide which charset to use for decode. However If the Content-Type is not listed in the response header then the client may check the page meta tags for a hint or default to ISO-8955-1

  • Client Request (POST) to Server:

    • Client Encode: The client will encode it’s request based on the encoding of the response it received from the server.

    • Server Decode: This is where things get a little tricky.

      • The request received from the client will likely lack any hint as to how things were encoded.

        • It may have a Accept-Charset defined, but that is simply informing the server which charset’s are valid for it’s response encoding.

        • It will also have a Content-Type which reflects the enctype set on the form element submitting this post. By default it is application/x-www-form-urlencoded. Notice no reference to the charset this request was encoded in.

        • Some requests like ajax requests will look like this application/x-www-form-urlencoded;charset=utf-8; This does work and Tomcat/JbossWeb will decode as utf-8 but I have not figured out how to force this on a non-ajax h:form

      • The catch here is that if there is not a charset defined in the request Content-Type then the request parameters will be decoded using ISO-8859-1.

So you’ve configured for pages for UTF-8 and ensured that your server responses are including a charset in the Content-Type. Everything is great until you submit the form and your UTF-8 encoded client request is decoded as ISO-8859-1. Depending on the data your users submit you may not even notice this in your app for weeks/months/years/never. But for example if user may submit something like I’m and you will get I’m

Once you accept that this is how things work, there is an easy way to fix this by adding the following snippet to your web.xml

<web-app>
      ...
    
        <filter>
          <filter-name>forceUTF8CharSet</filter-name>
          <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>
          <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
          </init-param>
        </filter>
    
        <filter-mapping>
          <filter-name>forceUTF8CharSet</filter-name>
          <url-pattern>*</url-pattern>
        </filter-mapping>
      ...
    </web-app>

This filter currently is in Tomcat 7.0.20 and up. If you are running JBoss 7 you can just grab the class from Github import it into your project. I’ve opened JBWEB-225 with JBoss Web to have this filter added.

tags: java jsf jboss
Cody Lerum - January 18, 2012

CDI Instance Injections and Session/Application Scoped Beans

If you’ve spent much time with CDI you invariably had a use case where you would prefer not to trigger an injection when the bean is initialized. This can be handy for example if it is an expensive action and the injected bean is only going be be invoked a small percentage of the time.

There is however caveat that is relevant. The beans produced by the Instance will live until the containing bean is destroyed.

This doesn’t cause an issue with Dependent, Request, View, or Conversation scoped beans, but it would cause a unexpected memory leak with Application or even Session scoped beans. Since the Instance could be invoked multiple times spanning hours or days with a @SessionScoped bean and potentially weeks or months with an @ApplicationScoped bean (if your lucky to run your app uninterrupted that long) the memory leak could bring your app to a halt.

Improvement are being made to the CDI 1.1 spec to handled this better CDI-139

But in the meantime the following will work nicely

@Inject
    BeanManager bm;
    
    public void run() {
    
      CreationalContext<Foo> ctx = bm.createCreationalContext(null);
      Bean<?> beans = BeanManagerTools.beans(bm, Foo.class);
      Foo f = bm.getReference(beans, Foo.class, ctx);
    
      //Do Work
    
      ctx.release();
    }

Calling the release at the end destroys all the beans created in the Context we initialized (ctx)

tags: java cdi
Cody Lerum - December 16, 2011

Fighting with empty github directories...and EGit

Occasionally I run into an issue where if I do a refactoring on my git project in eclipse that requires renaming a folder those folders will still show up on the github website (completely empty) even though they are not in the local workspace.

It appears that happens only when I commit the changes through eclipse via EGit via JGit. It appears to be https://bugs.eclipse.org/bugs/show_bug.cgi?id=314105

Anyway the easiest way to fix this is to do a commit outside of eclipse via the command line git. Once pushed to the remote the empty folders disappear.

tags: git github
Cody Lerum - February 28, 2011

Sorting Java Enums

Occasionally when working with JSF I have the need to display the values of a Java Enum in a pick-list.

public enum Cars {
      KIA,
      BMW,
      TOYOTA,
      FERRARI
    }

Returning an array of these values is easy enough. Cars.values();

The ordering of the values in the array is set by the ordinal value of the enum, or more simply the order which it appears in the source code. {"KIA", "BMW", "TOYOTA", FERRARI"}

Now depending on your application, if you need to change the order you can simply change the order they appear in the source code. However if you are like me and persisting these values to a database based on their ordinal value to save space then changing the order will break your application.

@NotNull
    @Column(columnDefinition = "tinyint")
    @Enumerated(EnumType.ORDINAL)
    public Cars getCar() {
      return car;
    }
    
    public void setEgressCodec(Cars car) {
      this.car = car;
    }

The first thing you might want to do is implement Comparable on the Enum and override the compareTo with your own to control the ordering. Unfortunately compareTo() is final on the Enum so we can’t override it.

Here is the solution that I’ve come up with.

First I create a new interface called ComparableEnum

ComparableEnum.java

public interface ComparableEnum {
      public String getDisplayName();
      public int getPriority();
      public boolean isDisplayed();
      public int ordinal();
    }

Then I can implement this on my Cars Enum using the cost a car as a value for the priority

Cars.java

public enum Cars implements ComparableEnum {
    
      KIA("Kia Motors", 15000, true),
      BMW("Bavarian Motor Works", 55000, true),
      TOYOTA("Toyota Motors", 35000, true),
      FERRARI("Ferrari S.p.A.", 150000, true)
    
      private String displayName;
      private int priority;
      private boolean displayed;
    
      private Cars(String displayName, int priority, boolean displayed) {
         this.displayName = displayName;
         this.priority = priority;
         this.displayed = displayed;
      }
      public String getDisplayName() {
         return displayName;
      }
      public int getPriority() {
         return priority;
      }
      public boolean isDisplayed() {
         return displayed;
      }
    }

Now it’s just a matter adding a couple comparators

EnumNameComparator.java

public class EnumNameComparator<T extends ComparableEnum> implements Comparator<T> {
      public int compare(T o1, T o2)
      {
         if (o1.getDisplayName().compareTo(o2.getDisplayName()) != 0){
            return o1.getDisplayName().compareTo(o2.getDisplayName());
         }
         else if (o1.toString().compareTo(o2.toString()) != 0) {
            return o1.toString().compareTo(o2.toString());
         }
         else {
            return new Integer(o1.ordinal()).compareTo(new Integer(o2.ordinal()));
         }
      }
    }

EnumPriorityComparator.java

public class EnumPriorityComparator<T extends ComparableEnum> implements Comparator<T> {
      public int compare(T o1, T o2)
      {
         if (new Integer(o1.getPriority()).compareTo(new Integer(o2.getPriority())) != 0)
         {
            return new Integer(o1.getPriority()).compareTo(new Integer(o2.getPriority()));
         }
         else if (o1.toString().compareTo(o2.toString()) != 0)
         {
            return o1.toString().compareTo(o2.toString());
         }
         else
         {
            return new Integer(o1.ordinal()).compareTo(new Integer(o2.ordinal()));
         }
      }
    }

Now I want to be able to sort these easily using any enum I have which implements Comparable enum so I add a generic method.

private static <T extends ComparableEnum> List<T> getEnumSortedByPriority(T[] t) {
      EnumPriorityComparator<T> c = new EnumPriorityComparator<T>();
      List<T> list = removeNonDispalyedValues(t);
      Collections.sort(list, c);
      return list;
    }

Now I can create a simple method to return my enum sorted how I wish

public static List<Cars> componentTypes() {
      return getEnumSortedByPriority(ComponentType.values());
    }
tags: java
Cody Lerum - May 21, 2010

Composite Primary Key with @ManyToOne

Here is a fun issue that I ran into the other day while working with a legacy database.

Three tables:

Nodes

  • NodeID(pk)

Interfaces

  • InterfaceID(pk)

  • NodeID(fk)

InterfaceTraffic_Detail

  • InterfaceID(pk)

  • DateTime(pk)

  • NodeID(fk)

The InterfaceTraffic_Detail table turned out to be a little tricky for me since I have never worked with composite indexes in hibernate. It took a little trial and error but here is what I came up with

My environment is Hibernate 3.4

NmsNode.java

@Name("nmsNode")
    @Entity
    @Table(name="Nodes")
    public class NmsNode implements Serializable {
      private static final long serialVersionUID = 1462044144509159489L;
    
      private int id;
      private List&lt;NmsInterface&gt; interfaces;
    
      @Id
      @Column(name="NodeID")
      public int getId() {
        return id;
      }
    
      public void setId(int id) {
        this.id = id;
      }
    
      @OneToMany(mappedBy="node", fetch=FetchType.LAZY)
      public List&lt;NmsInterface&gt; getInterfaces() {
        return interfaces;
      }
    
      public void setInterfaces(List&lt;NmsInterface&gt; interfaces) {
        this.interfaces = interfaces;
      }
    }

NmsInterface.java

@Name("nmsInterface")
    @Entity
    @Table(name="Interfaces")
    public class NmsInterface implements Serializable
    {
    
       private static final long serialVersionUID = 1L;
    
       private int id;
       private NmsNode node;
    
    
       @Id
       @Column(name="InterfaceID")
       public int getId()
       {
          return id;
       }
       public void setId(int id)
       {
          this.id = id;
       }
    
       @ManyToOne
       @JoinColumn(name="NodeID")
       public NmsNode getNode()
       {
          return node;
       }
       public void setNode(NmsNode node)
       {
          this.node = node;
       }
    }

InterfaceTraffic_Detail.java

@Entity
    @Table(name="InterfaceTraffic_Detail")
    @AssociationOverrides
       (
          {
               @AssociationOverride(name = "id.nmsInterface",
                     joinColumns = @JoinColumn(name = "InterfaceID"))
          }
       )
    public class InterfaceTraffic_Detail implements Serializable
    {
       private static final long serialVersionUID = 1L;
       private InterfaceTraffic_PrimaryKey id;
       private NmsNode nmsNode;
    
       @EmbeddedId
       @AttributeOverrides
       (
             {
                @AttributeOverride(name="id.dateTime", column=@Column(name="DateTime"))
             }
       )
       public InterfaceTraffic_PrimaryKey getId()
       {
          return id;
       }
       public void setId(InterfaceTraffic_PrimaryKey id)
       {
          this.id = id;
       }
       @ManyToOne
       @JoinColumn(name="NodeID")
       public NmsNode getNmsNode()
       {
          return nmsNode;
       }
       public void setNmsNode(NmsNode nmsNode)
       {
          this.nmsNode = nmsNode;
       }
    }

InterfaceTraffic_PrimaryKey.java

@Embeddable
    public class InterfaceTraffic_PrimaryKey implements Serializable
    {
       private static final long serialVersionUID = 1L;
       private NmsInterface nmsInterface;
       private Date dateTime;
    
       @ManyToOne
       public NmsInterface getNmsInterface()
       {
          return nmsInterface;
       }
       public void setNmsInterface(NmsInterface nmsInterface)
       {
          this.nmsInterface = nmsInterface;
       }
       public Date getDateTime()
       {
          return dateTime;
       }
       public void setDateTime(Date dateTime)
       {
          this.dateTime = dateTime;
       }
    
       public int hashCode() {
          return (int) dateTime.hashCode() + nmsInterface.getId();
      }
    
      public boolean equals(Object obj) {
          if (obj == this) return true;
          if (obj == null) return false;
          if (!(obj instanceof InterfaceTraffic_PrimaryKey)) return false;
          InterfaceTraffic_PrimaryKey pk = (InterfaceTraffic_PrimaryKey) obj;
          return pk.nmsInterface.getId() == nmsInterface.getId() &amp;&amp; pk.dateTime.equals(dateTime);
      }
    }

The important part here is the @EmbeddedId and @Embeddable on the InterfaceTraffic_Detail and InterfaceTraffic_PrimaryKey as well as the name "id.nmsInterface" on the @AssociationOverride so that I could reference the variable on the embedded class and define the @JoinColumn

Hopefully this saves someone else some time.

tags: java hibernate
Cody Lerum - January 12, 2010
About outjected.com

Outjected is an infrequent blog about the frequent issues and annoyances that pop up while coding.

These are living posts and will be updated as errors or improvements are found.
About Me
Google+