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 2.1.
Seam Catch Integration -
NoResultException
handler
@HandlesExceptions
public class ExceptionHandler
{
@Inject @RestResource
ResponseBuilder 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 programmatically, 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 2.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 2.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 2.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 2.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 2.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 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>