odata4j 多次请求元数据
odata4j requests metadata too many times
我使用 odata4j 库访问 WCF 数据服务。
这就是我从 Android 代码中调用服务方法的方式:
OQueryRequest<OEntity> l = consumer.getEntities("GetDataList")
.custom("dataId", String.format("'%s'", actualData.ID))
.orderBy("Name").skip(0).top(200);
我用 WireShark 检查了一下,发现每个方法调用之前都有 2 次元数据信息请求调用:
为什么?它们是必不可少的吗?元数据信息比较重,不应该每次都请求(更不用说2次了)
如何防止odata4j多次请求元数据信息?
我在源代码中找到了 'extra' 请求发生的地方(在 odata4j/odata4j-core/src/main/java/org/odata4j/consumer/AbstractODataConsumer.java 中):
@Override
public EdmEntitySet findEdmEntitySet(String entitySetName) {
EdmEntitySet rt = super.findEdmEntitySet(entitySetName);
if (rt == null && delegate != EdmDataServices.EMPTY) {
refreshDelegate();
rt = super.findEdmEntitySet(entitySetName);
}
return rt;
}
似乎如果找不到实体集,消费者会创建到服务器的额外往返以再次获取 元数据(通过调用 refreshDelegate()
):
private void refreshDelegate() {
ODataClientRequest request = ODataClientRequest.get(AbstractODataConsumer.this.getServiceRootUri() + "$metadata");
try {
delegate = AbstractODataConsumer.this.getClient().getMetadata(request);
} catch (ODataProducerException e) {
// to support services that do not expose metadata information
delegate = EdmDataServices.EMPTY;
}
}
我不太明白为什么:也许它假设服务器已经更改并且有新版本的元数据可用,所以它会重试。
如果失败,它会尝试查找具有给定名称的函数。
个人我认为这不是很有效,除非服务器端非常不稳定以至于它在调用之间发生变化。
因此,如果您在服务器上没有更改元数据,可以安全地删除 entitySet 的 check 并将其 return 设为 null:
@Override
public EdmEntitySet findEdmEntitySet(String entitySetName) {
EdmEntitySet rt = super.findEdmEntitySet(entitySetName);
//if (rt == null && delegate != EdmDataServices.EMPTY) {
// refreshDelegate();
// rt = super.findEdmEntitySet(entitySetName);
//}
return rt; //if it is null, then the search for a function will commence
}
我使用 odata4j 库访问 WCF 数据服务。
这就是我从 Android 代码中调用服务方法的方式:
OQueryRequest<OEntity> l = consumer.getEntities("GetDataList")
.custom("dataId", String.format("'%s'", actualData.ID))
.orderBy("Name").skip(0).top(200);
我用 WireShark 检查了一下,发现每个方法调用之前都有 2 次元数据信息请求调用:
为什么?它们是必不可少的吗?元数据信息比较重,不应该每次都请求(更不用说2次了)
如何防止odata4j多次请求元数据信息?
我在源代码中找到了 'extra' 请求发生的地方(在 odata4j/odata4j-core/src/main/java/org/odata4j/consumer/AbstractODataConsumer.java 中):
@Override
public EdmEntitySet findEdmEntitySet(String entitySetName) {
EdmEntitySet rt = super.findEdmEntitySet(entitySetName);
if (rt == null && delegate != EdmDataServices.EMPTY) {
refreshDelegate();
rt = super.findEdmEntitySet(entitySetName);
}
return rt;
}
似乎如果找不到实体集,消费者会创建到服务器的额外往返以再次获取 元数据(通过调用 refreshDelegate()
):
private void refreshDelegate() {
ODataClientRequest request = ODataClientRequest.get(AbstractODataConsumer.this.getServiceRootUri() + "$metadata");
try {
delegate = AbstractODataConsumer.this.getClient().getMetadata(request);
} catch (ODataProducerException e) {
// to support services that do not expose metadata information
delegate = EdmDataServices.EMPTY;
}
}
我不太明白为什么:也许它假设服务器已经更改并且有新版本的元数据可用,所以它会重试。
如果失败,它会尝试查找具有给定名称的函数。
个人我认为这不是很有效,除非服务器端非常不稳定以至于它在调用之间发生变化。
因此,如果您在服务器上没有更改元数据,可以安全地删除 entitySet 的 check 并将其 return 设为 null:
@Override
public EdmEntitySet findEdmEntitySet(String entitySetName) {
EdmEntitySet rt = super.findEdmEntitySet(entitySetName);
//if (rt == null && delegate != EdmDataServices.EMPTY) {
// refreshDelegate();
// rt = super.findEdmEntitySet(entitySetName);
//}
return rt; //if it is null, then the search for a function will commence
}