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