Java 为什么Resteasy mobile中的ClientResponseFailure会导致堆栈溢出错误?解决办法?

Java 为什么Resteasy mobile中的ClientResponseFailure会导致堆栈溢出错误?解决办法?,java,android,resteasy,Java,Android,Resteasy,我目前正在开发一个Android应用程序,它使用Resteasy mobile实现REST(JAXRS),并使用Jackson实现JSON之间的序列化。后者是由Resteasy在后台完成的 服务器端我有一个Jersey Web服务,也使用jackson进行JSON的序列化 Resteasy客户端和webresource都实现了一个JAXRS注释接口,如下所示: @Path("/equipment") @Consumes({"application/json"}) @Pro

我目前正在开发一个Android应用程序,它使用Resteasy mobile实现REST(JAXRS),并使用Jackson实现JSON之间的序列化。后者是由Resteasy在后台完成的

服务器端我有一个Jersey Web服务,也使用jackson进行JSON的序列化

Resteasy客户端和webresource都实现了一个JAXRS注释接口,如下所示:

    @Path("/equipment")
    @Consumes({"application/json"})
    @Produces({"application/json"})
    public interface AndroidEquipmentResourceIF
    {
      @GET 
      public Model getModel();

      @GET 
      @Path("/version") 
      public String getVersion();

      @GET 
      @Path("/{eId}") 
      public List<Equipment> getEquipmentListWithId(@PathParam("eId") String eId);
    }

让它以以下方式工作:

Resteasy mobile是JBOSS Resteasy 2.2.1 GA的删减版。为了使其在Android上工作,很多东西都被删除了。但是去掉的太多了

我发现如果抛出
ClientResponseFailure
,其实体的响应将被转换为
Byte
数组,并将再次读取以复制到
ClientResponseFailure
。问题是,删减后的版本只包含字符串和文本/普通的Messagebody读写器,而不包含字节数组。因此,当尝试读取实体时,它会尝试抛出一个新的
ClientResponseFailure
,因为无法找到与
Byte[]兼容的
MessageBodyReader
。然后,它再次将该实体强制转换为字节数组,尝试再次读取它,从而进入一个无限循环,该循环将以
StackOverflowError
结束

通过添加Resteasy到类路径(位于
org.jboss.Resteasy.plugins.providers.ByteArrayProvider
org.jboss.Resteasy.util.ReadFromStream
)的未删减版本中缺少的
ByteArrayProvider
ReadFromStream
,ClientErrorInterceptor
()的工作非常有魅力

编辑:我说得有点太早了,还没有发挥出魅力。 ResteasyProviderFactory也进行了修改,以使其在Android中工作。.getInstance()方法不断返回一个新实例,因此如果将ClientErrorInterceptor注册为:
ResteasyProviderFactory.getInstance().addClientErrorInterceptor(new DataExceptionInterceptor())它不工作。ProxyFactory将在内部使用ResteasyProviderFactory的新实例

要解决此问题,应将用于添加拦截器的ResteasyProviderFactory传递给
ProxyFactory.create()

像这样:

ResteasyProviderFactory pf;
BasicHttpParams params;

pf = ResteasyProviderFactory.getInstance();

pf.addClientErrorInterceptor(new DataExceptionInterceptor());

params = new BasicHttpParams();
HttpProtocolParams.setVersion(params,
                              HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params,
                                     HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params,
                                        false);
return ProxyFactory.create(AndroidEquipmentResourceIF.class,
                           ProxyFactory.createUri(requestURI),
                           new ThreadSafeApacheHttpClient4Executor(params),
                           pf);

这可能会有帮助[[1]:不太可能。这些问题与向响应对象添加自定义错误消息有关,我使用的不是该对象。我返回的对象不是响应。引发自定义异常(从WebApplicationException继承)如果id无效,则从服务器方法不适用于您?这正是我现在正在做的,但我认为我无法捕获异常客户端?或者可以吗?我不知道reasteasy mobile,但您应该尝试。我认为您将获得异常客户端。
ResteasyProviderFactory pf;
BasicHttpParams params;

pf = ResteasyProviderFactory.getInstance();

pf.addClientErrorInterceptor(new DataExceptionInterceptor());

params = new BasicHttpParams();
HttpProtocolParams.setVersion(params,
                              HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params,
                                     HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params,
                                        false);
return ProxyFactory.create(AndroidEquipmentResourceIF.class,
                           ProxyFactory.createUri(requestURI),
                           new ThreadSafeApacheHttpClient4Executor(params),
                           pf);