特殊类的异常处理/映射 [英] Exception Handling/Mapping for a particular class

查看:126
本文介绍了特殊类的异常处理/映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我拥有本身与内部服务谈判的资源类。此资源为该服务执行休息API。服务层可以抛出意外的异常,因此资源应该处理那些处理意外的异常并记录它。我正在使用dropwizard框架,而后者又使用球衣。它就像这样。

  @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){//基本上是400的
return Response.status(400).entity(moe.getMsg())。build();
}
catch(异常e){//意外异常

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

这里的问题是我必须这样做每个REST api端点的异常处理相同。我可以为这个特定的资源做一些异常映射,以便我可以把所有的处理逻辑和日志记录在那里?
我知道我可以为运动衫中的特殊异常构建一个映射器,但是整个模块不是一个类。

解决方案

Afaig你不能向资源方法注册一个 ExceptionMapper 。我已经通过实现一个 DynamicFeature 来寻求一个自定义注释,然后尝试注册一个自定义的 ExceptionMapper FeatureContext



结果令人失望:

警告:类path.to.CustomExceptionMapper提供程序的给定合同(接口javax.ws.rs.ext.ExceptionMapper)无法绑定到资源方法。



可能不工作:

但是...



对于资源类,其实很简单。在您的 ResourceConfig 中注册您的资源类的 ExceptionMapper 。对我来说,它看起来像:

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

所以如果你在资源类级别上可以这样做,就这样做。



否则,您可能需要使用Aspects (但我没有看到任何理由这样做) / EM> 。例如:



Aspect



  @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){//意外异常
logger.debug(e.getMessage);
return Response.status(500).entity(e.getMessage())。build();
}
}

}

请注意, RESOURCE config。这里它适用于 none 方法在 path.to.resources 下返回 Response 并与$ code> HandleMyOwnException 注释结合。



HandleMyOwnException



  @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HandleMyOwnException {}



ResourceMethod



  @GET 
@PATH(/ user)
@HandleMyOwnException
public Response getUser(@QueryParam(id)String userId){
assertNotNull(userId);
return Response.ok(service.getUser(userId))。build();
}



pom.xml



< pre class =lang-xml prettyprint-override> <! - deps - >
< dependency>
< groupId> org.aspectj< / groupId>
< artifactId> aspectjrt< / artifactId>
< version> 1.8.2< / version> <! - 或更新版本 - >
< / dependency>

<! - 构建插件 - >
< 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>
<执行>
< execution>
< goals>
< goal> compile< / goal>
< / goals>
< / execution>
< / executions>
< / plugin>
< / plugins>
< pluginManagement>
< plugins>
< plugin>
< groupId> org.eclipse.m2e< / groupId>
< artifactId>生命周期映射< / 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中注释缺少的路径


I have resource class which itself's talks with a internal service. This resource acts a rest API for the service. The service layer can throw unexpected exceptions, thus the resource should handle those handled unexpected exceptions and log it. I am using dropwizard framework which in turns use jersey. It goes like this.

@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();
   }
}

The problem here is that i have to do this exact same exception handling for each REST api endpoint. Can i do some kind of exception mapping for this particular resource so that i can put all the handling logic and logging there? I know i can build a mapper for an particular exception in jersey, but that is for the whole module not a single class.

解决方案

Afaig you can't register an ExceptionMapper to a resource method. I've tried this by implementing a DynamicFeature which was looking for a custom Annotation and then tried to register a custom ExceptionMapper with the FeatureContext.

The result was disillusioning:
WARNING: The given contract (interface javax.ws.rs.ext.ExceptionMapper) of class path.to.CustomExceptionMapper provider cannot be bound to a resource method.

Might not work:
But...

For a resource class this is in fact easy. Just register your ExceptionMapper for your resource class within your ResourceConfig. For me it looks like:

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

So if you are okay with having this on resource class level, do it like this.

Otherwise you might need to use Aspects (but I don't see any reasons to do so). Example:

Aspect

@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();
        }
    }

}

Please notice, the RESOURCE config. Here it works for none static methods under path.to.resources which returning Response and are anntotated with the HandleMyOwnException annotation.

HandleMyOwnException

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HandleMyOwnException {}

ResourceMethod

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

pom.xml

<!-- 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>

Have a nice day!

EDITED

~ Added more complete pom.xml config
~ Corrected missing path for Annotation in ResourceAspect

这篇关于特殊类的异常处理/映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆