Phil Webb's Blog

Random thoughts from a software developer

Archive for the ‘Spring’ Category

Integrating Spring & JavaServer Faces : Exception Handling

with one comment

Most JSF developers will be familiar the “An Error Occurred” page that gets displayed when an unexpected exception is thrown somewhere their code. This page is really useful when developing but is not something you usually want for a production application. You generally have a couple of options when it comes to replacing this page with stock JSF; you can use define some HTML <error-page> elements in your web.xml or you can write a custom ExceptionHandler.

Neither option is ideal for a Spring developer, <error-page> elements tend to be too simplistic and it is hard to use Spring concepts, such as dependency injection, with custom ExceptionHandlers. Luckily both JSF and Spring are very extensible frameworks so a project that I have been working on to integrate the technologies can offer some compelling alternatives.

The first option available allows ExceptionHandlers to be registered as Spring beans. Rather than use the existing javax.faces.context.ExceptionHandler class a new org.springframework.springfaces.exceptionhandler.ExceptionHandler interface is available. The interface is pretty straight forward, it defines a single handle method that should return true if the exception has been handled. The interface uses a generic to limit the types of exception considered.

public interface ExceptionHandler<E extends Throwable> {
  boolean handle(E exception, ExceptionQueuedEvent event) throws Exception;
}

All relevant beans beans that implement the ExceptionHandler interface will be consulted when an exception occurs from JSF. The first handler to return true will ‘win’ and subsequent handlers will not be called. You can use the org.springframework.core.Ordered interface or the @Ordered annotation if you need to sort your handlers. Of course, now that exception handlers are regular Spring beans, you can use all the standard Spring functionality such a dependency injection and AOP.

Now that we have basic exception handler hooks we can go on to offer a couple of useful implementations:

Sometimes the best way to handle certain exceptions is to simply show a message and remain on the current screen. For example, suppose a service throws TooManyResultsException when search queries are too broad. A simple message telling the user to ‘try again with more precise terms’ might be the only exception handling required. The org.springframework.springfaces.exceptionhandler.ObjectMessageExceptionHandler class builds on previous work that maps Objects to messages. Include an entry in your Spring MessageSource with the fully qualified name of the Exception as the key and a FacesMessage will be shown if the exception is thrown.

com.mycorp.search.TooManyResultsException=Too many results found, please try again with more precise search terms

You can easily map any number of exceptions to messages, you can even refer to properties of the exception using ‘{property}‘ placeholders in your message string. Messages can be displayed on the screen using standard JSF techniques (usually a <h:messages/> component).

Support for quickly mapping exceptions to messages is nice but it won’t be enough for a lot of applications and writing ExceptionHandler beans can quickly become tiresome. The final optional available is org.springframework.springfaces.mvc.exceptionhandler.DispatcherExceptionHandler. The DispatcherExceptionHandler provides a bridge between JSF and Spring MVC that allows you to use @ExceptionHandler annotations in your @Controllers as you would with any other Spring MVC application. Methods annotated with @ExceptionHandler are really versatile and can have very flexible signatures; you can deal with exceptions directly or return a view that should be rendered:

@ExceptionHandler
public String handle(ExampleException e) {
  return "redirect:errorpage";
}

Using @ExceptionHandler annotations with Spring MVC is a very natural fit and there have been numerous articles written on the subject. Hopefully existing JSF developers will find the Spring MVC programming style an attractive alternative to standard JSF.

Please take a look at the other articles in this series and if you want to examine the exception handing code the ‘org.springframework.springfaces.exceptionhandler’ and ‘org.springframework.springfaces.mvc.exceptionhandler’ packages are a good place to start.

Written by Phillip Webb

June 29, 2012 at 8:34 am

Database testing using DBUnit, Spring and Annotations

with 31 comments

If you have ever tried writing database tests in Java you might have come across DBUnit. DBUnit allows you to setup and teardown your database so that it contains consistent rows that you can write tests against. You usually specify the rows that you want DBUnit to insert by writing a simple XML document, for example:

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
	<Person id="0" title="Mr" firstName="Dave" lastName="Smith"/>
	<Person id="1" title="Mrs" firstName="Jane" lastName="Doe"/>
</dataset>

You can also use the same format XML files to assert that a database contains specific rows.

DBUnit works especially well using in-memory databases, and if you work with Spring, setting them up is pretty straightforward. Here is a good article describing how to get started.

Working directly with DBUnit is fine, but after a while it can become apparent how many of your tests are following the same pattern of setting-up the database then testing the result. To cut down on this duplication you can use the spring-test-dbunit project. This project is hosted on GitHub and provides a new set of annotations that can be added to your test methods. Version 1.0.0 has just been released and is now available in the maven central repository:

<dependency>
  <groupId>com.github.springtestdbunit</groupId>
  <artifactId>spring-test-dbunit</artifactId>
  <version>1.0.0</version>
  <scope>test</scope>
</dependency>

Once installed three new annotations are available for use in your tests: @DatabaseSetup, @DatabaseTearDown and @ExpectedDatabase. All three can either be used on the test class or individual test methods.

The @DatabaseSetup and @DatabaseTearDown annotations are used to put your database into a consistent state, either before the test runs or after it has finished. You specify the dataset to use as the annotation value, for example:

@Test
@DatabaseSetup("sampleData.xml")
public void testFind() throws Exception {
  // test code
}

The @ExpectedDatabase annotation is used to verify the state of the database after the test has finished. As with the previous annotations you must specify the dataset to use.

@Test
@DatabaseSetup("sampleData.xml")
@ExpectedDatabase("expectedData.xml")
public void testRemove() throws Exception {
  // test code
}

You can use @ExpectedDatabase in a couple of different modes depending on how strict the verification should be (see the JavaDocs for details).

For the annotations to be processed you need to make sure that your test is using the DbUnitTestExecutionListener. See the project readme for full details. If you want to learn more there is an example project on GitHub and some walk-though instructions available here.

Written by Phillip Webb

April 23, 2012 at 12:52 am

Posted in DBUnit, Spring

Integrating Spring & JavaServer Faces : Improved Templating

with 3 comments

With the release of version 2.0 Facelet templating became a core part of the JSF specification. Using <ui:composition> and <ui:decorate> tags it becomes pretty easy to build up complicated pages whilst still keeping your mark-up clean. Templates are particularly useful when creating HTML forms but, unfortunately, do tend to cause repetition in your xhtml files, breaking the DRY (Don’t Repeat Yourself) principal of good software design. As part of a project to provide deeper integration between JSF and Spring I have developed a couple of new components that aim to make templating easier. Before diving into the new components, lets look at how a typical form might be built up using standard JSF templates.

Often the initial starting point with form templates is to add some boiler plate surround to each input. Often you need extra <div> or <span> tags for your css to use. Here is a typical example:

<!-- /WEB-INF/pages/entername.xhtml -->
<ui:decorate template="/WEB-INF/layout/form.xhtml">
  <h:inputText id="firstName" label="First Name" value="#{bean.firstName}"/>
  <ui:param name="label" value="First Name"/>
  <ui:param name="for" value="firstName"/>
</ui:decorate>
<ui:decorate template="/WEB-INF/layout/form.xhtml">
  <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}"/>
  <ui:param name="label" value="Last Name"/>
  <ui:param name="for" value="lastName"/>
</ui:decorate>
<!-- Many additional form elements -->
<!-- /WEB-INF/layout/form.xhtml -->
<ui:composition>
  <div class="formElement">
    <span class="formLabel">
      <h:outputLabel for="#{for}" label="#{label}">
    </span>
    <ui:insert/>
  </div>
</ui:composition>

Here we can see that each item on the form is contained within a <div> and form labels are wrapped in an additional <span>. There is already some repetition in the mark-up, with the “for” parameter mirroring the component ID. I have also given each <h:inputText> element a label attribute
for better validation error messages, this is repeated in the “label” <ui:param>. Things start getting worse if we want to mark required fields with an asterisk:

<!-- /WEB-INF/pages/entername.xhtml -->
<ui:decorate template="/WEB-INF/layout/form.xhtml">
  <h:inputText id="firstName" label="First Name" value="#{bean.firstName}" required="false"/>
  <ui:param name="label" value="First Name"/>
  <ui:param name="for" value="firstName"/>
  <ui:param name="showAsterisk" value="false"/>
</ui:decorate>
<ui:decorate template="/WEB-INF/layout/form.xhtml">
  <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}" required="true"/>
  <ui:param name="label" value="Last Name"/>
  <ui:param name="for" value="lastName"/>
  <ui:param name="showAsterisk" value="true"/>
</ui:decorate>
<!-- Many additional form elements -->
<!-- /WEB-INF/layout/form.xhtml -->
<ui:composition>
  <div class="formElement">
    <span class="formLabel">
      <h:outputLabel for="#{for}" label="#{label}#{showAsterisk ? ' *' : ''}">
    </span>
    <ui:insert/>
  </div>
</ui:composition>

It’s pretty frustrating that we need to pass <ui:param> items that duplicate attributes already specified on the <h:inputText>. It is easy to see how, even for relatively small forms, we are going to end up with a lot of duplication in our mark-up. What we need is a way to get information about the inserted component inside the template, even though we don’t know what type of component it will be. What we need is <s:componentInfo>.

The <s:componentInfo> component exposes a variable containing information about the inserted component. This information includes the label, the component clientID and if the component is required. By inspecting the inserted item we can remove a lot of duplication:

<!-- /WEB-INF/pages/entername.xhtml -->
<ui:decorate template="/WEB-INF/layout/form.xhtml">
  <h:inputText id="firstName" label="First Name" value="#{bean.firstName}" required="false"/>
</ui:decorate>
<ui:decorate template="/WEB-INF/layout/form.xhtml">
  <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}" required="true"/>
</ui:decorate>
<!-- Many additional form elements -->
<!-- /WEB-INF/layout/form.xhtml -->
<ui:composition>
  <s:componentInfo var="info">
    <div class="formElement">
      <span class="#{info.valid ? 'formLabel' : 'formErrorLabel'}">
        <h:outputLabel for="#{info.for}" label="#{info.label}#{info.required ? ' *' : ''}">
      </span>
      <ui:insert/>
    </div>
  </s:componentInfo>
</ui:composition>

Something else that we can now do is tell if the inserted component has failed validation. Notice that the example above will pick the “formErrorLabel” CSS class for components that are not valid.

One interesting feature of having the new <s:componentInfo> component is that all the <ui:decorate> tags become identical. We have removed all the repetition inside the tag, but the tag itself is still repeated many times. Here we have one more trick that can help by introducing a new <s:decorateAll> tag. Using <s:decorateAll> allows use to apply a template once for every child component. Here is the updated form mark-up:

<!-- /WEB-INF/pages/entername.xhtml -->
<s:decorateAll template="/WEB-INF/layout/form.xhtml">
  <h:inputText id="firstName" label="First Name" value="#{bean.firstName}" required="false"/>
  <h:inputText id="lastName" label="Last Name" value="#{bean.lastName}" required="true"/>
  <!-- Many additional form elements -->
</s:decorateAll>
<!-- /WEB-INF/layout/form.xhtml -->
<ui:composition>
  <s:componentInfo var="info">
    <div class="formElement">
      <span class="#{info.valid ? 'formLabel' : 'formErrorLabel'}">
        <h:outputLabel for="#{info.for}" label="#{info.label}#{info.required ? ' *' : ''}">
      </span>
      <ui:insert/>
    </div>
  </s:componentInfo>
</ui:composition>

If you want to look at the source code for these components check out the org.springframework.springfaces.template.ui package on springfaces GitHub project.

Written by Phillip Webb

April 13, 2012 at 6:21 pm

Integrating Spring & JavaServer Faces : Select Items

leave a comment »

With JSF, to use comboboxes, listboxes and checkboxes, you need to be aware of the javax.faces.model.SelectItem class. A SelectItem represents a single selectable option; it contains both the information needed for rendering, and the value that should be bound if the item is selected. Most of the time SelectItems are constructed with a value and a label:

new SelectItem(Title.MISS, "Miss");

Working with SelectItems before JSF 2.0 was often tedious as you needed to write code to adapt your domain objects into SelectItems. JSF 2.0 has improved things a lot and you can now dynamically construct SelectItems using EL expressions. For example:

<h:selectOneMenu>
  <f:selectItems value="#{customerRepository.all}" var="customer" label="#{customer.name}"/>
</h:selectOneMenu>

This certainly helps to reduce the amount of boiler-plate code, however, I still think that there are things that we can do make SelectItems even easier to use, especially when working with Spring. With that in mind, I have been developing a <s:selectItems> component, intended as a drop-in replacement for <f:selectItems>.

The first thing we can do, is help to reduce boiler-plate typing by removing the need to specify a var attribute. With <s:selectItems>, if the var attribute is not specified then it will default to item. So the code above can be written:

<h:selectOneMenu>
  <s:selectItems value="#{customerRepository.all}" label="#{item.name}"/>
</h:selectOneMenu>

In the above example, the value is being bound to a repository Interface that returns a Collection of Customer entities. As with the standard <f:selectItems> components you can also bind to an Array or DataModel. In addition the new component also supports any comma separated String value.

<h:selectOneMenu>
  <s:selectItems value="Java, Spring, JavaServer Faces"/>
</h:selectOneMenu>

The next thing that <s:selectItems> can help with is null values. It is quite common to need a “Please Select” option in drop downs to represent nulls. In vanilla JSF this can often mean additional mark-up for each component:

<h:selectOneMenu>
  <f:selectItem label="--- Please Select ---" noSelectionOption="true" itemValue=""/>
  <s:selectItems value="'{items}"/>
</h:selectOneMenu>

Instead of needing this additional mark-up for each element, our component will automatically insert a “Please Select” option whenever it is linked to a UISelectOne component. You can use the includeNoSelectionOption attribute to override this behavior. The label used for the “no selection option” will default to “— Please Select —” but you can customize and internationalize this text easily by adding a org.springframework.context.MessageSource to your ApplicationContext that can resolve the code "spring.faces.noselectionoption".

On the subject of MessageSource, the <s:selectItems> component will, whenever possible, try to create the label of the SelectItem using a org.springframework.springfaces.message.ObjectMessageSource. I have blogged in the past about how to convert Objects to messages and this component simply makes use of those ideas.

The new component has helped us when creating the SelectItems to display, but what about dealing with form submit? How do you convert the submitted String option back to a real Object? in the initial example above, we are binding to JPA Customer entities; The values will display just fine, but when you submit a form a “Conversion Error” is displayed because JSF does not know how to get from the submitted String back to the Customer object. The usual answer here is to develop your own javax.faces.convert.Converter implementation, but this is often problematic. Often you your select item value will be some complex object that is hard to represent in its entirety as a String.

There is an interesting technique that you can use when writing a Converter that will be used with a UISelectOne or UISelectMany component. You actually only need write code to convert from the Object to a String, conversion in the other direction can be accomplished by iterating the SelectItems and returning the single Object value that, when converted to a String, matches your submitted value. You can read more about the idea in this blog post by Arjan Tijms. Using this technique with the <s:selectItems> component is really easy, simply provide a itemConverterStringValue attribute that will be used to create the unique getAsString() value:

<h:selectOneMenu>
  <s:selectItems value="#{customerRepository.all}" label="#{item.name}" itemConverterStringValue="#{item.id}"/>
</h:selectOneMenu>

In actual fact the itemConverterStringValue is optional. If you don’t specify it, the toString() method of the object will be used or, in the case of a JPA @Entity, the @ID field will automatically be used. You are still free to write and attach your own Converter if you need to, in such cases the itemConverterStringValue is ignored.

Finally that is one more trick that the <s:selectItems> can perform. If you select component is bound to a Boolean or an Enum then the value attribute can be completely omitted. The select items will be built based on all possible options that the binding supports (“Yes”/”No” for Booleans or the complete set of Enum values). This also works with typed collections. For example, the following will display the options “Java”, “Spring” and “JavaServer Faces” (assuming you have an appropriate ObjectMessageSource) :

public enum Technology {
  JAVA, SPRING, JAVASERVER_FACES
}
public class Bean implements Serializable {
  private Set<Technology> technologies = new HashSet<Technology>();
  // ... getters and setters
}
<h:selectManyCheckbox value="#{bean.technologies}">
  <s:selectItems/>
</h:selectManyCheckbox>

If you want to check out any of this code take a look at the org.springframework.springfaces.selectitems package from the GitHub Project.

Written by Phillip Webb

January 12, 2012 at 5:31 pm

Integrating Spring & JavaServer Faces : Internationalization and Localization

with 10 comments

If you are working on a JSF application that is targeted to multiple languages, you may well be familiar with the <f:loadBundle> tag. Even if your application does not support internationalization using message bundles is still probably a good idea. Under the hood the <f:loadBundle> tag reads messages from a Java java.util.ResourceBundle and, whilst this will work, Spring developers often prefer the org.springframework.context.MessageSource interface.

As an alternative to <f:loadBundle> I have been developing a new <s:messageSource> component that can be used to expose messages from any Spring MessageSource, as well as offering a few other advantages.

The new component is a drop-in replacement for <f:loadBundle>.

<s:messageSource source="#{messageSource}" var="messages"/>
<p>
  <h:outputText value="#{messages.hello}"/>
</p>

The source attribute can be any EL expression that resolves to a MessageSource instance. If the source is not specified the Spring ApplicationContext will be used. The var attribute is the name of the variable that will be used to access the messages.

Unlike standard JSF, the key of the message to load will be built from the ID of the page being rendered. For example, assuming the page above is from the file WEB-INF/pages/messages/simple.xhtml, the key used to load the hello message will be pages.messages.simple.hello. Using these compound keys prevents message key clashes and keeps the page mark-up nice and concise. You can use the prefix attribute to override this behaviour if you need to.

If you make reference to message in your XHTML that you have forgotten to define you will either see a warning message (when in development) or an exception will be thrown (when in production).

As with standard JSF, your messages and include place-holders for use with <h:outputFormat>

pages.message.simple.welcome=Welcome to {1} with {0}
<h:outputFormat value="#{messages.welcome}">
  <f:param value="Spring"/>
  <f:param value="JSF"/>
</h:outputFormat>

The <h:outputFormat> tag is a little bit verbose, so for convenience, Spring messages can be used as Maps. This allows you to reference place-holders in a much more concise way:

<h:outputText value="#{messages.welcome['Spring']['JSF']}"/>

The same syntax allows you to map Java objects to messages. By default objects are mapped by building a message key from class name. For example, the following class:

package org.example;
public class ExampleObject {
}

Can be referenced in JSF:

<h:outputText value="#{messages[exampleInstance]}"/>

Resolving to the following message:

org.example.ExampleObject=example

For enum objects the message key includes the enum name as well as the class:

package org.example;
public enum ExampleObject {
  ONE, //mapped to message key org.example.ExampleObject.ONE
  TWO  //mapped to message key org.example.ExampleObject.TWO
}

Object messages can also make reference to properties that should form part of the message:

org.example.PersonName=Name is {first} {last}
...

package org.example;
public class PersonName {
  ...
  public String getFirst() {...}
  public String getLast() {...}
}

You can also define your own object message strategies by using a message source that implements the org.springframework.springfaces.message.ObjectMessageSource interface.

If you want to check out any of this code take a look at the org.springframework.springfaces.message and org.springframework.springfaces.message.ui packages from the GitHub Project.

Written by Phillip Webb

November 15, 2011 at 5:55 pm

Integrating Spring & JavaServer Faces : Converters

with 2 comments

When working with any web framework, you invariable run into the need to convert data input by the user from a String to some other type. Both Spring and JSF have converter strategies to deal with this, although they are really quite different in both their design and capabilities. Lets start by looking at Spring.

Spring 3 introduced a whole new conversion framework that allows objects of any type to be converted to any other type (as long as an appropriate converter is registered). Keith Donald has written about how the new conversion process works. Spring MVC was also updated at version 3 to make use of the converter service when dealing with request parameters, for example, passing a String parameter to the following controller method:

@RequestMapping
public void example(@RequestParam Integer value)

will result in the StringToNumber converter (via the StringToNumberConverterFactory) running to create the equivalent Integer.

Unlike Spring, converters in JSF only deal with converting objects to and from Strings. The javax.faces.convert.Converter interface defines two methods: getAsString (used when rendering) converts an object to a string and getAsObject (used when decoding postbacks) converts a previously rendered string back to an object.

By default, you can register converters with JSF either by adding an entries to your faces-config.xml or by using the @FacesConverter annotation. I have been working to allow you to also register JSF converters by simply declaring them as Spring beans. Using Spring beans gives you a number of advantages over vanilla JSF. For example, you easily can inject other collaborator beans and you can use Spring AOP. To use the converter bean simply refer to its ID from JSF:

@Component
public class MyConverter implements Converter {
    @Autowire
    private MyHelper helper;
    ...
}
<h:inputText value=”#{bean.value}”>
    <f:converter converterId=”myConverter”/>
</h:inputText>

In order to save referencing the same converter ID over and over again, JSF allows you to register a converter “for” a particular class. To support this with Spring a new @ForClass annotation has been introduced:

@Component
@ForClass(MyCustomType.class)
public class MyConverter implements Converter {
    ...
}

The example above will use MyConverter every time an object of MyCustomType needs converting.

For convenience I have also provided a variant of javax.faces.convert.Converter that supports generics. The org.springframework.springfaces.convert.Converter interface has an identical signature to the standard JSF version. When using this interface with @ForClass you can also omit the value on the annotation:

@Component
@ForClass
public class MyConverter implements Converter<MyCustomType> {
    ...
}

You can also implement more complex “for class” bindings using the ConditionalForClass interface (see the JavaDoc for details).

Finally, there is also support for using JSF converters (no matter how they are registered) from Spring MVC. The GenericFacesConverter is a Spring ConditionalGenericConverter that, when registered, automatically delegates to JSF.

For example, assuming that MyConverter is registered for MyCustomType the following MVC mapping will work:

@RequestMapping("/example")
public void example(@RequestParam MyCustomType value) {
    ....
}

You can also use the @FacesConverterId annotation if you need to reference a specific JSF converter:

@RequestMapping("/example")
public void example(@RequestParam @FacesConverterId("myOtherConverter") MyOtherCustomType value) {
    ....
}

If you want to see this in action take a look at ConverterExampleController from the showcase application.

Written by Phillip Webb

October 8, 2011 at 4:30 pm

Integrating Spring & JavaServer Faces : Pagination

with 2 comments

When working with large datasets you often need to present data in a paged format. Pagination is an interesting problem because it tends to cut across all layers of your application, from the view tier though application services down to the raw calls to your database.

When it comes to fetching paged data there are some pretty good solutions available. If you are using JPA then you are probably familiar with the setFirstResult() and setMaxResult() methods available on javax.persistence.Query. Even better is the Spring Data JPA project that provides org.springframework.data.domain.Pageable and org.springframework.data.domain.Page interfaces for use directly in your repositories.

With JSF there are also some well documented methods of displaying and fetching paged data. The exact solution will depend on the component suite that you are using but most of them are based around creating a custom javax.faces.model.DataModel implementation. For example MyFaces have suggestions on their wiki, RichFaces have blogged about the problem and PrimeFaces provide a Lazy Loading DataTable.

Recently I have been trying to develop something to ease the burden of the JSF developer and remove the need to create the custom DataModels and the backing beans that expose them. The basic idea is that a JSF component will create a lazy loading DataModel on your behalf using EL expressions to fetch the data as it is need.

Here is an example:

<s:pagedData 
  var="myDataModel" 
  value="#{userRepository.findByLastName(
    backingBean.lastName, pageRequest.offset, pageRequest.pageSize)}" 
  pageSize="20" />

This will create a myDataModel variable that will fetch 20 rows of data at a time by calling userRepository.findByLastName(). The EL expression will be called several time as the DataModel is scrolled.

(I am assuming that you are using EL 2.2, if you an older server such as Tomcat 6 you may need to install an updated el-impl.jar.)

Each time the EL expression is called a pageRequest variable is made available. This variable provides access the following context information that may be required when fetching a page of data:

pageNumber The page number to display
pageSize The page size requested
offset The offset (first result)
sortColumn The column used to sort data
sortAscending If the sort is in ascending or descending order
filters A map of filters to apply

 
One problem with the DataModel created in the above example is that the total number of rows is unknown. To get this information we need to provide an additional expression:

<s:pagedData 
  value="#{userRepository.findByLastName(
    backingBean.lastName,pageRequest.offset, pageRequest.pageSize)}"
  rowCount="#{userRepository.countByLastName(backingBean.lastName)}" />

The example above has also dropped the var and pageSize attributes, this will use a default page size of 10 and use a variable name of pagedData.

If you have used Spring Data you may have noticed how similar the pageRequest variable is to the org.springframework.data.domain.Pageable interface. In fact, as long as Spring Data is on your classpath, pageRequest can be cast to Pageable. Furthermore the component understands the org.springframework.data.domain.Page object so you no longer need the rowCount expression.

Here is an example that calls a spring data repository and presents data using MyFaces Tomahawk components. This example also allows you to sort the data by clicking on a column header:

<s:pagedData value="#{userRepository.findByLastName(backingBean.lastName, pageRequest)}" />
<t:dataTable value="#{pagedData}" rows="#{pagedData.pageSize}" 
    sortColumn="#{pagedData.sortColumn}" sortAscending="#{pagedData.sortAscending}" var="user">
  <t:column>
    <f:facet name="header">
      <t:commandSortHeader columnName="name">
        <h:outputText value="User Name" />
      </t:commandSortHeader>
    </f:facet>
    <h:outputText value="#{user.name}" />
  </t:column>
  <f:facet name="footer">
    <t:dataScroller paginator="true" paginatorMaxPages="9" />
  </f:facet>
</t:dataTable>

One final trick up our sleeves is to ensure that when using PrimeFaces the created DataModel is compatible with org.primefaces.model.LazyDataModel. Here the same example as above but using PrimeFaces components:

<s:pagedData value="#{userRepository.findByLastName(backingBean.lastName, pageRequest)}" />
<p:dataTable value="#{pagedData}" rows="#{pagedData.pageSize}" 
    paginator="true" lazy="true" var="user">
  <p:column headerText="User Name" sortBy="#{user.name}">
    <h:outputText value="#{user.name}" />
  </p:column>
</p:dataTable>

If you want to take a look at any of the code for this it is available on GitHub (look at the org.springframework.springfaces.page.ui and org.springframework.springfaces.model packages). I also have a basic sample application showing page mark-up. As always this code is a moving target so you might encounter some problems running the demos.

Written by Phillip Webb

August 7, 2011 at 3:28 pm

Logging a full stacktrace in Spring Web Flow using a FlowExecutionListener

leave a comment »

One problem I sometimes encounter when using Spring Web Flow is that the root cause of exceptions get burred so deep that they are not always logged.

For example, say you have an end-state that calls a bean method, and that method throws an exception:

<end-state id="finish">
    <output name="result" value="someBean.processFinalResultAndSometimesThrow()">
</end-state>

You will probably end up with a log entry like this:

org.springframework.webflow.engine.FlowOutputMappingException: Errors occurred during output mapping in state 'finish' of flow 'exampleFlow'; errors = [[SourceAccessError@3f3a3f3a mapping = someBean.processFinalResultAndSometimesThrow(), code = 'evaluationException', error = true, errorCause = org.springframework.binding.expression.EvaluationException: An ELException occurred getting the value for expression 'someBean.processFinalResultAndSometimesThrow()' on context [class org.springframework.webflow.engine.impl.RequestControlContextImpl], originalValue = [null], mappedValue = [null]]]

We get information about the flow and the state where the error occurred, we even get the bean method that was called, but we don’t have a complete stack trace of the actual root cause. Luckily for us the root cause is available and to log it you need to do is write a FlowExecutionListener:

import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.binding.mapping.MappingResult;
import org.springframework.stereotype.Component;
import org.springframework.webflow.engine.FlowAttributeMappingException;
import org.springframework.webflow.execution.FlowExecutionException;
import org.springframework.webflow.execution.FlowExecutionListenerAdapter;
import org.springframework.webflow.execution.RequestContext;

public class LoggingFlowExecutionListener extends FlowExecutionListenerAdapter {
    private final Log logger = LogFactory.getLog(getClass());

    @Override
    @SuppressWarnings("unchecked")
    public void exceptionThrown(RequestContext context, FlowExecutionException exception) {
        if (exception instanceof FlowAttributeMappingException) {
            List<MappingResult> errors = ((FlowAttributeMappingException)exception).getMappingResults().getErrorResults();
            for (MappingResult error : errors) {
                if (error.getErrorCause() != null) {
                    logger.warn("FlowAttributeMappingException thown containing error : " + error.getErrorCause(), error.getErrorCause());
                }
            }
        }
    }
}

Attach the listener in usual web flow way and all exceptions will be logged, complete with full stack trace.

Written by Phillip Webb

July 11, 2011 at 1:56 pm

Posted in Web Flow

Integrating Spring & JavaServer Faces : Dynamic Navigation

leave a comment »

Often your JSF application will need to move beyond basic static navigation and start to make dynamic navigation decisions.  For example, you may want to redirect users based on their age.  Most JSF tutorials recommend that dynamic navigation is implemented by binding the action attribute of a command to a backing bean:

<h:commandButton action="#{bean.actionBasedOnAge}"/>
public String actionBasedOnAge() {
  if(age &lt; 12) {
    return "fetchadult";
  } else {
    return "ok"
  }
}

The example above shows how anyone under twelve is directed to 'fetchadult' instead of the usual 'ok'. Both the 'fetchadult' and 'ok' outcomes will need to have navigation rules defined in the faces-config.xml so that JSF knows what actual page to display.

When working with Spring MVC it is often more natural to have navigation logic contained in the @Controller bean. To help with this, implicit 'controller' and 'handler' variables are available when rendering JSF from MVC. The 'controller' variable provides access to the controller bean that was mapped to the original request, and the 'handler' variable to the underling MVC handler.  In Spring 3.0 'controller' and 'handler' are generally the same object. In Spring 3.1 however, the underlying MVC architecture is changing and 'handler' will generally be a org.springframework.web.method.HandlerMethod instance.

Here is a submit button that references the someNavigation() method of the the @Controller:

<h:commandButton action="#{controller.someNavigation"/>

Whilst accessing the controller bean is useful, it is not the ideal solution.  I prefer to use logical names in my JSF pages and map those the Java methods.  I also want an easy way to get back to data from the underlying model.

The @NavigationMapping annotation provides another, more flexible approach to handling navigation.  It works in a very similar way to @RequestMappings.  The annotation can be placed on any public method in your @Controller to map navigation outcomes to destinations.

<h:commandButton action="submit"/>
@NavigationMapping
public String onSubmit() {
  return "redirect:http://www.springsource.org";
}

If you need access to a backing bean the standard Spring @Value annotation can be used.  Any EL expression that the page can resolve can also be used on a navigation method parameter.

@NavigationMapping
public String onSubmit(@Value("#{person.age}") int age) {
...
}

Accessing model elements is even easier.  As long as you only have a single object of the type you want to access in your model, and it is not a simple type (int, String, etc), you don’t need any annotations:

@NavigationMapping
public String onSubmit(Person p) {
...
}

Other argument types can also be used (see the JavaDoc for a complete list).  For example, here is a navigation mapping that handles 'submit', 'cancel' and 'save' outcomes.  The injected arguments tell us the which of the three outcomes was clicked and provides access to the source UIComponent.

@NavigationMapping('submit','cancel','save')
public String handleNavigation(String outcome, UIComponent source) {
...
}

Return types are also equally flexible.  You can return view names as Strings, you can also use the same "@hotelsController.show" notation that I have previously blogged about.  You can also return View objects directly or you can use NavigationOutcome if you want to include implicit model items.

Finally, if you just want to render an immediate response you can use the @ResponseBody annotation or return a HttpEntity.  This works in exactly the same way as Spring.

Written by Phillip Webb

July 1, 2011 at 7:56 pm

Integrating Spring & JavaServer Faces : MVC Nuts and Bolts

with 3 comments

I have attempted to integrate JSF with Spring MVC in the past, and whilst my first attempt worked, it was far from ideal.  This time around I decided to take a few key decisions to help focus my efforts:

  • Drop backwards compatibility.  There is just too much work involved with supporting JSF 1.2 and too much good stuff coming up in Spring 3.1 to ignore.
  • MVC annotations are king.  @RequestMapping seems to be the preferred approach for most people; lets only support this and keep any custom annotations to a minimum.
  • Reduce dependencies.  It’s nice to reuse stuff but this is an integration project so the less there is to integrate the better.

With this in mind I decided to take the org.springframework.faces.mvc.JsfView class from Web Flow as my inspiration.  This class works really well because it only deals with the View in MVC, the Model and Controller remain entirely in the realm of Spring.   The only problem with JsfView is the lack of postback support.  We need to somehow detect the difference between the initial request for a view and any subsequent JSF postback.

Thanks to Spring MVC having a very flexible architecture this is entirely possible.  We can have multiple HandlerMapping and HandlerAdapter beans registered with the DispatcherServlet.  To support JSF we need something high up in this chain that can detect and deal with  postbacks, leaving anything that is not a postback to be dealt with in the usual way.  Here is the general sequence of events:

user               dispatcher    @controller
 |  /some/request      |              |
 |-------------------->|   maps to    |
 |                     |------------->|  creates
 |                     |              |------------> FacesView
 |                     |                             (/pages/file.xhtml)
 |                     |   render                        |
 |                     |-------------------------------->|
 |                     |                           [Delegate to JSF]
 |  response           |<--------------------------------|
 |<--------------------|
 |                     |
 |                     |
 | /some/request       |
 | (postback)          |
 |-------------------->|      postback handler
 |                     |--------->|
 |                     |    [Delegate to JSF]
 |  response           |<---------|
 |<--------------------|          |
 |                     |          |

 
The postback handler has a couple of interesting problems to deal with.  1) How do we know we are a postback.  2) How do we know what view to restore.  Obviously a postback will be a HTTP POST operation, but we cannot blindly assume that all POSTs are JSF postbacks.  We also need to know what XHTML file to restore, but this file is based on a decision taken by the @Controller of the last request.

The answer to both these problems is to write our own JSF ResponseStateManager.  The ResponseStateManager is part of JSFs state management infrastructure and is responsible for reading and writing component state.  Usually JSF will save the state data in the HTTP session and write a hidden form field within the page so it can be restored later.  Hooking into this mechanism we can write an additional field for MVC, the presence of the field lets us know that we have a postback and furthermore the value will let us know what XHTML file to restore.

With the postback handler in place we now have the best of both the Spring and JSF worlds.  We can use @RequestMapping annotations to build expressive URLs and JSF components to render complex web pages.  If want to we can even return different Views for the same URL based on entirely different technologies (for example by inspecting the HTTP header we might decide to return a JSF page or a XML document).

If you want to look at postback handler code it is available here.  The usual caveats of this being a moving codebase apply.

Written by Phillip Webb

June 20, 2011 at 7:15 pm