Java RestClient 中的异常处理 [英] Handling exception in Java RestClient

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

问题描述

我需要编写一个由多个返回特定对象的应用程序使用的 RestClient.在错误请求 (400) 的情况下,我想向调用方应用程序提供消息错误和状态代码的建议.我想知道抛出带有代码和消息属性的托管异常以便从调用者代码中正确捕获是否是一种好行为.像这样:

I need to write a RestClient used by several application that return a specific object. In case of bad request (400) I'd like to advice the caller application of the message error and status code. I wonder if is it a good behavior to throw a managed Exception with code and message property in order to be catched properly from the caller code. Something like this:

RestClient.java

ClientResponse response;
try {
    response = client.resource(requestURI).queryParams(queryParams)
            .type(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON)
            .post(ClientResponse.class, richiesta);

    boolean output =  response.getStatus() == Response.Status.NO_CONTENT.getStatusCode();

    if (!output && response.getStatus() == Response.Status.BAD_REQUEST)
        throw new RestClientRuntimeException(response.getStatus, response.getEntity(String.class));

} catch (ClientHandlerException e) {
    throw new RestClientRuntimeException(e);
} catch (UniformInterfaceException e) {
    throw new RestClientRuntimeException(e);
}

来电申请

try 
{

    boolean output = restClient.method()

} catch (RestClientRuntimeException e) {

    // read exception status and message entity

}

这是一个好习惯吗?

推荐答案

你的问题有几个方面.让我们分别考虑一下:

Your question has several aspects. Lets consider them separately:

是的,您应该将错误代码转换为异常.例外很好(当然,如果使用得当).他们将快乐路径与特殊情况分开.如果您不使用异常而是返回代码,则您的调用者需要检查该返回代码.如果你调用多个方法,你会得到一些令人讨厌的级联 ifs:

Yes you should translate error codes into exceptions. Exceptions are nice (if used correctly of course). They separate the happy path from the exceptional cases. If you don't use exceptions but return codes, your callers need to check for that return code. And if you call several methods you get some nasty cascading ifs:

if (service1.method1() == NO_ERROR) {
    if (service2.method2() = NO_ERROR) {
        if (service3.method2() = NO_ERROR) {
            ...
        } else {
            ...
        }
    } else {
        ...
    }
} else {
    ...
}

此外,如果您有多个层(而且您几乎肯定有),则需要在每个级别再次执行此操作.这里的例外要好得多.他们让你先编码(和阅读!)漂亮而干净的快乐路径,然后您可以担心 catch 块中的异常.这样写起来更容易,也更容易阅读.

Furthermore if you have several layers (and you almost certainly have), you need to do this at every level again. Exceptions are much better here. They let you code (and read!) the nice and clean happy path first and then you can worry about the exceptions in the catch block. That's easier to write and easier to read.

这会变得非常虔诚.有些人认为检查异常是个好主意,有些人认为它们是邪恶的.我不想在这里详细辩论.就是这样:你想强迫你的调用者考虑那个特定的异常吗?是否总是或至少在绝大多数情况下调用者可以处理该异常?

This can get quite religious. Some people think checked exceptions are a good idea, some think, they are evil. I don't want to debate that here in detail. Just that: Do you want to force your callers to think about that particular exception? Is there always or at least in the vast majority of cases a way for the caller to handle that exception?

如果你得出的结论是调用者除了记录异常并且自己失败之外什么也做不了,你应该避免使用检查异常.这使得调用者代码更加清晰.无意义的 try..catch 块没有任何用处,只是为了让编译器满意.

If you come to the conclusion that the caller cannot do anything but log the exception and fail itself, you should refrain from using checked exceptions. This makes the caller code much cleaner. There is no use in pointless try..catch blocks that are just there to make the compiler happy.

说到 REST:在 500 的情况下,很可能没有机会恢复.如果你得到 405,你很可能有一个错误,也没有办法恢复.如果您收到 409 Conflict 和一些有关如何解决冲突的特殊信息,那么可能有一个很好的方法来处理它(取决于您的要求).在这种情况下,您可以考虑检查异常.

Speaking of REST: In case of a 500, there is most likely no chance to recover. If you get a 405 you most likely have a bug and there is no way to recover either. If you get a 409 Conflict with some special info on how to resolve the conflict there might be a good way to handle that (depending on your requirements). In such a case you may consider a checked exception.

当您使用通用的 RestClientRuntimeException 并让您的调用者查询响应代码时,您的调用者显然与这是 REST 调用相关联.如果您正在编写可以查询任意 REST API 的通用 REST 客户端,则可以这样做.在这种情况下没有问题.

When you use generic RestClientRuntimeExceptions and have your callers query the response code, then your caller is obviously coupled to this being a REST call. You can do that if you are writing a generic REST client that can query arbitrary REST APIs. No problem in this case.

但是您已经在使用通用库(我猜是 Jersey).那么将通用 API 包裹在通用 API 周围有什么意义呢?可能有一些原因(例如评估一些内部使用的标头参数),但您应该考虑这是否合理.

But you are already using a generic library (I guess Jersey). So what's the point in wrapping a generic API around a generic API? There may be some reasons (e.g. evaluating some internally used header params) but you should think about it whether this is justified.

也许您想编写特定于应用程序的 REST 客户端,即反序列化特定于应用程序的表示类 (DTO) 的客户端.在这种情况下,您不应使用通用异常,而应使用特定于应用程序的异常.如果您使用特定于应用程序的异常,您的调用者不会与这是一个 REST 调用耦合.也许将来会出现一项很酷的新技术,您需要改变您的客户.如果您使用通用异常并让您的调用者评估响应代码,则调用者也需要更改.但是如果你使用特定于应用程序的异常,这个接口会更稳定.调用者甚至不需要知道 REST 之类的东西存在.当您分离关注点时,这会使调用方代码更简单且更易于维护.

Maybe you want to write an application-specific REST client, i.e. one that deserializes your application-specific representation classes (DTOs). In such a case you should not use generic exceptions but rather application-specific ones. If you use application-specific exceptions your callers are not coupled to this being a REST call. Maybe in the future a cool new technology shows up and you need to change your client. If you use the generic exceptions and have your callers evaluate the response codes, the callers need to change, too. But if you use application-specific exceptions, this interface will be more stable. The callers don't even need to know that such a thing as REST exists. This makes the caller code simpler and more maintainable as you separate concerns.

我知道你没有问过这个问题.但也许你应该这样做.向任意客户端提供具有 Jersey 依赖项的 rest-client jar(在我看来,您就是这样做的)起初看起来不错,但可能会让您在依赖项方面遇到真正的麻烦.如果你不相信,我可以详细解释,但让我们在一个单独的问题中讨论这个.

I know you haven't asked that question. But maybe you should do so. Providing a rest-client jar with a Jersey dependency to arbitrary clients (that's what it seems to me that you do) looks nice at first but can get you into real trouble with dependencies. If you are not convinced, I can explain that in detail but lets discuss this in a separate question.

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

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