SeamFramework.orgCommunity Documentation
Seam REST allows to create HTTP responses based on the defined templates. Instead of being bound to a particular templating engine, Seam REST comes with a support for multiple templating engines and support for others can be plugged in.
REST-based web services are often expected to return multiple representations of a resource. The templating support is useful for producing media formats such as XHTML and it can be also used instead of JAXB to produce domain-specific XML representations of a resource. Besides, almost any other representation of a resource can be described in a template.
To enable templating for a particular method, decorate the method with the
@ResponseTemplate
annotation. Path to a template file to be used for rendering is required.
Example 59.1.
@ResponseTemplate
in action
@ResponseTemplate("/freemarker/task.ftl")
public Task getTask(@PathParam("taskId") long taskId) {
...
}
The
@ResponseTemplate
annotation offers several other options. For example, it is possible for a method
to offer multiple representations
of a resource, each rendered with a different template.
In the example below, the
produces
member of the
@ResponseTemplate
annotation is used
to distinguish between produced media types.
Example 59.2.
Multiple
@ResponseTemplate
s
@GET
@Produces( { "application/json", "application/categories+xml", "application/categories-short+xml" })
@ResponseTemplate.List({
@ResponseTemplate(value = "/freemarker/categories.ftl", produces = "application/categories+xml"),
@ResponseTemplate(value = "/freemarker/categories-short.ftl", produces = "application/categories-short+xml")
})
public List<Category> getCategories()
Table 59.1.
@ResponseTemplate
options
Name | Required | Default value | Description |
---|---|---|---|
value
| true | - |
Path to the template (for example
/freemarker/categories.ftl
)
|
produces
| false | */* | Restriction of media type produced by the template (useful in situations when a method produces multiple media types, with different templates) |
responseName
| false | response | Name under which the object returned by the JAX-RS method is available in the template (for example, Hello ${response.name}) |
There are several ways of accessing the domain data within a template.
Firstly, the object returned by the JAX-RS method is available under the "response" name by default.
The object
can be made available under a different name using the
responseName
member of the
@ResponseTemplate
annotation.
Secondly, every bean reachable via an EL expression is available within a template.
Example 59.4. Using EL names in a template
#foreach(${student} in ${university.students})
<student>${student.name}</student>
#end
Note that the syntax of the expression depends on the particular
templating engine and mostly differs from
the syntax of EL expressions. For example,
${university.students}
must be used instead of
#{university.students}
in a FreeMarker template.
Last but not least, the model can be populated programmatically. In order to do that, inject the
TemplatingModel
bean and put the desired objects into the underlying
data
map. In the following example, the list of professors is available under the "professors" name.
Example 59.5. Defining model programmatically
@Inject
private TemplatingModel model;
@GET
@ResponseTemplate("/freemarker/university.ftl")
public University getUniversity()
{
// load university and professors
University university = ...
List<Professor> professors = ...
model.getData().put("professors", professors);
return university;
}
When using JAXB-annotated classes as a return type for JAX-RS methods, you may see the
following RESTEasy message:
“Could not find JAXBContextFinder for media type: text/html”
. This is caused by the built-in JAXB
provider being too eager. You can prevent the built-in JAXB provider from being used for a method by adding the
@DoNotUseJAXBProvider
annotation on the method.
Seam REST currently comes with built-in templating providers for FreeMarker and Apache Velocity.
FreeMarker is one of the most popular templating engines. To enable Seam REST FreeMarker support, bundle the FreeMarker jar with the web application.
For more information on writing FreeMarker templates, refer to the FreeMarker Manual .
Apache Velocity is another popular Java-based templating engine. Similarly to FreeMarker support, Velocity support is enabled automatically if Velocity libraries are detected on the classpath.
For more information on writing Velocity templates, refer to the Apache Velocity User Guide
All that needs to be done to extend the set of supported templating engines is to implement
the
TemplatingProvider
interface. Refer to
Javadoc
for hints.
In certain deployment scenarios it is not possible to control the classpath completely and multiple template engines may be available at the same time. If that happens, Seam REST fails to operate with the following message:
Multiple TemplatingProviders found on classpath. Select the preferred one.
In such case, define the preferred templating engine in the XML
configuration as demonstrated below to resolve
the TemplatingProvider
ambiguity.
Example 59.6. Preferred provider
<beans xmlns:rest="urn:java:org.jboss.seam.rest:org.jboss.seam.rest.exceptions">
<rest:SeamRestConfiguration preferedTemplatingProvider="org.jboss.seam.rest.templating.freemarker.FreeMarkerProvider">
</beans>
Table 59.2. Built-in templating providers
Name | FQCN |
---|---|
FreeMarker | org.jboss.seam.rest.templating.freemarker.FreeMarkerProvider |
Apache Velocity | org.jboss.seam.rest.templating.velocity.VelocityProvider |