我尝试使用我的Android移动应用客户端调用我的AWS Lambda函数(无服务器后端)。 AWS lambda函数返回POJO对象的ArrayList(作为JSON)。
问题是android客户端AWS Lambda(JSON)DataBinder没有反序列化为我的POJO的ArrayList。我得到一个LinkedTreeMap的ArrayList(参见下面onPostExecute()的代码)。
在Android客户端,我正在使用Android AWS SDK:com.amazonaws:aws-android-sdk-core:2.6
以下是一些代码:
commandReg.Dependencies.Add(
commandReg.Constructor.GetParameters().First(
p => p.ParameterType.IsGenericType && p.ParameterType.GetGenericTypeDefinition() == typeof(ILogDifferencesLogger<>)).Name,
new GenericTypesWorkaroundInstance(
loggers[AppSettingsManager.Get("logDifferences:Target")],
// specify which types are correct
types => types.Skip(1).ToArray()));
这是我的lambda函数接口的代码:
public void readSurveyList(String strUuid, int intLanguageID) {
// Create an instance of CognitoCachingCredentialsProvider
// You have to configure at least an AWS identity pool to get access to your lambda function
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
this.getApplicationContext(),
IDENTITY_POOL_ID,
Regions.EU_CENTRAL_1);
LambdaInvokerFactory factory = LambdaInvokerFactory.builder()
.context(this.getApplicationContext())
.region(Regions.EU_CENTRAL_1)
.credentialsProvider(credentialsProvider)
.build();
// Create the Lambda proxy object with default Json data binder.
myInterface = factory.build(MyInterface.class);
//create a request object (depends on your lambda function)
SurveyListRequest surveyListRequest = new SurveyListRequest(strUuid, intLanguageID);
// Lambda function in async task with definiton of
// request object (-> SurveyListRequest)
// response object (-> ArrayList<SurveyListItem>>)
new AsyncTask<SurveyListRequest, Void, ArrayList<SurveyListItem>>() {
@Override
protected ArrayList<SurveyListItem> doInBackground(SurveyListRequest... params) {
try {
return myInterface.ReadSurveyList(params[0]);
} catch (LambdaFunctionException lfe) {
Log.e("TAG", String.format("echo method failed: error [%s], details [%s].", lfe.getMessage(), lfe.getDetails()));
return null;
}
}
@Override
protected void onPostExecute(ArrayList<SurveyListItem> surveyList) {
// PROBLEM: here i get a ArrayList of LinkedTreeMap
}
}.execute(surveyListRequest);
}
我希望得到一个我的POJO对象列表。我发现了很多关于Gson和ArrayList类型的讨论以及基于TypeToken的解决方案(例如Gson TypeToken with dynamic ArrayList item type)。也许同样的问题...
答案 0 :(得分:0)
我找到了使用自定义LambdaDataBinder的解决方案。我已经指定了我的POJO类的类型&#34; SurveyListItem&#34;在反序列化函数中。 Gson使用TypeToken定义并将JSON字符串正确转换为POJO列表(在我的情况下&#34; SurveyListItem&#34;对象)。
以下是MyLambdaDataBinder的源代码:
public class MyLambdaDataBinder implements LambdaDataBinder {
private final Gson gson;
Type mType;
//CUSTOMIZATION: pass typetoken via class constructor
public MyLambdaDataBinder(Type type) {
this.gson = new Gson();
mType = type;
}
@Override
public <T> T deserialize(byte[] content, Class<T> clazz) {
if (content == null) {
return null;
}
Reader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(content)));
//CUSTOMIZATION: Original line of code: return gson.fromJson (reader, clazz);
return gson.fromJson(reader, mType);
}
@Override
public byte[] serialize(Object object) {
return gson.toJson(object).getBytes(StringUtils.UTF8);
}
}
以下是如何使用自定义MyLambdaDataBinder。使用您的POJO代替&#34; SurveyListItem&#34;:
myInterface = factory.build(LambdaInterface.class, new MyLambdaDataBinder(new TypeToken<ArrayList<SurveyListItem>>() {}.getType()));