【问题标题】:RESTEasy Client Exception HandlingRESTEasy 客户端异常处理
【发布时间】:2015-08-18 07:05:29
【问题描述】:

我有一个使用 RESTEasy 的简单客户端,如下所示:

public class Test {
    public static void main(String[] args) {
        ResteasyClient client = new ResteasyClientBuilder().build();
        ResteasyWebTarget target = client.target("http://localhost");
        client.register(new MyMapper());
        MyProxy proxy = target.proxy(MyProxy.class);
        String r = proxy.getTest();
    }
}

public interface MyProxy {
   @GET
   @Path("test")
   String getTest();
}

@Provider
public class MyMapper implements ClientExceptionMapper<BadRequestException>{

    @Override
    public RuntimeException toException(BadRequestException arg0) {
        // TODO Auto-generated method stub
        System.out.println("mapped a bad request exception");
        return null;
    }

}

服务器配置为在http://localhost/test 上返回400 - Bad Request 以及有用的消息。 BadRequestException 正在被 ClientProxy 抛出。除了包裹在try/catch 中之外,我怎样才能让getTest() 捕获异常并将响应的有用消息作为字符串返回。我尝试了各种ClientExceptionMapper 实现,但似乎都做对了。上面的代码从来没有调用过toException。我在这里错过了什么?

我目前的解决方法是使用ClientResponseFilter,然后执行setStatus(200) 并将原始状态填充到响应实体中。这样我就避免了异常抛出。

【问题讨论】:

  • 您能解释一下“服务器配置为返回 400 - 错误请求”是什么意思吗?我的想法是MyProxy.getTest() 的实现实际上应该抛出一个包含有用消息的异常。然后,您将使用 ExceptionMapper 将该异常映射到 400 - Bad Request 响应(您可以将消息作为响应的正文包含在内)。
  • 阅读我的问题的第一句话。我正在编写客户端,而不是服务器。

标签: java jax-rs resteasy


【解决方案1】:

Resteasy 中的ClientExceptionMapper 已弃用(请参阅java docs)

resteasy-client 模块中的 JAX-RS 2.0 客户端代理框架确实 不使用 org.jboss.resteasy.client.exception.mapper.ClientExceptionMapper.

尝试使用这样的 ExceptionMapper:

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

@Provider
public class MyMapper implements ExceptionMapper<ClientErrorException> {

    @Override
    public Response toResponse(ClientErrorException e) {
        return Response.fromResponse(e.getResponse()).entity(e.getMessage()).build();
    }
}

问候,

【讨论】:

    【解决方案2】:

    我建议您使用 Jax-RS 客户端 API,除非您需要使用 RestEasy 客户端的功能。 (RestEasy 附带 Jax-RS,因此没有库差异)

    Client client = ClientFactory.newClient();
    WebTarget target = client.target("http://localhost/test");
    Response response = target.request().get();
    if ( response.getStatusCode() != Response.Status.OK.getStatusCode() ) {
        System.out.println( response.readEntity(String.class) );
        return null;
    }
    String value = response.readEntity(String.class);
    response.close();
    

    您的映射器不起作用的原因是客户端实际上并未抛出异常。客户端正在向代理返回一个有效结果,而代理正在读取该结果并抛出异常,这发生在映射器可以拦截它之后。

    【讨论】:

    • 这难道不会排除使用代理的所有好处吗(例如 /test 在上面的示例中是硬编码的)?我将问题阅读为如何让代理抛出更有用的异常。当实际消息在响应中时,代理返回带有硬编码消息“错误请求”的异常对我来说很奇怪。是否有拦截器来包裹代理的异常处理?
    • 代理不保留有关潜在错误的任何信息这一事实是一个非常致命的缺陷,恕我直言。我能看到的唯一解决方法是让代理的方法返回响应,调用者可以从中获取实体和/或 HTTP 元素。但这意味着接口中不再指定实体返回类型。真可惜。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 2015-04-26
    • 1970-01-01
    • 2019-11-09
    • 1970-01-01
    • 1970-01-01
    • 2017-04-08
    相关资源
    最近更新 更多