К сожалению, нет простого способа настроить это поведение при использовании API.Как вы уже заметили, текущая реализация ожидает, что результат JSON будет содержать объект с тем же именем ключа, что и имя import , вызываемое в запросе OData.
Вот временный обходной путьВаша проблема:
Переопределите класс реализации FluentHelperFunction следующим методом getFunctionName:
@Override
@Nonnull
protected String getFunctionName()
{
final String callingMethod = Thread.currentThread().getStackTrace()[2].getMethodName();
if( "generatePath".equals(callingMethod) ) {
return "TheFunctionNameInUrlPath";
}
if( "executeSingle".equals(callingMethod) ) {
return "TheKeyOfODataResponse";
}
throw new IllegalStateException("This should not happen.");
}
Покаэто не очень хороший код, мы проверим, как это можно упростить в будущем с помощью SAP Cloud SDK.
Обновление: К сожалению, ответ JSON, который вы получаете,не оборачивает содержимое в другой объект внутри корневого элемента "d".Это значительно усложняет решение проблемы.
Если вы все еще хотите использовать SAP Cloud SDK в этом сценарии, вам потребуется адаптировать некоторый внутренний код.Вместо перечисленного выше getFunctionName
попробуйте следующее изменение метода execute
(или executeSingle
):
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import com.google.common.io.CharStreams;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.google.json.JsonSanitizer;
import com.sap.cloud.sdk.odatav2.connectivity.ODataExceptionType;
import com.sap.cloud.sdk.odatav2.connectivity.ODataGsonBuilder;
import com.sap.cloud.sdk.result.GsonResultElementFactory;
import com.sap.cloud.sdk.result.ResultElement;
import org.apache.http.HttpEntity;
...
@Override
@Nullable
public T execute( @Nonnull final ErpConfigContext configContext )
throws ODataException
{
final HttpEntity httpEntity = accessibleQuery(configContext);
final ProposalHeader response;
try( final InputStream content = httpEntity.getContent() ) {
final String rawContent = CharStreams.toString(new InputStreamReader(content, StandardCharsets.UTF_8));
final JsonElement responseJsonElement = new JsonParser().parse(JsonSanitizer.sanitize(rawContent));
// select JSON root object
final JsonElement jsonElement = responseJsonElement.getAsJsonObject().getAsJsonObject("d");
// deserialize contents
final GsonResultElementFactory elementFactory = new GsonResultElementFactory(ODataGsonBuilder.newGsonBuilder());
final ResultElement resultElement = elementFactory.create(jsonElement);
response = resultElement.getAsObject().as(getEntityClass());
}
catch( final IOException | IllegalArgumentException | JsonSyntaxException e ) {
throw new ODataException(ODataExceptionType.ODATA_OPERATION_EXECUTION_FAILED, "Failed to read OData result.", e);
}
return response;
}
private HttpEntity accessibleQuery( @Nonnull final ErpConfigContext configContext ) {
try {
final Method query = FluentHelperFunction.class.getDeclaredMethod("query", ErpConfigContext.class);
query.setAccessible(true);
Object httpEntityRaw = query.invoke(this, configContext);
return HttpEntity.class.cast(httpEntityRaw);
}
catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassCastException e) {
// log error
// throw exception
return null;
}
}
Вы можете изменить универсальный тип T
на ожидаемый класс ответа,Также измените строки // log error
и // throw exception
, чтобы они соответствовали сценарию использования вашего приложения, чтобы в будущем можно было легко выполнять обработку ошибок.Кроме того, вы должны ввести в этот код некоторые проверки null
.