2017-12-09 19 views
0

AndroidモバイルアプリケーションクライアントでAWS Lambda関数(サーバーレスバックエンド)を呼び出そうとしています。 AWSラムダ関数は、POJOオブジェクトのArrayList(JSON)を返します。Amazon LambdaからPOJOのArrayListを取得する方法(LinkedTreeMapのみ取得)

問題は、アンドロイドクライアントのAWS Lambda(JSON)DataBinderがPOJOのArrayListにデシリアライズしないことです。 LinkedTreeMapのArrayListを取得します(下記のonPostExecute()のコードを参照)。

アンドロイドクライアント側では、私はAndroidのAWS SDKを使用しています:com.amazonaws:AWS-アンドロイド-SDK-コア:ここでは2.6

はいくつかのコードです:ここでは

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); 
} 

コードです私のラムダ関数のインターフェイス:

public interface MyInterface { 

    @LambdaFunction 
    ArrayList<SurveyListItem> ReadSurveyList (SurveyListRequest surveyListRequest); 
} 

私のPOJOオブジェクトのリストを取得すると思います。 GsonとArrayListのタイプとTypeTokenに基づいたソリューション(例:Gson TypeToken with dynamic ArrayList item type)について多くの議論がありました。おそらく同じ問題です...

答えて

0

私はカスタムLambdaDataBinderを使って解決策を見つけました。 deserialize関数で私のPOJOクラス "SurveyListItem"の型を指定しました。 GsonはTypeToken定義を使用し、JSON文字列をPOJOのリスト(私の場合は "SurveyListItem"オブジェクト)のリストに変換します。ここで

は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を使用する方法です。 "SurveyListItem"の代わりにPOJOを使用してください:

myInterface = factory.build(LambdaInterface.class, new MyLambdaDataBinder(new TypeToken<ArrayList<SurveyListItem>>() {}.getType())); 
関連する問題