【问题标题】:RESTEasy + spring, notfound exception not being caught in mapperRESTEasy + spring,未发现异常未在映射器中捕获
【发布时间】:2014-02-21 00:15:30
【问题描述】:

我有一些关于 REST 的资源可以正常工作,但是当我对无效 URL 进行 REST 调用时,JBoss 返回 404 html 异常。我想将其更改为 JSON 异常响应。我尝试创建映射器,但控件没有到达那里。我正在为参考添加我的映射器代码。

@Provider
@Produces(MediaType.APPLICATION_JSON)
public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> {

/**
 * Map an exception to a {@link javax.ws.rs.core.Response}.
 *
 * @param exception the exception to map to a response.
 * @return a response mapped from the supplied exception.
 */
@Override
public Response toResponse(final NotFoundException exception) {
    Map<String, Object> info = new HashMap<>();
    info.put("msg", exception.getMessage());
    info.put("date", new Date());
    info.put("details", "The requested resource hasn't been found");

    return Response
            .status(Response.Status.INTERNAL_SERVER_ERROR)
            .entity(info)
            .type(MediaType.APPLICATION_JSON)
            .build();
}

【问题讨论】:

  • 您是如何注册 NotFoundExceptionMapper 的?你是使用类路径扫描,在web.xml中注册,还是通过Spring检测?
  • @GregWhitaker 我认为提供者注释会注册。我的团队已经熟悉了 xml 配置,所以我试图用注释来做到这一点。您能否建议最好的方法。
  • 这取决于您是否在 web.xml 中启用了 providers.scan,或者您是否将 DI 框架配置为也扫描 @Provider 注释。你需要告诉我你当前是如何配置 Resteasy 的。
  • 我们正在使用基于简单注释的注册。
  • 我尝试了所有方法,但都没有奏效。

标签: java spring rest exception-handling resteasy


【解决方案1】:

您可以通过多种不同方式注册@Provider 注释类:

  1. 由 Resteasy 自动扫描为 ServletContextListener。
  2. 在 web.xml 中显式配置为 ServletContextListener。
  3. 明确配置为独立的javax.ws.rs.Application
  4. 由 IOC 容器(如 Spring)自动扫描。

Resteasy 自动扫描

通过设置 resteasy.scan.providers 上下文参数,将您的应用程序配置为自动扫描 web.xml 文件中的 @Provider 注释类。

<web-app>
   <listener>
      <listener-class>
         org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
      </listener-class>
   </listener>

    <context-param>
        <param-name>resteasy.scan.providers</param-name>
        <param-value>true</param-value>
    </context-param>

   <servlet>
      <servlet-name>Resteasy</servlet-name>
      <servlet-class>
         org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
      </servlet-class>
   </servlet>

   <servlet-mapping>
      <servlet-name>Resteasy</servlet-name>
      <url-pattern>/resteasy/*</url-pattern>
   </servlet-mapping>

</web-app>

注意:如果您在 JBoss 7 或更高版本上部署,请勿使用此选项。 @Provider 在 JBoss 7 及更高版本中自动启用,使用此值可能会导致应用程序启动期间出错。


在 web.xml 中显式配置

通过设置 resteasy.providers 上下文参数,可以在 web.xml 文件中向 Resteasy 显式注册提供程序。

<web-app>

    <context-param>
        <param-name>resteasy.providers</param-name>
        <param-value>com.foo.NotFoundExceptionMapper,com.foo.SomeOtherProvider</param-value>
    </context-param>

   ... All of the other HttpServletDispatcher and ResteasyBootstrap stuff like above.
</web-app>

显式配置为独立应用程序

如果您使用 javax.ws.rs.Application 类引导您的 Resteasy 服务,您可以按如下方式添加您的提供程序实现:

 public class FooApplication extends Application
 {
     private Set<Object> singletons = new HashSet<Object>();
     private Set<Class> classes = new HashSet<Class>();

     public FooApplication()
     { 
         classes.put(NotFoundExceptionMapper.class);
     }

     public Set<Class<?>> getClasses()
     {
         return classes;
     }

     public Set<Object> getSingletons()
     {
         return singletons;
     }
 }

Spring 自动扫描

如果您使用 Spring 扫描您的 Resteasy 提供程序,您需要告诉 Spring 您对 @Provider 注释感兴趣,并且您需要配置 Spring 以告诉 Resteasy 它已扫描的 bean。

异常映射器

您需要向您的提供程序添加一个@Component 注释,以便 Spring 知道扫描它。

@Component
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class NotFoundExceptionMapper implements ExceptionMapper<NotFoundException> 
{
   //Implementation removed for brevity...
}

Web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <!-- Spring Configuration -->
    <context-param>
        <param-name>contextClass</param-name>
        <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>

    <context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>com.foo.SpringConfig</param-value>
    </context-param>

    <!-- RESTEasy Configuration -->
    <listener>
        <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
    </listener>

    <context-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/v1</param-value>
    </context-param>

    <!-- RESTEasy <-> Spring Connector (Needed so that RESTEasy has access to Spring managed beans!) -->
    <listener>
        <listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
    </listener>

    <!-- RESTEasy HTTP Request Processor Servlet -->
    <servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/v1/*</url-pattern>
    </servlet-mapping>

</web-app>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    相关资源
    最近更新 更多