Site Network: Personal | Professional | Photography

Technical Blog

This blog will contain content related to Java, Seam, Security, my sites and projects, as well as other technical subjects I am interested in.

Comments and questions are welcome!

Archive for the ‘Seam’ Category

10MinuteMail and Form Submission Charsets in Seam/JSF

Thursday, March 4th, 2010

I launched a minor update to 10MinuteMail.com last night. It contained:

  1. Changed the mail domain to owlpic.com
  2. Updated the Russian language translation (thanks to Vladimir)
  3. Fixed a bug where replying to an e-mail using a non-latin character set would result in an unreadable e-mail (also thanks to Vladimir for pointing this out)

This last issue was an odd one to fix, so I wanted to document it here (although the same fix can be found elsewhere on the net).

10MinuteMail.com is pretty well internationalized. The site content is translated into over 30 languages and the pages are served as UTF-8. Incoming e-mails are also displayed using UTF-8 and display non-latin character sets correctly. However, until this latest release, if you replied to an e-mail using non-latin characters, the resulting e-mail contained gibberish instead of the correct characters.

I started off by adding UTF-8 as the specified character set for outgoing e-mails. That didn’t help. I added UTF-8 encoding declaration attribute to the form element. That didn’t help. Finally after some frustration, googling, and trying a ton of things, I discovered that for some reason, and I”m not sure if the bug is in JBoss, JSF, Seam, or where exactly, but you have to set the request objects character encoding programmatically for each request, otherwise it will use the wrong encoding on the form contents and you end up with gibberish. The easiest way to solve this that I’ve found so far is to create a small Servlet Filter that sets the encoding on the request, and add that filter in before your Seam filter in your web.xml. It worked for me.

The filter:

package com.digitalsanctuary.seam;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

/**
 * The Class UTF8Filter.
 */
public class UTF8Filter implements Filter {

    /** The Constant UTF_8. */
    private static final String UTF_8 = "UTF-8";

    /**
     * Destroy.
     *
     * @see javax.servlet.Filter#destroy()
     */
    public void destroy() {
    }

    /**
     * Do filter.
     *
     * @param pRequest
     *            the request
     * @param pResponse
     *            the response
     * @param pChain
     *            the chain
     * @throws IOException
     *             Signals that an I/O exception has occurred.
     * @throws ServletException
     *             the servlet exception
     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
     *      javax.servlet.FilterChain)
     */
    public void doFilter(ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain) throws IOException,
	    ServletException {
	pRequest.setCharacterEncoding(UTF_8);
	pChain.doFilter(pRequest, pResponse);
    }

    /**
     * Inits the.
     *
     * @param arg0
     *            the arg0
     * @throws ServletException
     *             the servlet exception
     * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
     */
    public void init(FilterConfig arg0) throws ServletException {
    }

}

An excerpt of web.xml:

....
	<filter>
		<filter-name>UTF8 Filter</filter-name>
		<filter-class>com.digitalsanctuary.seam.UTF8Filter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>UTF8 Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<filter>
		<filter-name>Seam Filter</filter-name>
		<filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>Seam Filter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
....

Does anyone have a better fix or know exactly why this happens?

Make Google Ignore JSESSIONID

Tuesday, February 16th, 2010

Search engines like Google will often index content with params like JSESSIONID and other session or conversation scope params. This causes two problems: first the links returned in the Google search results can have these parameters in them, resulting in “session not found” or other incompatible session state issues. Secondly it can cause a single page of content, to be indexed multiple times (with differing parameters) this diluting your page’s rank.

I’ve posted two solutions to this issue in the past: Using Apache to ReWrite URLs to remove JSESSIONID and a more advanced solution of using a Servlet Filter to avoid adding JSESSIONID for GoogleBot Requests.

Now there’s an even better way to handle this. Google has added an amazing new feature to their Webmaster Tools which allows you to specify how the GoogleBot indexer should handle various parameters. You can ignore certain parameters such as JSESSIONID, cid, and others, and also specifically not ignore other parameters such as productId, skuId, etc…

Log into your Google Webmaster Tools, and select the site you wish to work with. Under “Site Configuration” -> “Settings” there is a new section at the bottom called “Parameter handling”. Click on “adjust parameter settings” to expand the parameter handling configuration for your site. Sometimes Google will suggest various parameters it has discovered while crawling your site, and other times you just enter the parameters you want Google to ignore or pay attention to.

Google Webmaster Tools Parameter Handling Interface

This is a much more elegant solution to the JSESSIONID problem, and also allows you to easily handle other parameters your site may use for either session state or dynamic content generation correctly. The only downside is that this only impacts Google, whereas with the correct configuration my older two solutions can handle any Search Engine Bot. Maybe other search providers will or do provide a similar feature.

Seam 2.x Web Development

Tuesday, June 2nd, 2009
Seam 2.x Web Development by David Salter

Seam 2.x Web Development by David Salter

Packt Publishing just sent me a copy of their new Seam book entitled Seam 2.x Web Development. Authored by David Salter, it seems to be a well laid out practical guide to building web apps with Seam 2. I’ve only skimmed it so far, but will be posting an in-depth review once I’m able to read through it.

It’s great to have a book that covers the new features of Seam 2 and provides examples of common Web 2.0 requirements such as OpenID integration, AJAX/RIA interfaces, and multi-tabbed browsing support using conversation scoped components. Personally I’m interested in reading about the new(ish) Identity Manager API (which I haven’t played with yet) and trying to add OpenID support for the application I am currently building.

You can read the second chapter online here: Chapter 2: Developing Seam Applications and let me know what you think of it!

Environment specific mail auth and Seam’s MailSession

Tuesday, May 19th, 2009

If you are using Seam’s MailSession to send out going e-mail from your Seam application you can run into trouble if you have a mail server in any environment (dev, test, stage, prod) that allows outgoing mail based on the client’s IP address and does not use username and password based authentication.

The standard configuration for the MailSession is in the components.xml file and looks like this (if you’ve used SeamGen to create your project):

	<mail:mail-session host="@mailhost@" port="@mailport@" username="@mailusername@" password="@mailpassword@" />

Then each of your environments has a components-{env}.properties file, which is deployed out and used to populate the @variable@ placeholders in the components.xml file. For instance your components.dev.properties file might look like this:

jndiPattern=YourApp/#{ejbName}/local
debug=true
mailhost=mail.mydomain.com
mailport=25
mailusername=mailus3r
mailpassword=mailp4ss

Which works great. However, if for instance your production environment uses IP based mail authentication for outbound e-mail, you might try to set your components-prod.properties file to look like this:

jndiPattern=YourApp/#{ejbName}/local
debug=false
mailhost=prodmail.mydomain.com
mailport=25
mailusername=
mailpassword=

However, that ends up setting empty strings into the username and password member variables of the MailSession component, and unfortunately the logic which determines whether or not to authenticate with the mail server checks for nulls only. So with empty strings, it attempts to authenticate with the mail server using a blank username and password. Which fails, and causes an unhelpful Faces error (unless you turn on debug on the MailSession component).

I’ve logged a Jira ticket about it here: JBSEAM-4176

You can do a simple workaround by overriding the MailSession component with your own sub-class of the MailSession class. In your sub-class you can override the setUsername and setPassword methods, check for empty strings and set null into the member variable if the parameter is null or empty. Luckily the Seam Install precedence system makes it very easy to override the default Seam component.

package com.myapp.mail;

import static org.jboss.seam.ScopeType.APPLICATION;

import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;

/**
 * The Class MailSession. This is an overriding class designed to work around
 * https://jira.jboss.org/jira/browse/JBSEAM-4176
 */
@Name("org.jboss.seam.mail.mailSession")
@Install(precedence = org.jboss.seam.annotations.Install.APPLICATION, classDependencies = "javax.mail.Session")
@Scope(APPLICATION)
@BypassInterceptors
public class MailSession extends org.jboss.seam.mail.MailSession {

    @Override
    public void setPassword(String pPassword) {
	if (pPassword == null || pPassword.trim().length() == 0) {
	    super.setPassword(null);
	} else {
	    super.setPassword(pPassword);
	}
    }

    @Override
    public void setUsername(String pUsername) {
	if (pUsername == null || pUsername.trim().length() == 0) {
	    super.setUsername(null);
	} else {
	    super.setUsername(pUsername);
	}
    }

}

Make A Custom RichFaces Skin

Thursday, April 9th, 2009

Using RichFaces in your application makes it easy to build great rich interfaces without spending a ton of time writing custom JavaScript for the front end and the back-end support for the JavaScript calls. It ties into your JSF components easily and makes dynamic interaction easy to build. It also comes with a number of default skins which is great when you’re first starting to build out a new application because it gives it a nice polished look instead of just black and white unstyled elements.

However, once you you get your own site design in place, the RichFaces skins probably won’t match your design perfectly. You can always override any of the particular element styles using CSS, but if you want to quickly change the global look and feel for all the RichFaces components, the easiest thing to do is to create a customized RichFaces skin.

You should start with the RichFaces skin that most closely matches your design and build your custom skin based on that. The skins are defined in properties files in the RichFaces jar file under /META-INF/skins/. You can also just download them from here, to avoid having to unpack the jar file yourself: richfaces-skins.zip.

Copy the skin file that’s closest to your design into your project. If you’re using a Seam project created with seam-gen, you’re in luck because the ant build file is already setup to deploy RichFaces skins if you have them. Just drop the skinname.skin.properties file into the “resources” directory of your Seam project. Rename it to a custom name for your site’s skin, i.e. mysite.skin.properties.

Now you need to configure your application to use the new custom skin. Edit /resources/WEB-INF/web.xml, and change the org.richfaces.SKIN param to the name of your new skin:

   <context-param>
      <param-name>org.richfaces.SKIN</param-name>
      <param-value>mysite</param-value>
   </context-param>

Now you can edit the skin file to adjust the colors and look and feel of the skin to match your site’s design. The ant build file will automatically deploy the custom skin file into the war file.

There are also other ways to customize RichFaces and build custom skins including extending an existing skin, or using the new Plug-n-Skin feature, or using XCSS, etc… But this should get you started!