如何从Amazon Lambda获取POJO的ArrayList(仅获取LinkedTreeMap)

时间:2017-12-09 17:27:58

标签: arraylist lambda gson aws-lambda pojo

我尝试使用我的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)。也许同样的问题...

1 个答案:

答案 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()));