Java モジュールの引数変換

バージョン 1.1 以降で使用可能

Java 呼び出しに指定された引数が Java メソッドが想定する型と完全に一致していないものの、指定されたパラメータをメソッドが想定する型に変換する方法を推測する手段がある場合には、Java モジュールがその引数を変換します。

引数が変換される状況

このモジュールは、指定されたパラメータごとに、その型がそのパラメータのメソッドが想定する型と一致するかどうかをチェックします。メソッドが想定する型でない場合は、このモジュールが想定される型に変換しようとします。

シンプルな引数変換の例

以下に、引数の 1 つが変換されるシンプルな例を示します。

'Math' クラスから 'min' 静的メソッドがコールされますが、2 つの int パラメータを受け取ることが想定されるため、このコールの実行時には Number と String が使用されます。

<flow name="calculateMinimum">
  <java:invoke-static class="java.lang.Math" method="min(int,int)" >
    <java:args>#[{
        'arg0': 5,
        'arg1' : "3"
      }]
    </java:args>
  </java:invoke-static>
</flow>

この場合、'arg1' は String として渡されるところですが、Java メソッドをコールする前に int に変換されます。

Map としてモジュールに渡されるカスタム POJO

以前は、カスタム POJO を処理する場合に、ユーザがデータをどの型に変換するかを DataWeave 式で明示的に宣言する必要がありました。現在は、指定された引数の想定される型を Java モジュールが自動的に認識し、指定されたデータを想定される型に変換しようとします。このモジュールで Map パラメータがカスタム POJO に変換される例を示します。

以下は、POJO のクラスです。

public class Car {
  private String doors;
  private String wheels;
  private String engine;

  public String getDoors() {
    return doors;
  }

  public String getWheels() {
    return wheels;
  }

  public String getEngine() {
    return engine;
  }
}

Java クラスが、上記の例で定義された POJO のインスタンスを受け取る静的メソッドを宣言します。

public class CarUtils {
  public static String describeCar(Car car) {
    return "This are the car has: " + car.getEngine() + "," + car.getWheels() + "," + car.getDoors();
  }
}

上記の静的メソッドが呼び出される Mule フローです。

<flow name="describeCarFlow">
    <java:invoke-static class="CarUtils" method="describeCar(Car)" >
        <java:args>
            #[{
            'car': {
                'doors' : "Four doors",
                'engine' : "120 Horse power engine",
                'wheels' : "17 Inch chromed rims"
            }
            }]
        </java:args>
    </java:invoke-static>
</flow>

mule 操作は car という Map を受け取り、そのキーと値を Car インスタンスにマップできます。Java メソッドを呼び出す前に、この Map が Car インスタンスに変換されます。こうした改善がなければ呼び出しに失敗し、Java メソッドに渡された引数がその署名と一致していなかった旨が表示されるでしょう。

Collection と Map

このモジュールは、Collection の各要素と Map の各エントリが、メソッドの署名で宣言された Java ジェネリクスを使用しているかどうかをチェックします。使用していない要素がある場合は、Collection または Map 全体を作成して、変換済みの要素を再入力する必要があります。

変換が必要な場合は、Collection または Map の別のインスタンスで Java メソッドがコールされます (Mule フローで渡されるものと同じではありません)。この点が特に重要となるのは、コールされたメソッドで Collection または Map の要素を追加または削除し、呼び出しが必要になった後でこの Collection または Map を参照できることが想定される場合です。

List が変換される場合の例

次に、操作に指定された List を変換する必要があり、変換された項目を含む新しい List が Java メソッドに渡される場合の例を示します。

以下は、静的メソッドを宣言する Java クラスです。

public class IntegerUtils {
  public static Integer sumNumbers(List<Integer> numbers) {
    return numbers.stream().mapToInt(i -> i.intValue()).sum();
  }
}

以下は、Mule フローでどのように呼び出されるかを示しています。

<flow name="sumListOfNumbers">
  <java:invoke-static class="IntegerUtils" method="sumNumbers(List)">
    <java:args>
      #[{
        'numbers' : [1, "5", 4, "8", 3]
      }]
    </java:args>
  </java:invoke-static>
</flow>

フローで指定されたリストに 2 つの String オブジェクトがあり、Integer に変換する必要があります。

Map が変換される場合の例

次に、操作に指定された Map を変換する必要があり、変換されたキーと値を含む新しい Map が Java メソッドに渡される場合の例を示します。

以下は、静的メソッドを宣言する Java クラスです。

public class MapUtils {
  public static Integer sumMapValues(Map<String, Integer> map) {
    return map.keySet().stream().mapToInt(i -> i.intValue()).sum();
  }
}

以下は、Mule フローでどのように呼び出されるかを示しています。

<flow name="sumValuesOnMap">
  <java:invoke-static class="MapUtils" method="sumMapValues(Map)">
    <java:args>
      #[{
        'map' :{
          'books': "22",
          'pencils': 33,
          'pens': 12
        }
      }]
    </java:args>
  </java:invoke-static>
</flow>

この Map には、Java メソッドで強制されるジェネリクスに従っていない値があります。このため、変換されたキーと値を指定した新しいインスタンスを使用してメソッドがコールされます。

Was this article helpful?

💙 Thanks for your feedback!

Edit on GitHub