RESTEasy客户端异常处理

15

我有一个使用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的响应以及有用的信息。由ClientProxy抛出了BadRequestException异常。除了使用try/catch包装外,我如何使getTest()捕获该异常并将响应的有用信息作为字符串返回?我尝试了各种ClientExceptionMapper实现,但似乎都不正确。上面的代码从未调用toException。我错过了什么?
我的当前解决方法是使用ClientResponseFilter,然后执行setStatus(200)并将原始状态放入响应实体中。这样我就避免了异常抛出。

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

1

Resteasy中的ClientExceptionMapper已经被弃用(请参见java文档

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

致敬,


0

我建议使用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();

你的映射器无法工作的原因是客户端实际上没有抛出异常。客户端向代理返回了一个有效的结果,代理读取该结果并抛出异常,这发生在映射器拦截之后。

2
这样做是否会抵消使用代理的所有好处呢(例如在上面的示例中硬编码了/test)?我认为问题是如何让代理抛出更有用的异常。对我来说,当实际消息在响应中时,代理返回一个带有硬编码消息“bad request”的异常很奇怪。是否有拦截器可以包装代理的异常处理? - Michael Haefele
4
在我看来,代理不保留有关底层错误的任何信息是一个相当致命的缺陷。我唯一能想到的解决方法是让代理的方法返回响应(Response)对象,然后调用者可以从中获取实体(entity)和/或HTTP元素。但这意味着实体返回类型不再在接口中指定。很遗憾。 - Bampfer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接