50.4. 将例外映射到响应


概述

存在引发 WebApplicationException 异常的实例是不现实或不可能的。例如,您可能不希望捕获所有可能的例外情况,然后为它们创建一个 WebApplicationException。您可能还想使用自定义例外,以便更轻松地处理应用程序代码。

若要处理这些情况,您可以使用 JAX-RS API 实施自定义异常提供程序,该提供程序生成要发送到客户端的 Response 对象。通过实施 ExceptionMapper<E> 接口来创建自定义异常供应商。当与 Apache CXF 运行时注册时,每当引发 E 类型的异常时,将使用自定义提供程序。

如何选择异常映射程序

在两个情况下,使用异常映射程序:

  • 如果引发任何例外或其子类,则运行时将检查相应的异常映射程序。如果指定映射程序会抛出特定异常,则会选择一个例外映射程序。如果没有为引发特定例外的异常映射程序,则会选择异常最接近的超级分类的异常映射程序。
  • 默认情况下,WebApplicationException 将由默认 mapper WebApplicationExceptionMapper 处理。即使注册了额外的自定义映射程序,这可能会正确处理 WebApplicationException 异常(例如,自定义 RuntimeException mapper),也不会 使用自定义映射程序,并将改为使用 WebApplicationExceptionMapper

    这种行为可以改变,但通过将 Message 对象上的 default.wae.mapper.least.specific 属性设为 true 来更改。启用此选项后,默认的 WebApplicationExceptionMapper 会被重新委派到最低优先级,以便可以处理 WebApplicationException 异常(带有自定义 mapper)。例如,如果启用此选项,可以通过注册自定义 RuntimeException mapper 来捕获 WebApplicationException 异常。请参阅 “为 WebApplicationException 注册异常映射程序”一节

如果没有找到异常的 mapper,则异常嵌套在 ServletException 异常中,并传递到容器运行时。容器运行时将决定如何处理异常。

实施异常映射程序

通过实施 javax.ws.rs.ext.ExceptionMapper<E> 接口来创建异常映射程序。如 例 50.5 “异常映射程序界面” 所示,接口具有一个单一方法 toResponse(),它使用原始例外作为参数并返回 Response 对象。

例 50.5. 异常映射程序界面

public interface ExceptionMapper<E extends java.lang.Throwable>
{
  public Response toResponse(E exception);
}

例外映射程序创建的 Response 对象与任何其他 Response 对象一样由运行时处理。生成的对消费者的响应将包含在 Response 对象中封装的状态、标头和实体正文。

异常映射程序实现由运行时被视为提供程序。因此,它们必须与 @Provider 注释进行解码。

如果在异常 mapper 正在构建 Response 对象时出现异常,则运行时将向使用者发送状态为 500 Server Error 的响应。

例 50.6 “将例外映射到响应” 显示一个例外映射程序,它截获 Spring AccessDeniedException 异常异常,并生成带有 403 Forbidden 状态和空实体正文的响应。

例 50.6. 将例外映射到响应

import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;

import org.springframework.security.AccessDeniedException;

@Provider
public class SecurityExceptionMapper implements ExceptionMapper<AccessDeniedException>
{

  public Response toResponse(AccessDeniedException exception)
  {
    return Response.status(Response.Status.FORBIDDEN).build();
  }

}

该运行时将捕获任何 AccessDeniedException 例外,并创建没有实体正文和 403 状态的 Response 对象。然后,运行时将处理 Response 对象,因为它会正常的响应。结果是消费者会收到状态 403 的 HTTP 响应。

注册异常映射程序

在 JAX-RS 应用可以使用例外映射程序之前,例外映射程序必须使用运行时进行注册。异常映射程序使用应用配置文件中的 jaxrs:providers 元素在运行时注册。

jaxrs:providers 元素是 jaxrs:server 元素的子级,含有 bean 元素的列表。每个 bean 元素都定义一个例外映射程序。

例 50.7 “使用运行时注册异常映射程序” 显示配置为使用自定义例外映射 SecurityExceptionMapper 的 JAX-RS 服务器。

例 50.7. 使用运行时注册异常映射程序

<beans ...>
  <jaxrs:server id="customerService" address="/">
    ...
    <jaxrs:providers>
      <bean id="securityException" class="com.bar.providers.SecurityExceptionMapper"/>
    </jaxrs:providers>
  </jaxrs:server>
</beans>

为 WebApplicationException 注册异常映射程序

WebApplicationException 异常异常异常注册是一个特殊情况,因为这种异常类型由默认的 WebApplicationExceptionMapper 自动处理。通常,即使您注册了应该处理 WebApplicationException 的自定义映射程序,它仍然将继续由默认的 WebApplicationExceptionMapper 处理。要更改这个默认行为,您需要将 default.wae.mapper.least.specific 属性设置为 true

例如,以下 XML 代码显示了如何在 JAX-RS 端点上启用 default.wae.mapper.least.specific 属性:

<beans ...>
  <jaxrs:server id="customerService" address="/">
    ...
    <jaxrs:providers>
      <bean id="securityException" class="com.bar.providers.SecurityExceptionMapper"/>
    </jaxrs:providers>
    <jaxrs:properties>
      <entry key="default.wae.mapper.least.specific" value="true"/>
    </jaxrs:properties>
  </jaxrs:server>
</beans>

您还可以在拦截器中设置 default.wae.mapper.least.specific 属性,如下例所示:

// Java
public void handleMessage(Message message)
{
    m.put("default.wae.mapper.least.specific", true);
    ...
Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.