当前位置: 首页 > 知识库问答 >
问题:

特定类的异常处理/映射

徐博雅
2023-03-14

我有一个资源类,它本身与内部服务进行对话。此资源充当服务的rest API。服务层可以抛出意外异常,因此资源应该处理那些已处理的意外异常并将其记录下来。我正在使用dropwizard框架,它反过来又使用jersey。事情是这样的。

@PATH(/user)
@GET
public Response getUser(@QueryParam("id") String userId) {
   assertNotNull(userId);
   try {
      User user = service.getUser(userId);
      return Response.ok(user).build();
   }
   catch (MyOwnException moe) { //basically 400's
     return Response.status(400).entity(moe.getMsg()).build();
   }
   catch (Exception e) {   //unexpected exceptions

      logger.debug(e.getMessage);
      return Response.status(500).entity(moe.getMsg()).build();
   }
}

这里的问题是,我必须对每个REST apiendpoint执行完全相同的异常处理。我可以为这个特定的资源进行某种类型的异常映射,以便将所有的处理逻辑和日志记录放在那里吗?我知道我可以为jersey中的特定异常构建映射器,但这是针对整个模块而不是单个类的。

共有2个答案

欧阳狐若
2023-03-14

为什么不把异常处理分解成一个私有方法呢?

@PATH(/user)
@GET
public Response getUser(@QueryParam("id") String userId) {
    assertNotNull(userId);
    return handleExceptions(() -> {
        User user = service.getUser(userId);
        return Response.ok(user).build();
    });
}

private Response handleExceptions(Callable<Response> callable) {
    try {
        return callable.call();
    }
    catch (MyOwnException moe) { //basically 400's
        return Response.status(400).entity(moe.getMsg()).build();
    }
    catch (Exception e) {   //unexpected exceptions
        logger.debug(e.getMessage);
        return Response.status(500).entity(e.getMessage()).build();
    }
}
潘宝
2023-03-14

Afaig您不能将异常标记注册到资源方法。我已经通过实现一个动态特性来尝试了这一点,该特性正在寻找一个自定义注释,然后尝试用FeatureContext注册一个自定义的异常apper。

结果让人大跌眼镜:警告:类路径的给定约定(接口javax.ws.rs.ext.ExceptionMapper)。到CustomExceptionMapper提供程序无法绑定到资源方法

可能不起作用:

对于资源类,这实际上很容易。只需在ResourceConfig中为您的资源类注册ExceptionMapper。对我来说,它看起来像:

@ApplicationPath("/")
public class ApplicationResourceConfig extends ResourceConfig {
    public ApplicationResourceConfig() {
        // [...]
        register(YourExceptionMapper.class, YourResource.class);
        // [...]
    }
}

<罢工> 所以,如果您对在资源类级别上使用它没问题,请这样做。

否则,您可能需要使用方面 <罢工> (但我不认为有任何理由这样做) 。例子:

@Aspect
public class ResourceAspect {

    Logger logger = [...]

    private static final String RESOURCE = "execution(public !static javax.ws.rs.core.Response path.to.resources..*(..)) && @annotation(path.to.HandleMyOwnException)";

    @Around(RESOURCE)
    public Object translateRuntimeException(ProceedingJoinPoint p) throws Throwable {

        try {
            return p.proceed();
        } catch (MyOwnException moe) {
            return Response.status(400).entity(moe.getMsg()).build();
        } catch (Exception e) {   //unexpected exceptions
            logger.debug(e.getMessage);
            return Response.status(500).entity(e.getMessage()).build();
        }
    }

}

请注意,资源配置。这里它适用于路径下的非静态方法。到返回响应的资源,并用HandleMyOwnException注释。

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HandleMyOwnException {}
@GET
@PATH("/user")
@HandleMyOwnException
public Response getUser(@QueryParam("id") String userId) {
   assertNotNull(userId);
   return Response.ok(service.getUser(userId)).build();
}
<!-- deps -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.2</version> <!-- or newer version -->
</dependency>

<!-- build plugins -->
<plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.7</version>
        <configuration>
            <complianceLevel>1.8</complianceLevel>
            <showWeaveInfo>true</showWeaveInfo>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>compile</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
</plugins>
<pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.eclipse.m2e</groupId>
            <artifactId>lifecycle-mapping</artifactId>
            <version>1.0.0</version>
            <configuration>
                <lifecycleMappingMetadata>
                    <pluginExecutions>
                        <pluginExecution>
                            <pluginExecutionFilter>
                                <groupId>org.codehaus.mojo</groupId>
                                <artifactId>aspectj-maven-plugin</artifactId>
                                <versionRange>[1.7,)</versionRange>
                                <goals>
                                    <goal>compile</goal>
                                </goals>
                            </pluginExecutionFilter>
                            <action>
                                <ignore></ignore>
                            </action>
                        </pluginExecution>
                    </pluginExecutions>
                </lifecycleMappingMetadata>
            </configuration>
        </plugin>
    <plugins>
<pluginManagement>

祝您有个美好的一天!

~添加了更完整的pom。xml配置更正了ResourceAspect中缺少的注释路径

 类似资料:
  • 我有一个队列系统,骆驼只是其中的一小部分。在此队列系统中,对于某些队列,代理在队列已满时返回 FAIL。为了解决这个问题,我查看我得到的 JMS 异常,从消息中我可以看到原因是否是队列已满。 我想在Camel中实现的是,对于满队列的特定情况,我希望重试传递,而对于任何其他JMS异常(或任何其他异常),我希望将其发送到DLQ。 我假设我必须使用onException(JMSException.cla

  • 我使用netbeans创建了这个异常类: 当我尝试编译时,问题变得更加突出,在setter方法中,我得到以下消息: 错误:未报告异常异常;必须捕获或声明被抛出抛出新车辆异常(2,matricula);C:\users\ivan\desktop\examen isidrer\m03-uf5\exmaenm03uf5\src\info\infomila\vehicle.java:55:错误:未报告的异

  • 我一直在研究ControllerAdvice和ExceptionHandler注释,但我认为这两个注释都不能按照我们的预期使用。ControllerAdvice只能覆盖整个控制器,因此任何异常处理也将覆盖非Ajax方法。类似地,ExceptionHandler注释将处理来自这两种类型方法的异常。 目前的想法是将ajax和CRUD这两种类型的方法拆分为单独的控制器。还有别的办法吗?

  • 本文向大家介绍PHP异常处理Exception类,包括了PHP异常处理Exception类的使用技巧和注意事项,需要的朋友参考一下 异常(Exception)用于在指定的错误发生时改变脚本的正常流程。 什么是异常? PHP 5 提供了一种新的面向对象的错误处理方法。 异常处理用于在指定的错误(异常)情况发生时改变脚本的正常流程。这种情况称为异常。 当异常被触发时,通常会发生: 当前代码状态被保存

  • 我有一个带有REST方法的控制器类,可以抛出各种异常。我已经决定在一个单独的类中处理这些异常,在我的处理程序方法中使用@ControlllerAdwn和@ExceptionHandler。但是,我有一个问题,我的REST方法使用另一个库的注释。此库捕获REST方法引发的异常。现在,我正在全局处理异常,而不是直接通过REST方法中的试/捕获,我的异常总是被其他库捕获,而不是被我自己的处理程序方法捕获

  • 我正在构建一个颤振应用程序,我必须解析api中的一些数据,我设置了所有内容,但我收到了这个错误,我不知道为什么,我是颤振新手,任何帮助都将不胜感激。谢谢。 生成的错误 这是我的api响应示例 这就是我处理数据的方式 这是模型课