SeamFramework.orgCommunity Documentation
The JAX-RS specification defines the mechanism for exception mapping providers as the standard mechanism for Java exception handling. The Seam REST module comes with an alternative approach, which is more consistent with the CDI programming model. It is also easier to use and still remains portable.
The Seam REST module allows you to:
integrate with Seam Catch and thus handle exceptions that occur in different parts of an application uniformly;
define exception handling rules declaratively with annotations or XML.
Seam Catch handles exceptions within the Seam REST module: as result, an exception that occurs during an invocation of a JAX-RS service is routed through the Catch exception handling mechanism similar to the CDI event bus. This allows you to implement the exception handling logic in a loosely-coupled fashion.
The following code sample demonstrates a simple exception handler
that converts the
NoResultException
exception to a 404 HTTP response.
Example 36.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 handling
|
Similarly to the CDI event bus, exceptions handled by a handler
method can be filtered by qualifiers. The example above treats
only exceptions that occur in a JAX-RS service
invocation (as opposed to all exceptions of the given type that
occur in the application, for example in the view layer). Thus, the
@RestRequest
qualifier is used to enable the handler only for exceptions that occur
during JAX-RS service invocation.
Catch integration is optional and only enabled when Catch libraries are available on classpath. For more information on Seam Catch, refer to Seam Catch reference documentation .
Exception-mapping rules are often fairly simple. Thus, instead of being implemented programatically, they can be expressed declaratively through metadata such as Java annotations or XML. The Seam REST module supports both ways of declarative configurations.
For each exception type, you can specify a status code and an error message of the HTTP response.
You can configure Seam REST exception mapping directly in your Java code
with Java Annotations.
An exception mapping rule is defined as a
@ExceptionMapping
annotation. Use an
@ExceptionMapping.List
annotation to define multiple
exception mappings.
Example 36.2. Annotation-based exception mapping configuration
@ExceptionMapping.List({
@ExceptionMapping(exceptionType = NoResultException.class, status = 404, message = "Requested resource does not exist."),
@ExceptionMapping(exceptionType = IllegalArgumentException.class, status = 400, message = "Illegal argument value.")
})
@ApplicationPath("/api")
public MyApplication extends Application {
The
@ExceptionMapping
annotation can be applied on any Java class in the deployment.
However, it
is recommended to keep all exception mapping
declarations in the same place, for example, in the
javax.ws.rs.core.Application
subclass.
Table 36.1. @ExceptionMapping properties
Name | Required | Default value | Description |
---|---|---|---|
exceptionType | true | - | Fully-qualified class name of the exception class |
status | true | - | HTTP status code |
message | false | - | Error message sent within the HTTP response |
useExceptionMessage | false | false | Exception error message |
interpolateMessageBody | false | true | Enabling/disabling the EL interpolation of the error message |
useJaxb | false | true | Enabling/disabling wrapping of the error message within a JAXB object. This allows marshalling to various media formats such as application/xml, application/json, etc. |
As an alternative to the annotation-based configuration, you can use the Seam Config module to configure the SeamRestConfiguration
class in XML.
First, add the Seam Config module to the application. If you are using maven, you can do this by specifying the following dependency:
Example 36.3. Seam XML dependency added to the pom.xml file.
<dependency>
<groupId>org.jboss.seam.config</groupId>
<artifactId>seam-config-xml</artifactId>
<version>${seam.config.version}</version>
</dependency>
For more information on the Seam Config module, refer to the
Seam Config reference documentation.
Once you have added the Seam XML module, specify the configuration in the
seam-beans.xml
file, located in the
WEB-INF
or
META-INF
folder of the web archive.
Example 36.4. Exception mapping configuration in seam-beans.xml
<rest:SeamRestConfiguration>
<rest:mappings>
<s:value>
<rest:Mapping exceptionType="javax.persistence.NoResultException" statusCode="404">
<rest:message>Requested resource does not exist.</rest:message>
</rest:Mapping>
</s:value>
<s:value>
<rest:Mapping exceptionType="java.lang.IllegalArgumentException" statusCode="400">
<rest:message>Illegal value.</rest:message>
</rest:Mapping>
</s:value>
</rest:mappings>
</rest:SeamRestConfiguration>
Furthermore, you can use EL expressions in message templates to provide dynamic and more descriptive error messages.
Example 36.5. Exception mapping configuration in seam-beans.xml
<rest:Mapping exceptionType="javax.persistence.NoResultException" statusCode="404">
<rest:message>Requested resource (#{uriInfo.path}) does not exist.</rest:message>
</rest:Mapping>
When an exception occurs at runtime, the
SeamExceptionMapper
first looks for a matching exception mapping rule.
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 and is thus 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 36.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>