SeamFramework.orgCommunity Documentation
The JAX-RS specification defines Exception Mapping Providers as a standard mechanism for treating Java exceptions. The Seam REST module comes with and alternative approach which is more consistent with the CDI programming model, easier to use and still portable.
Firstly, Seam Catch is plugged in which allows exceptions that occur in different parts of an application to be treated uniformly. Besides, a builtin exception handler is provided which enables simple exception-mapping rules to be defined declaratively.
Seam Catch can be used within the Seam REST module for dealing with exceptions. As a result, an exception that occurs during an invocation of a JAX-RS service is routed through the Catch exception handling mechanism which is similar to the CDI event bus and lets exception handling logic to be implemented in a loosely-coupled fashion.
The following code sample demonstrates a simple exception handler
that converts the
NoResultException
exception to the 404 HTTP response.
Example 2.1. Seam Catch Integration - NoResultException handler
@HandlesExceptions
public class ExceptionHandler
{
@Inject @RestResourceResponseBuilder builder
public void handleException(@Handles @RestRequest CaughtException<NoResultException> event)
{
builder.status(404).entity("The requested resource does not exist.");
}
}
The
| |
The
| |
A method for hanling
|
Similarly to the CDI event bus, exceptions to be handled by a handler
method can be filtered by qualifiers. In the example above, we
are
only interested in exceptions that occur in a JAX-RS service
invocation. (As opposed to all exceptions of the given type that
occur in the application - in the view layer for example.) Thus, the
@RestRequest
qualifier is used.
Catch integration is optional and only enabled when Catch libraries are available on classpath. For more information on Seam Catch, see Seam Catch reference documentation .
Often, exception-mapping rules are simple. Thus, they do not really need to be implemented in Java. Instead, declarative approach is more appropriate in these situations. The Seam REST module allows exception types to be bound to HTTP responses declaratively.
For each exception type, it is possible to specify the status code and the error message of the HTTP response. There are two ways of exception mapping configuration in Seam REST.
Seam REST exception mapping can be configured from Java code.
Firstly, create an
ExceptionMappingConfiguration
subclass which
@Specializes
the provided one. Then, implement a
@PostConstruct
-annotated
method in which the
ExceptionMapping
definitions are added as shown in the following example.
Example 2.2. Programmatic exception mapping configuration
@Specializes
public class CustomExceptionMappingConfiguration extends ExceptionMappingConfiguration {
{
@PostConstruct
public void setup()
{
addExceptionMapping(new ExceptionMapping(NoResultException.class, 404, "Requested resource does not exist."));
addExceptionMapping(new ExceptionMapping(IllegalArgumentException.class, 400, "Illegal parameter value."));
}
}
Table 2.1. ExceptionMapping properties
Name | Required | Default value | Description |
---|---|---|---|
exceptionType | true | - | Fully-qualified class name of the exception class |
statusCode | true | - | HTTP status code |
message | false | - | Error message sent within the HTTP response |
interpolateMessageBody | false | true | Enables/Disables EL interpolation of the error message |
An alternative and more practical way of configuration is to use
the
Seam XML module to configure the
ExceptionMappingConfiguration
and
ExceptionMapping
classes in XML.
Firstly, the Seam XML module needs to be added to the application. If using maven, this can be done by specifying the following dependency:
Example 2.3. Seam XML dependency added to the pom.xml file.
<dependency>
<groupId>org.jboss.seam.xml</groupId>
<artifactId>seam-xml-config</artifactId>
<version>${seam.xml.version}</version>
</dependency>
For more information on the seam-xml module, refer to the
Seam XML reference documentation
Once the Seam XML module is added, specify the configuration in the
seam-beans.xml
file, located in the
WEB-INF
or
META-INF
folder of the web archive.
Example 2.4. Exception mapping configuration in seam-beans.xml
<exceptions:ExceptionMappingConfiguration>
<s:replaces/>
<exceptions:exceptionMappings>
<s:value>
<exceptions:ExceptionMapping exceptionType="javax.persistence.NoResultException" statusCode="404">
<exceptions:message>Requested resource does not exist.</exceptions:message>
</exceptions:ExceptionMapping>
</s:value>
<s:value>
<exceptions:ExceptionMapping exceptionType="java.lang.IllegalArgumentException" statusCode="400">
<exceptions:message>Illegal parameter value.</exceptions:message>
</exceptions:ExceptionMapping>
</s:value>
</exceptions:exceptionMappings>
</exceptions:ExceptionMappingConfiguration>
Furthermore, EL expressions can be used in message templates to provide dynamic and more descriptive error messages.
Example 2.5. Exception mapping configuration in seam-beans.xml
<exceptions:ExceptionMapping exceptionType="javax.persistence.NoResultException" statusCode="404">
<exceptions:message>Requested resource with id #{pathParameters['id']} does not exist.</exceptions:message>
</exceptions:ExceptionMapping>
When an exception occurs at runtime, the
SeamExceptionMapper
first looks for a matching
ExceptionMapping
.
If it finds one, it creates an HTTP response with the specified
status
code and error message.
The error message is marshalled within a JAXB object. As a result, the error message is available in multiple media formats. The most commonly used formats are XML and JSON. Most JAX-RS implementations provide media providers for both of these formats. In addition, the error message is also available in plain text.
Example 2.6. Sample HTTP response
HTTP/1.1 404 Not Found
Content-Type: application/xml
Content-Length: 123
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<error>
<message>Requested resource does not exist.</message>
</error>