6.4.3. JAX-RS Response Handler

This handler returns the response information from the subsequent handler (resource (action) class or Request Body Conversion Handler) to the client. If an exception and error is thrown by the subsequent handler, constructs the response information corresponding to the error and exception, and returns it to the client.

This handler performs the following process.

The process flow is as follows.

../../../../_images/flow19.png

6.4.3.2. Module list

<dependency>
  <groupId>com.nablarch.framework</groupId>
  <artifactId>nablarch-fw-jaxrs</artifactId>
</dependency>

6.4.3.4. Generate responses in response to exceptions and errors

Generation of response information based on the exceptions and errors is performed by ErrorResponseBuilder configured in the errorResponseBuilder property. However, when the exception class that has occurred is HttpErrorResponse, HttpResponse that is returned from HttpErrorResponse#getResponse() is returned to the client.

If the setting is omitted, ErrorResponseBuilder of the default implementation will be used. If the default implementation cannot meet the project requirements, inherit the default implementation class.

A configuration example is shown below.

<component class="nablarch.fw.jaxrs.JaxRsResponseHandler">
  <property name="errorResponseBuilder">
    <component class="sample.SampleErrorResponseBuilder" />
  </property>
</component>

Important

Because ErrorResponseBuilder is responsible for generating responses in response to exceptions and errors, if an exception occurs during the processing of ErrorResponseBuilder, the response will not be generated and the response will not be returned to the client. Therefore, if you are customizing ErrorResponseBuilder in your project, ensure that no exceptions are thrown during the processing of ErrorResponseBuilder. If an exception is thrown during the processing of ErrorResponseBuilder, the framework logs the exception at the WARN level, generates a response with status code 500, and continues with the subsequent processing.

6.4.3.5. Log output in response to exceptions and errors

Log output in response to exceptions and errors is performed by JaxRsErrorLogWriter configured in the property errorLogWriter.

If the setting is omitted, JaxRsErrorLogWriter of the default implementation will be used. If the default implementation cannot meet the project requirements, inherit the default implementation class.

A configuration example is shown below.

<component class="nablarch.fw.jaxrs.JaxRsResponseHandler">
  <property name="errorLogWriter">
    <component class="sample.SampleJaxRsErrorLogWriter" />
  </property>
</component>

6.4.3.6. Expansion example

6.4.3.6.1. Configure a message in response to an error

In some cases, such as a validation error, etc., the error message may have to be configured in the response body and returned. For such cases, support by creating an inherited class of ErrorResponseBuilder.

An implementation example where a JSON format error message is configured in the response is shown below.

public class SampleErrorResponseBuilder extends ErrorResponseBuilder {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public HttpResponse build(final HttpRequest request,
            final ExecutionContext context, final Throwable throwable) {
        if (throwable instanceof ApplicationException) {
            return createResponseBody((ApplicationException) throwable);
        } else {
            return super.build(request, context, throwable);
        }
    }

    private HttpResponse createResponseBody(final ApplicationException ae) {
        final HttpResponse response = new HttpResponse(400);
        response.setContentType(MediaType.APPLICATION_JSON);

        // Generation process of error message is omitted

        try {
            response.write(objectMapper.writeValueAsString(errorMessages));
        } catch (JsonProcessingException ignored) {
            return new HttpResponse(500);
        }
        return response;
    }
}

6.4.3.6.2. Return individually defined error response for specific errors

For errors that occur in the subsequent process after this handler, error response defined with a particular status code or body may have to be returned.

In such cases, create an inherited class from ErrorResponseBuilder and implement the response generation process individually corresponding to the exception thrown.

An implementation example is shown below.

public class SampleErrorResponseBuilder extends ErrorResponseBuilder {

    @Override
    public HttpResponse build(final HttpRequest request,
            final ExecutionContext context, final Throwable throwable) {
        if (throwable instanceof NoDataException) {
            return new HttpResponse(404);
        } else {
            return super.build(request, context, throwable);
        }
    }
}

6.4.3.6.3. Add common processing to the response returned to the client

At any time, such as during normal times or when an error occurs, there are cases when the response returned to the client may want to specify a common response header to support CORS or security for the response.

To handle such cases, the framework provides the ResponseFinisher interface to finish the response. If it is necessary to add common processing to the response, simply create a class that implements the ResponseFinisher interface and specify it in the responseFinishers property of this handler.

Implementation and configuration examples are shown below.

public class CustomResponseFinisher implements ResponseFinisher {
    @Override
    public void finish(HttpRequest request, HttpResponse response, ExecutionContext context) {
        // Common processing, such as setting the response header.
    }
}
<component class="nablarch.fw.jaxrs.JaxRsResponseHandler">
  <property name="responseFinishers">
    <list>
      <!-- Specify a class that implements ResponseFinisher -->
      <component class="sample.CustomResponseFinisher" />
    </list>
  </property>
</component>

In some cases, an existing handler such as Secure Handler, which sets security-related response headers, may be used as a ResponseFinisher. To handle such cases, the framework provides the AdoptHandlerResponseFinisher class that applies the handler to ResponseFinisher.

The handlers that can be used with AdoptHandlerResponseFinisher are limited to handlers that do not create their own responses and change the responses returned by subsequent handlers.

An example of the use of AdoptHandlerResponseFinisher is shown below.

<component class="nablarch.fw.jaxrs.JaxRsResponseHandler">
  <property name="responseFinishers">
    <list>
      <!-- AdoptHandlerResponseFinisher -->
      <component class="nablarch.fw.jaxrs.AdoptHandlerResponseFinisher">
        <!-- Specify the handler for the handler property -->
        <property name="handler" ref="secureHandler" />
      </component>
    </list>
  </property>
</component>