Jersey, the JAX-RS reference implementation, includes an MVC framework supporting the rendering of views by JSP templates. The application passes a model object to the framework, where the model object implements properties providing the data to render in the JSP template. Jersey exposes the model object to the JSP template as a request attribute named “it”. So to read a model property, a JSP template must evaluate an EL expression reading a property of this object, for example, ${it.propertyName}.

In Spring MVC, you don’t have to write a specific prefix at the start of an EL expression to read model data. The model is a key-value map, and the framework exposes every entry of the map as a request attribute.

To avoid cluttering JSP templates with “it.”, I wrote a custom ELResolver which exposes model properties as implicit objects, allowing a JSP template to read a model property with an EL expression like ${propertyName}.

A custom servlet context listener registers the custom ELResolver when the application starts. To use it, define a listener in the web.xml file:

<listener>
  <listener-class>com.github.pukkaone.jsp.ViewableModelELResolverListener</listener-class>
</listener>

Details

The custom ELResolver gets the model object from the request attribute named “it”, then uses reflection to resolve a name to a property of the object. Assuming the requested property name is key, the following steps are tried:

  • If the object is a Map, then lookup the value from the Map using key as the key.

  • If the object has a method named key with non-void return type, then use the return value from calling the method.

  • If the object has a method named `get`key with the first letter of key capitalized and non-void return type, then use the return value from calling the method.

  • If the object has a field named key, then get the field value.

Finally, if the value acquired from the previous steps is an object implementing Callable, then use the return value from invoking it.