カスタムロジック

カスタムロジックを記述する際に利用する、MVCパターンベースのフレームワークの説明です。

1. フレームワークの概要

Java/JavaEEの上に構成されたMVCパターンに沿ったWebアプリケーションフレームワークです。 java、JSPまた、Groovy、Groovy Template(GroovyベースのJSPライクなテンプレート言語)でコーディングが可能です。 Groovy/Groovy Templateでロジックを作成した場合、それらのアプリケーションへの反映はコンパイル・warデプロイの必要なく即座に行われます。

iPLAssにおけるModel、View、Controllerはそれぞれ次のように位置付けられます。

Model

EntityがModelに相当します。 定義されたEntityはカスタムロジック上では org.iplass.mtp.entity.Entity として参照可能です。Entityデータの操作は org.iplass.mtp.entity.EntityManager インタフェースを介して行います。 検索処理は、 EQL(Entity Query Language) というSQLライクなDSLで記述可能です。 また org.iplass.mtp.entity.EntityEventListener にて、登録、更新、削除時などのタイミングで任意のロジックを追加することが可能です。

View

iPLAssにおいて、ViewはTemplateと呼称します。 Templateは実装手段、出力する内容により、いくつかの種類が存在します。 主にhtmlなどのテキストデータを出力する為のJspTemplate、GroovyTemplateやバイナリ出力用のTemplate、帳票出力用のTemplateなどが存在します。 JspTemplateは実装手段としてJSPを利用します。GroovyTemplateはGroovyベースのJSPライクなDSLで記述します。

Controller

iPLAssにおいて、ControllerはCommandとAction定義から構成されます。

  • Command
    org.iplass.mtp.command.Command を実装する処理ロジックの本体です。 Javaもしくは、Groovyで実装が可能です。 iPLAssが提供するjavaBeanへのバインディング機能、バリデーション機能、EntityManagerなどを利用し、リクエストを処理するロジックを記述します。

  • Action定義
    ルーティング制御を行うための定義です。 URLのパス単位に、そのパスが呼び出された場合の対応するCommandと処理結果により表示するTemplateを定義します。

GEMモジュール、WAMモジュール、MDCモジュール自体もこのMVCフレームワーク上に構築されています。それぞれのモジュール内にカスタムのTemplateやActionを組み込むことも可能です。

あわせて、カスタムロジックのコーディングをサポートする為の機能群、java apiを提供します。

2. EntityManager

カスタムロジックからEntityのデータに対する操作を行う場合は、 org.iplass.mtp.entity.EntityManager を利用します。

Entity定義の詳細については、Entity の説明を参照ください。

EntityManagerの利用例
import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.entity.DeleteOption;
import org.iplass.mtp.entity.Entity;
import org.iplass.mtp.entity.EntityManager;
import org.iplass.mtp.entity.GenericEntity;
import org.iplass.mtp.entity.SearchResult;
import org.iplass.mtp.entity.UpdateOption;
import org.iplass.mtp.entity.query.Query;
import org.iplass.mtp.entity.query.condition.expr.And;
import org.iplass.mtp.entity.query.condition.predicate.Like.MatchPattern;

:

EntityManager em = ManagerLocator.manager(EntityManager.class);

//Entityの登録
Entity e = new GenericEntity("samples.SampleEntity");
e.setName("nameOfEntity");
e.setValue("customProp", "propValue");
String oid = em.insert(e);


//Entityの読み込み
e = em.load(oid, "samples.SampleEntity");


//Entityの更新
e.setValue("customProp", "propValue2");
em.update(e, new UpdateOption().add("customProp"));


//Entityの検索
//select oid, name, customProp from samples.SampleEntity where name='nameOfEntity' and customProp like 'propValue%'
Query q = new Query()
        .select(Entity.OID, Entity.NAME, "customProp")
        .from("samples.SampleEntity")
        .where(new And()
                .eq(Entity.NAME, "nameOfEntity")
                .like("customProp", "propValue", MatchPattern.PREFIX));

//文字列からクエリを生成する場合
//Query q = new Query("select oid, name, customProp from samples.SampleEntity where name='nameOfEntity' and customProp like 'propValue%'");

SearchResult<Entity> res = em.searchEntity(q);


//Entityの削除
em.delete(e, new DeleteOption(false));

以下に主要な処理、メソッドの概要を記述します。 EntityManager のapiの詳細は、javadocを参照ください。

2.1. 読み込み (load)

load処理は、対象となるEntityの定義名、oid(Entityを一意に特定するためのキー、オブジェクトID)で特定されるEntityのデータを1件取得する処理です。
Entityをバージョン管理している場合は、特定のバージョンを指定し取得することも可能です。
loadの結果は org.iplass.mtp.entity.Entity のインスタンスとして返却されます。 Entity定義にて、Java Mapping Classを指定している場合は、そのクラスのインスタンスが返却されます。 未指定の場合は、 org.iplass.mtp.entity.GenericEntity のインスタンスが返却されます。
load時には、読み込み方法を指定するオプション(org.iplass.mtp.entity.LoadOption)を指定することが可能です。

org.iplass.mtp.entity.EntityEventListener にて、load時のカスタム処理を組み込むことが可能です。EntityEventListenerの詳細は EventListener を参照ください。

検索条件を指定して、Entityのリストを取得することが可能です。
検索条件は、EQL (Entity Query Language)にて指定します。 EQLの詳細は、 EQLリファレンス を参照ください。

searchEntity()

searchEntity() は、結果としてEntityのインスタンスを返却します。select項目としては、Entityのプロパティとして定義されているもののみ取得可能です。

1対多の参照関係を持つEntityを構造化して取得することも可能です。 検索時のオプション org.iplass.mtp.entity.SearchOption で指定可能です。 例えば、 1件のUserエンティティに対して、2件のGroupエンティティが関連付けされている場合

  • 構造化した場合(returnStructuredEntityをtureとした場合)

    検索結果には、1件のUserエンティティが返却されます。Userエンティティのgroupsプロパティには、長さ2のGroupエンティティ配列が設定されています。

  • 構造化しない場合

    構造化しない場合は、RDBのテーブルを結合した表形式のまま行が返却されます。
    つまり、検索結果には、2件のUserエンティティが返却されます。Userエンティティのgroupsプロパティには、それぞれGroupエンティティ1件ずつ設定されています。

org.iplass.mtp.entity.EntityEventListener にて、検索時のカスタム処理を組み込むことが可能です。EntityEventListenerの詳細は EventListener を参照ください。

search() は、Entity定義に含まれるプロパティとは異なる形式の検索結果を取得する目的で利用します。
結果としてObject[]のインスタンスを返却します。
select項目としては、演算項目、集計関数や、スカラーサブクエリなども指定可能です。

count()

count() は、指定のEQLの結果件数を取得します。

1対多の関連を持つEntityを検索するEQLの場合は注意が必要です。 from句に指定されたEntityの件数ではなく、それぞれのEntityが結合された状態の行数が返却されます。

callback

検索結果が大量件数になる可能性がある場合、callbackを利用することで、検索結果をストリーム処理可能です。

callbackの例
EntityManager em = ManagerLocator.manager(EntityManager.class);
:

Query query = ...;

em.searchEntity(query, entity -> {
    //handle entity
    System.out.println(entity);

    return true; (1)
});
1 callbackにてfalseを返却した場合、そこで処理を中断します。

2.3. 登録 (insert)

insert処理は、Entityのインスタンスを登録する処理です。
登録されたインスタンスにはoid(一意のID、オブジェクトID)が付与されます。
登録時の処理のオプションを org.iplass.mtp.entity.InsertOption で指定可能です。

org.iplass.mtp.entity.EntityEventListener にて、登録時のカスタム処理を組み込むことが可能です。EntityEventListenerの詳細は EventListener を参照ください。

2.4. 更新 (update)

update処理はEntityのインスタンスのプロパティの値を更新する処理です。
更新対象のプロパティは、 org.iplass.mtp.entity.UpdateOption で指定します。 また、処理時のタイムスタンプによる楽観ロック制御の有無などを制御可能です。

org.iplass.mtp.entity.EntityEventListener にて、更新時のカスタム処理を組み込むことが可能です。EntityEventListenerの詳細は EventListener を参照ください。

2.5. 削除 (delete)

delete処理はEntityのインスタンスを削除する処理です。
org.iplass.mtp.entity.DeleteOption にて、処理時のタイムスタンプによる楽観ロック制御、論理削除とするか否か(ごみ箱に入れるか否か)などを制御可能です。

org.iplass.mtp.entity.EntityEventListener にて、削除時のカスタム処理を組み込むことが可能です。EntityEventListenerの詳細は EventListener を参照ください。

2.6. 一括更新 (updateAll)

updateAll処理は更新対象のEntityの条件を指定し、一括でプロパティの値を更新する処理です。
更新対象の条件、更新する値は org.iplass.mtp.entity.UpdateCondition で指定します。

一括更新の例
import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.entity.EntityManager;
import org.iplass.mtp.entity.UpdateCondition;
import org.iplass.mtp.entity.query.value.ValueExpression;
import org.iplass.mtp.entity.query.condition.expr.And;
:

EntityManager em = ManagerLocator.manager(EntityManager.class);

String defName = "samples.SampleEntity";

UpdateCondition cond = new UpdateCondition(defName)
        .value("propA", Boolean.TRUE)
        .value("propB", ValueExpression.newValue("mod(propB, 7)") (1)
        .where(new And()
                .eq("propX", "1")
                .eq("propY", "10"));

int updateCount = em.updateAll(cond);
1 更新値には、値もしくは、数式(ValueExpression)を指定可能です

一括更新は以下の制約があります。

  • 楽観ロック(タイムスタンプのチェック)は行われません

  • EventListenerは呼び出されません

  • Binary、LongText、AutoNumber、Referenceは更新できません

  • NamePropertyに指定しているプロパティは更新できません

2.7. 一括削除 (deleteAll)

deleteAll処理は削除対象のEntityの条件を指定し、一括で削除する処理です。
削除対象の条件は org.iplass.mtp.entity.DeleteCondition で指定します。

一括削除の例
import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.entity.EntityManager;
import org.iplass.mtp.entity.DeleteCondition;
import org.iplass.mtp.entity.query.condition.expr.And;
:

EntityManager em = ManagerLocator.manager(EntityManager.class);

String defName = "samples.SampleEntity";

DeleteCondition cond = new DeleteCondition(defName)
        .where(new And()
                .eq("propX", "1")
                .eq("propY", "10"));

int deleteCount = em.deleteAll(cond);

一括削除は以下の制約があります。

  • 楽観ロック(タイムスタンプのチェック)は行われません

  • EventListenerは呼び出されません

  • Binary、LongTextをPropertyとしてもつEntityは削除できません

  • 親子関係(COMPOSITION)のReferencePropertyをもつEntityは削除できません

2.8. バルク更新 (bulkUpdate)

bulkUpdate処理は、 org.iplass.mtp.entity.bulkupdate.BulkUpdatable で指定される一連のEntityを一括で更新(Insert/Update/Delete)する処理です。
更新処理の際は、EntityEventListenerの呼び出しや、Validation、タイムスタンプチェック、CascadeDelete処理などは実行されません。
外部データの取り込み、初期データImportなどの大量データを一括で取り込む場合の利用を想定しています。

bulkUpdateを実行するユーザーは、当該Entityに対して登録、更新、削除権限を範囲条件なしに保有している必要があります。
バージョン管理時はバージョン番号を明示的に指定する必要があります。
バルク更新の例
import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.entity.Entity;
import org.iplass.mtp.entity.EntityManager;
import org.iplass.mtp.entity.GenericEntity;
import org.iplass.mtp.entity.bulkupdate.BulkUpdatable;
import org.iplass.mtp.entity.bulkupdate.BulkUpdateEntity;
import org.iplass.mtp.entity.bulkupdate.BulkUpdateEntity.UpdateMethod;
import org.iplass.mtp.entity.query.Query;
:

EntityManager em = ManagerLocator.manager(EntityManager.class);

String defName = "test";
String propertyName = "propX";

Query query = new Query()
        .select(Entity.OID, Entity.NAME, propertyName)
        .from(defName);
final List<Entity> entityList = em.searchEntity(query).getList();

int[] counter = {0};
BulkUpdatable bulkUpdatable = BulkUpdatable.as(defName)
        .updateProperties(propertyName)
        .onNext(() -> {
            if (counter[0] == entityList.size()) {
                return null;
            }
            GenericEntity entity = (GenericEntity) entityList.get(counter[0]);
            entity.setValue(propertyName, "customValue");

            BulkUpdateEntity ret = new BulkUpdateEntity(UpdateMethod.UPDATE, entity);
            counter[0]++;
            return ret;
        });

em.bulkUpdate(bulkUpdatable);

3. TypedDefinitionManager

org.iplass.mtp.definition.TypedDefinitionManager を継承した各メタデータ用のManagerインタフェースを使用して、メタデータをソースコードから直接変更することが可能です。 例えば、Entity定義を操作する場合には org.iplass.mtp.entity.definition.EntityDefinitionManager を、Message定義を操作する場合には org.iplass.mtp.message.MessageManager を使用します。 詳細は、javadocを参照してください。

(例1)EntityDefinitionManagerによるEntity操作
import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.entity.definition.EntityDefinitionManager;
import org.iplass.mtp.entity.definition.PropertyDefinition;
import org.iplass.mtp.entity.definition.properties.StringProperty;
import org.iplass.mtp.entity.definition.properties.BooleanProperty;
import org.iplass.mtp.entity.definition.EntityDefinition;

EntityDefinitionManager entityDefinitionManager = ManagerLocator.getInstance()
                .getManager(EntityDefinitionManager.class);

PropertyDefinition propertyDefinition1 = new StringProperty();
propertyDefinition1.setName("string");
propertyDefinition1.setDisplayName("文字列");
propertyDefinition1.setMultiplicity(1);

PropertyDefinition propertyDefinition2 = new BooleanProperty();
propertyDefinition2.setName("boolean");
propertyDefinition2.setDisplayName("論理値");
propertyDefinition2.setMultiplicity(1);

List<PropertyDefinition> propertyList = new ArrayList<>();
propertyList.add(propertyDefinition1);
propertyList.add(propertyDefinition2);

EntityDefinition entityDefinition = new EntityDefinition();
entityDefinition.setName("test.SampleEntity");
entityDefinition.setDisplayName("サンプルEntity");
entityDefinition.setPropertyList(propertyList);

// Entity定義の作成
entityDefinitionManager.create(entityDefinition);

// Entity定義の更新
EntityDefinition entityDefinitionUpdate = entityDefinitionManager.get("test.SampleEntity");
entityDefinitionUpdate.setDescription("これはサンプルEntityです。");
entityDefinitionManager.update(entityDefinitionUpdate);

// Entity定義の削除
entityDefinitionManager.remove("test.SampleEntity");
(例2)MessageManagerによるメッセージ操作
import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.message.MessageManager;
import org.iplass.mtp.message.MessageItem;
import org.iplass.mtp.message.MessageCategory;
import org.iplass.mtp.definition.LocalizedStringDefinition;

MessageManager messageManager = ManagerLocator.getInstance().getManager(MessageManager.class);

List<LocalizedStringDefinition> localizedStringDefinitionList = new ArrayList<>();
LocalizedStringDefinition localizedStringDefinition1 = new LocalizedStringDefinition();
localizedStringDefinition1.setLocaleName("en");
localizedStringDefinition1.setStringValue("This is a sample message.");
localizedStringDefinitionList.add(localizedStringDefinition1);

MessageItem messageItem1 = new MessageItem();
messageItem1.setMessageId("M0001");
messageItem1.setMessage("これはサンプルです。");
messageItem1.setLocalizedMessageList(localizedStringDefinitionList);

Map<String, MessageItem> messageItems = new HashMap<>();
messageItems.put(messageItem1.getMessageId(), messageItem1);

MessageCategory messageCategory = new MessageCategory();
messageCategory.setName("test/sample");
messageCategory.setDisplayName("サンプルメッセージ");
messageCategory.setMessageItems(messageItems);

// メッセージ定義の作成
messageManager.create(messageCategory);

// メッセージ定義の更新
MessageCategory messageCategoryUpdate = messageManager.get("test/sample");
messageCategoryUpdate.setDisplayName("サンプルメッセージ(アップデート)");
messageManager.update(messageCategoryUpdate);

// メッセージ定義の削除
messageManager.remove("test/sample");

4. Command

org.iplass.mtp.command.Command を実装する処理ロジックの本体(コード)とそのメタデータです。 Javaもしくは、Groovyで実装が可能です。 iPLAssが提供するjavaBeanへのバインディング機能、バリデーション機能、EntityManagerなどを利用し、リクエストを処理するロジックを記述します。

Commandの実装例
import org.iplass.mtp.command.Command;
import org.iplass.mtp.command.RequestContext;

public class TutorialCommand implements Command {
    @Override
    public String execute(RequestContext request) {
        String paramX = request.getParam("x");

        boolean success = SomeClass.someMethod(paramX);

        if (success) {
            return "SUCCESS";
        } else {
            return "FAIL";
        }
    }
}

execute() メソッド内にリクエストに対する処理を記述します。処理結果を表現するステータス(文字列)を返却するように実装します。 org.iplass.mtp.command.RequestContext はHttpServletRequestを抽象化するインタフェースです。

Commandのインスタンスは、デフォルトの設定では、Servletと同様に複数のリクエストから共有されます。フィールドにはリクエストやセッション、ユーザーに依存する情報を保持しないでください。

作成したCommandクラス/コードはメタデータ(Command定義)としてiPLAssに登録する必要があります。 Command定義はadminConsleから作成、もしくはJavaで記述されたCommandクラス自体にアノテーション記述することより定義可能です。

4.1. Commandの実装

Commandの実装パターンは2つ存在します。

クラス形式によるCommandの実装

org.iplass.mtp.command.Command インターフェースを実装するクラスを作成します。 Javaで実装するか、AdminConsole上からGroovyで記述することが可能です。

実装例(Java)
import org.iplass.mtp.command.Command;
import org.iplass.mtp.command.RequestContext;

public class TutorialCommand implements Command {
    @Override
    public String execute(RequestContext request) {
        String paramX = request.getParam("x");

        boolean success = SomeClass.someMethod(paramX);

        if (success) {
            return "SUCCESS";
        } else {
            return "FAIL";
        }
    }
}
実装例(Groovy)
import org.iplass.mtp.command.Command;
import org.iplass.mtp.command.RequestContext;

class TutorialCommand implements Command {

    String execute(RequestContext request) {
        def paramX = request.getParam("x")

        def success = SomeClass.someMethod(paramX)

        if (success) {
            return "SUCCESS"
        } else {
            return "FAIL"
        }
    }
}

Groovy Script形式によるコマンドの実装

AdminConsole上からGroovyで記述する際に、Groovy Script形式で記述することが可能です。 Scriptは最終的に処理結果を表現するステータス(文字列)を返却するように実装します。

実装例(Groovy Script)
def paramX = request.getParam("x")
def success = SomeClass.someMethod(paramX)

success ? "SUCCESS": "FAIL"

Groovy Scriptにはあらかじめ次の変数名でそれぞれのインスタンスがバインドされています。

変数名 インスタンス

request

org.iplass.mtp.command.RequestContext のインスタンス

em

org.iplass.mtp.entity.EntityManager のインスタンス

edm

org.iplass.mtp.entity.definition.EntityDefinitionManager のインスタンス

auth

org.iplass.mtp.auth.AuthContext のインスタンス

4.2. Command定義(AdminConsole)

AdminConsoleを利用してCommandを定義する方法を説明します。

Command定義の作成

メニュー右クリックし「コマンドを作成する」を選択します。 Typeとして、JavaかScriptを選択します。別途編集画面で変更することが可能です。

Commandの設定項目

Commandの編集画面は2つのパートに分かれます。

共通設定
項目 内容

Name

Command定義名です。
/ 区切りで階層化可能です。
例: gem/auth/LoginCommand

Display Name

表示名です。現状、AdminConsole上でのみ利用されます。

Description

Commandの概要文です。現状、AdminConsole上でのみ利用されます。

Command固有設定
項目 内容

Type

コマンドの実装方法を選択します。
実装方法の詳細については Commandの実装 の章を参照してください。

Java

Javaにて実装します。

Script

Groovyにて実装します。AdminConsoleより、コードを直接編集します。

read only proccess

このCommandの処理をreadOnlyトランザクションで実行可能な場合にtrueを指定します。
デフォルト:false

instantiated for each request

このCommandのインスタンスをリクエスト処理の都度、newする場合にtrueを指定します。
デフォルト:false(同一のインスタンスを共有する)

Java ClassName

(TypeがJavaの場合)
Commandを実装するJavaクラスを指定します。

Script

(TypeがScriptの場合)
Commandの処理を実装するGroovyのコードを記述します。

4.3. Command定義(アノテーション)

JavaにてCommandを実装する場合、Commandクラス自体にアノテーションでCommand定義を設定することが可能です。

アノテーションで定義されたCommand定義はすべてのテナントで有効化されます。

Command定義を行うためのアノテーションは @CommandClass です。設定可能な要素はAdminConsoleでの設定項目に準じます。 詳細はjavadocを参照ください。

アノテーションによる定義のサンプル1
package sample;
import org.iplass.mtp.command.annotation.CommandClass;

@CommandClass(name="sample/tutorial", displayName="チュートリアル",
        description="チュートリアルの説明です")
public class TutorialCommand implements Command {
    @Override
    public String execute(RequestContext request) {

        
        

        return "OK";
    }
}

アノテーションの要素が未指定の場合はデフォルト値が適用されます。
nameが未指定の場合は、クラス名の"."を"/"に置換したものがnameになります。 下記の例だと"sample/TutorialCommand"というnameになります。

アノテーションによる定義のサンプル2
package sample;
import org.iplass.mtp.command.annotation.CommandClass;

@CommandClass
public class TutorialCommand implements Command {
    @Override
    public String execute(RequestContext request) {

        
        

        return "OK";
    }
}

アノテーションされているクラスの解決

iPLAssにおいて、アノテーションされているクラスは自動解決はされません(意図せぬ定義の読み込みを防ぐため)。 service-configの MetaDataRepository の設定にて明示的に読み込むクラスを指定する必要があります。

設定例
<service>
    <interface>org.iplass.mtp.impl.metadata.MetaDataRepository</interface>
    <property name="annotatedClass" value="sample.TutorialCommand" additional="true" />
    <property name="annotatedClass" value="sample.AnotherCommand" additional="true" />

    :
    :
</service>

多数のアノテーションされたクラスが存在する場合、 設定ファイル上にすべてのクラスを羅列せず、 @MetaDataSeeAlso アノテーションを利用することも可能です。

@MetaDataSeeAlsoの利用
package sample;
import org.iplass.mtp.command.annotation.CommandClass;
import org.iplass.mtp.command.annotation.MetaDataSeeAlso;

@MetaDataSeeAlso({
    ACommand.class,
    BCommand.class
})
@CommandClass
public class MainCommand implements Command {
    @Override
    public String execute(RequestContext request) {

        
        

        return "OK";
    }
}

この場合、MainCommandが読み込まれる際に、ACommand、BCommandも同時に読み込まれます。

@MetaDataSeeAlsoアノテーションはCommandクラス以外に指定し、そのクラスをservice-configにて指定することも可能です。

4.4. パラメータのBean/Entityへのマッピング

リクエストパラメータの値をBeanやEntityに自動的にマッピングする機能を提供します。 マッピングを行う場合は、 org.iplass.mtp.command.beanmapper.BeanParamMapper を利用します。

BeanParamMapperの利用例
@CommandClass
public class SampleCommand implements Command {
    private BeanParamMapper mapper = new BeanParamMapper()
            .whitelistPropertyNameRegex("^(age|name|details\..*)$"); (1)

    @Override
    public String execute(RequestContext request) {
        FormBean bean = new FormBean();
        mapper.populate(bean, request.getParamMap()); (2)

        :
        :

        return "OK";
    }
}
1 BeanParamMapperの初期化を行います。Commandのコンストラクト時に行います。
2 beanにパラメータ値を格納します。"age", "name", "details.id" などwhitelistPropertyNameRegexにマッチするパラメータがプロパティにセットされます。

パラメータ名のルール

リクエストパラメータ名(formのinputタグのnameなど)にて、Beanのどのプロパティに値をセットするかを指定します。 デフォルトの設定では、以下のような命名規則が適用されます。

  • パラメータ名と名前が一致するプロパティに値をセットします

  • "."により、ネストされたプロパティを表現します。

  • "[x]"(xは数値)により、List/配列のインデックス指定可能です。

  • "['key']"(keyは任意の文字列)により、Mapのキー指定可能です。 Mapのキー表現"propA['key']"は、propA.keyと表現も可能です。

パラメータ名、値は改竄の恐れがあることを注意してください。パラメータ値を受ける専用のBean(FormBean)を作成しない場合、whitelistPropertyNameRegexにて設定可能なプロパティを制限することを推奨します。
formの定義とbeanの呼び出されるメソッドのイメージ
HTML上のFormでの定義 呼び出されるメソッドのイメージ

<input type="text" name="age" value="25">

bean.setAge(25)

<input type="text" name="accout.name" value="testUser">

bean.getAccount().setName("testUser")

<input type="text" name="details[0].id" value="123">

bean.getDetails()[0].setId(123)

<input type="text" name="map['key1'].id" value="123">

bean.getMap().get('key1').setId("123")

<input type="text" name="map.key1.id" value="123">

bean.getMap().get('key1').setId("123")

パラメータの値は可能な限りbeanの各プロパティの型に自動変換を行います。 変換出来なかった場合は、 org.iplass.mtp.command.beanmapper.MappingException がスローされます。

BeanParamMapperの設定値、詳細はjavadocを参照してください。

4.5. Bean Validationによる検証

BeanParamMapperによるマッピング処理の際に、Bean Validationによる検証を同時に行うことが可能です。 Bean Validationを実行する場合は、withValidationオプションを有効化します。

BeanParamMapperの利用例
@CommandClass
public class SampleCommand implements Command {
    private BeanParamMapper mapper = new BeanParamMapper()
            .withValidation() (1)
            .whitelistPropertyNameRegex("^(age|name|details\..*)$");

    @Override
    public String execute(RequestContext request) {
        FormBean bean = new FormBean();
        mapper.populate(bean, request.getParamMap()); (2)

        :
        :

        return "OK";
    }
}
1 Bean Validaitonを有効化します
2 beanにマップする際にBean Validationも実行されます。

検証に失敗した場合は、 org.iplass.mtp.command.beanmapper.MappingException がスローされます。

EntityのBean Validation

Entityのプロパティの検証を行うValidEntityバリデータを提供します。 Entity定義の各プロパティに定義されたvalidationの設定に従った検証を実行します。

ValidEntityの利用例
import org.iplass.mtp.beanvalidation.constraints.ValidEntity;

public class SampleBean {
    private User user;

    @ValidEntity(properties={"accountId", "rank.*", "groups.**"}) (1)
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    :
    :

}
1 propertiesを指定することにより、検証対象プロパティを指定可能です。 未指定の場合は、ネストされたEntity含め、すべてのプロパティの検証を行います。

ValidEntityの設定値、詳細はjavadocを参照してください。

5. Template

画面を表示するためのプレゼンテーションロジックやリソースを表します。 Templateは実装手段、出力する内容により、いくつかの種類が存在します。 主にhtmlなどのテキストデータを出力する為のJspTemplate、GroovyTemplateやバイナリ出力用のTemplate、帳票出力用のTemplateなどが存在します。 JspTemplateは実装手段としてJSPを利用します。GroovyTemplateはGroovyベースのJSPライクなDSLで記述します。

5.1. Template定義(AdminConsole)

AdminConsoleを利用してTemplateを定義する方法を説明します。

Templateの作成

メニューを右クリックし「テンプレートを作成する」を選択します。
この際、作成するTemplateの種類を指定します。

Templateの設定項目

Templateの設定画面は3つのパートに分かれます。

共通設定
項目 内容

Name

Template定義名です。

Display Name

表示名です。現状、AdminConsole上でのみ利用されます。

Description

Templateの概要文です。現状、AdminConsole上でのみ利用されます。

Template固有設定
項目 内容

Content Type

必要に応じて対象TemplateのContent Typeを設定します。
(例) text/html; charset=utf-8

Type

Templateの種類を設定します。
詳細は Templateの種類 を参照してください。

Layout Action

Layout Actionを設定します。
Layout Actionについては、 Templateの部品化 を参照してください。

Path

(TypeがJSPの場合)
JSPのパスを指定します。

Source

(TypeがGroovyTemplateもしくはHtml(Text Resource)の場合)
ソースコードを直接記述します。

File

(TypeがBinaryの場合)
ファイルを指定します。

多言語設定

言語毎にTemplate定義を異なるものに設定することが可能です。

項目 内容

Language

言語設定を行います。

そのほかの項目

Templateの種別毎に、指定されたLanguageに対応する項目を設定可能です。

5.2. Templateの種類

JSP

Templateの実装にJSPを利用します。
PathにJSPファイルへのパスを指定します。 iPLAssが提供するカスタムタグ、EL関数を利用することが可能です。 詳細は、 JSPカスタムタグ・EL関数 を参照してください。

GroovyTemplate

Templateの実装にGroovyTemplateを利用します。
Sourceにコードを直接記述します。 GroovyTemplateの記法は GroovyTemplate を参照してください。

Html(Text Resource)

Htmlなどの静的なテキストを出力します。
適切なContent Typeを指定した上で、Sourceに直接記述します。

Binary

テキスト以外の静的なバイナリデータを出力します。
適切なContent Typeを指定した上で、ファイルをアップロードします。

Binaryの場合、Layout Actionは設定できません。
Template定義のバイナリデータはメモリ内にキャッシュされます。大きなサイズのバイナリデータを出力したい場合は、 静的リソースAction の実行結果:Streamなどを利用してください。

Report

ExcelやPDFを出力します。
詳細は 帳票出力(Jasper/JXLS/POI) を参照してください。

5.3. Templateの部品化

Templateの一部分をパーツとして切り出し別のTemplateに組み込んだり、Templateに共通のヘッダー・フッターを切り出して、共通のレイアウトとして定義することが可能です。

include(パーツの組み込み)

JSPと同様、Template内に、別に定義されたTemplate/Actionを組み込む(includeする)ことが可能です。 Actionをincludeした場合は、そのActionに紐付けされているCommandの処理も実行されます。

JSPでincludeを行う場合、iPLAssが提供するカスタムタグを呼び出します。

JSPにおけるincludeのサンプル
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="m" uri="http://iplass.org/tags/mtp"%> (1)
<!DOCTYPE html>
<html>
 :
 :
<body>

    <div>
        <p>This is main Contents.</p>
    </div>
    <div>
        <p>include action.</p>
        <m:include action="your/action/name" /> (2)
    </div>
    <div>
        <p>include template.</p>
        <m:include template="your/template/name" /> (3)
    </div>
:
:
</body>
</html>
1 iPLAssの提供するカスタムタグライブラリを定義します
2 actionをincludeする場合はタグ属性actionにAction名を指定します
3 templateをincludeする場合はタグ属性templateにTemplate名を指定します

GroovyTemplateでincludeする場合はinclude/includeTemplate関数を呼び出します。

GroovyTemplateにおけるincludeのサンプル
<!DOCTYPE html>
<html>
 :
 :
<body>

    <div>
        <p>This is main Contents.</p>
    </div>
    <div>
        <p>include action.</p>
        <%include("your/action/name")%> (1)
    </div>
    <div>
        <p>include template.</p>
        <%includeTemplate("your/template/name")%> (2)
    </div>
:
:
</body>
</html>
1 actionをincludeする場合はinclude関数を呼び出します
2 templateをincludeする場合はincludeTemplate関数を呼び出します

LayoutAction(レイアウトの適用)

includeは、Template内にパーツを組み込むための手法ですが、LayoutActionは、Templateの外側にレイアウトを適用する為の仕組みです。 レイアウト(ヘッダやフッター)を作成して、それを、コンテンツを表現する複数のTemplateに共通的に適用することが可能です。

次にJSPでLayoutActionを作成し、適用する例を示します。

レイアウト用Templateを作成する
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="m" uri="http://iplass.org/tags/mtp"%> (1)
<!DOCTYPE html>
<html>
 :
 :
<body>

    <div>
        <p>This is Header.</p>
    </div>

    <m:renderContent /> (2)

    <div>
        <p>This is Footer.</p>
    </div>
:
:
</body>
</html>
1 iPLAssの提供するカスタムタグライブラリを定義します
2 renderContentタグが指定された箇所に個別のTemplateの内容が出力されます

作成したレイアウト用Templateに紐付けたLayoutActionを作成します。 Actionの定義の方法は Action を参照してください。

コンテンツを表現するTemplateを作成する
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

    <div>
        <p>This is main Contents in Template A.</p>
    </div>

上記、TemplateにLayoutActionを適用した場合、次のように出力されます。

html出力結果
<!DOCTYPE html>
<html>
 :
 :
<body>

    <div>
        <p>This is Header.</p>
    </div>

    <div>
        <p>This is main Contents in Template A.</p>
    </div>

    <div>
        <p>This is Footer.</p>
    </div>
:
:
</body>
</html>

GroovyTemplateでLayoutActionを作成する場合は、renderContent関数を利用します。

GroovyTemplateにおけるrenderContentのサンプル
<!DOCTYPE html>
<html>
 :
 :
<body>

    <div>
        <p>This is Header.</p>
    </div>

    <%renderContent()%> (1)

    <div>
        <p>This is Footer.</p>
    </div>
:
:
</body>
</html>
1 renderContent関数を呼び出した箇所に個別のTemplateの内容が出力されます

5.4. Template定義(アノテーション)

Javaにてカスタムロジックを実装する場合、任意のクラス、インタフェースにアノテーションでTemplate定義を設定することが可能です。なお、アノテーションで指定可能なテンプレートの種類はJSPのみとなります。

アノテーションで定義されたTemplate定義はすべてのテナントで有効化されます。

Template定義を行うためのアノテーションは @Template です。 複数のTemplate定義を行う場合は、 @Templates を利用します。 詳細はjavadocを参照ください。

アノテーションによる定義のサンプル
package sample;
import org.iplass.mtp.command.annotation.CommandClass;
import org.iplass.mtp.command.annotation.template.Template;
import org.iplass.mtp.command.annotation.template.Templates;

@Templates({
    @Template(name="sample/top", displayName="トップ画面", path="/jsp/sample/top.jsp", contentType="text/html; charset=utf-8"),
    @Template(name="sample/detail", displayName="詳細画面", path="/jsp/sample/detail.jsp", contentType="text/html; charset=utf-8", layoutActionName="sample/layout")
})
@CommandClass(name="sample/tutorial", displayName="チュートリアル",
        description="チュートリアルの説明です")
public class TutorialCommand implements Command {
    @Override
    public String execute(RequestContext request) {

        
        

        return "OK";
    }
}

Templateアノテーションは、あくまでTemplateを定義するもので、Commandとの関連付けはされません。CommandとTemplateを関連付けするためにはAction定義を行う必要があります。

6. Action

Actionはルーティング制御を行うための定義です。
URLのパス単位に、そのパスが呼び出された場合の対応するCommandと処理結果により表示するTemplate(などの出力内容)の関連を定義します。

Action定義はAdminConsole、もしくは、Javaで実装されたCommandへのアノテーションにより定義可能です。

6.1. Action定義(AdminConsole)

AdminConsoleを利用してActionを定義する方法を説明します。

Actionの作成

メニュー右クリックし「アクションを作成する」を選択します。 アクションの名前はURLのパスとなります。

Actionの設定項目

Actionの設定画面は3つのパートに分かれます。

共通設定
項目 内容

Name

Action定義名です。
アクションを呼び出す際のURLのパスとなります。
/ 区切りで階層化可能です。
Nameを gem/auth/verify2nd と定義した場合、次のURLでこのActionが呼び出されます。

http(s)://[server]/[tenantContextPath]/gem/auth/verify2nd

※[tenantContextPath]については、パスの種類 を参照してください。

Display Name

表示名です。現状、AdminConsole上でのみ利用されます。

Description

Actionの概要文です。現状、AdminConsole上でのみ利用されます。

Action固有設定
Allow Method
項目 内容

Allow Method

アクセス可能なHTTPメソッド(GET, POST, PUT, DELETE)を指定します。
全てチェックされていない場合は全メソッドでのアクセスが可能です。デフォルトでは全てチェックされていない状態となります。
ひとつでもチェックされている場合は、チェックされているメソッドでのみアクセスが可能となります。

Access Policy
項目 内容

parts. not direct access

メインのTempalteからincludeされる部品用のActionの場合指定します。URLを指定した直接の呼び出しは出来なくなります。

privilege execute

Action内の処理において、権限の制約を一切受けずに(特権として)実行する事ができます。

public action

未ログインユーザーでもアクセス可能になります。
通常、未ログインユーザーでも実行可能にするにはAction権限の定義が必要ですが、これをチェックすることでAction権限のチェックを省略することができます。

public Action と privilege execute の違い

public actionは、Actionを誰でも呼び出せるようにするだけです。Entity検索などの際には、Entity権限が適用されます。
一方、privilege executeは、Action実行中は、権限チェックを全く行いません。Entity操作なども特権で実行されます。

synchronize on session

同一Sessionのリクエストを同期します。
このフラグがONにされた場合、Session単位に単一のロック用Objectにてsynchronizeされた上で、Actionの処理が実行されます。

Action処理全体(Templateの処理も含め)を同期します。可能であればCommand内にて必要な箇所で明示的に同期することを推奨します。

trusted authentication required

RememberMe機能を有効にした場合、ブラウザを閉じても一定期間ログイン状態が保持されます。
このフラグを有効化した場合、 RememberMe機能で自動的にログインした状態で、このActionを呼び出した際には再認証が要求されます。
ユーザー情報の更新、パスワードの更新や決済処理など重要な処理を行うActionで、他のユーザーの可能性をできるだけ排除する必要がある場合はこのフラグをチェックしてください。

Token Check
項目 内容

Token Check

CSRF(XSRF)対策用Tokenのチェックを行うか否かを設定します。
また設定により、このTokenを重複サブミット(トランザクションの重複起動)対策として利用することも可能です。

No Check

Tokenのチェックを行いません。

Check

遷移元で指定したTokenを利用し不正な遷移や重複サブミットを検出します。

Tokenのチェックを行う場合は、Tokenの値を送信元画面に埋め込み、リクエストパラメータで送信する必要があります。 その際のパラメータ名は、 _t とする必要があります。

TemplateにてTokenの値を埋め込むためのユーティリティを提供しています。詳細は JSPカスタムタグ・EL関数 また、GroovyTemplate を参照ください。

JSPでの実装例
<%@ taglib prefix="m" uri="http://iplass.org/tags/mtp"%>

<form>
:
:
<input type="hidden" name="_t" value="${m:token()}"> (1)
<input type="submit" />
</form>
1 Tokenの値を出力するEL関数です。

use fixed Token

Tokenチェックに、セッション単位に固定に払いだされる固定Tokenを利用します。CSRF(XSRF)対策のみ必要な場合は固定Tokenを利用可能です。

固定Tokenを利用する場合、送信元画面には固定Tokenの値を埋め込む必要があります。

JSPでの実装例
<%@ taglib prefix="m" uri="http://iplass.org/tags/mtp"%>

<form>
:
:
<input type="hidden" name="_t" value="${m:fixToken()}"> (1)
<input type="submit" />
</form>
1 固定Tokenの値を出力するEL関数です。

consume a Token

このAction実行時にチェックしたTokenを消費します。
消費されたTokenは再利用できません(同一Tokenでリクエストが来た場合、エラーになります)。
重複サブミット(トランザクションの重複起動)を防ぐためには、トランザクションを完了するActionにおいて、このフラグをONにします。

複数の画面をまたがってトランザクションを完了する場合、このフラグをONにする必要があるのは完了画面(および、キャンセル時)です。

Tokenの消費についての例を示します。

入力画面→確認画面→完了画面

といった画面遷移がある場合に、トランザクションTokenを利用して

入力画面:トランザクションToken発行
確認画面:トランザクションToken確認(ただし消費しない)→ consumeチェックなし
完了画面:トランザクションToken消費 → consumeチェックあり

といった事が可能になります。

rollback on exception

Exception発生時にTokenを消費しません。

Client Cache
項目 内容

Client Cache

レスポンスのキャッシュ設定を指定します。

Cache

クライアントへ当該レスポンスのキャッシュを許可します。具体的には Cache-Control ヘッダに private を指定します。

Cache Public

共有キャッシュへ当該レスポンスのキャッシュを許可します。具体的には Cache-Control ヘッダに public を指定します。

Cache Publicを設定する場合、プロキシサーバやCDNがキャッシュする可能性があり、キャッシュのコントロールが難しくなります。 不特定多数のユーザーに対して同一のキャッシュが返却されるので、注意が必要です。
例えば、ログイン後のユーザーの個人情報が表示されるページをCache Publicしてしまった場合、そのユーザー以外の人が同一URLにアクセスした場合、本来参照できないはずの別ユーザーの個人情報が参照できてしまいます。
Not Cache

クライアントへ当該レスポンスをキャッシュしないように指示します。具体的には Cache-Control ヘッダに private, no-store, no-cache, must-revalidate を指定します。

Default

service-config内の WebFrontendServicedefaultClientCacheType の設定が適用されます。

Max Ageの値を指定しない場合、ブラウザにより挙動が異なりますのでご注意ください。

Max Age

クライアントへ当該コンテンツのキャッシュ有効期間(秒)を通知します。
0未満の値は未設定とみなされます。

レスポンスのキャッシュが許可された場合( Cache-Controlprivate の場合 )、Cache-Control ヘッダに max-age 属性を追加します。

Restriction of Request
項目 内容

Allow Request Content Types

許可するcontentTypeを指定します。未指定の場合は全て許可します。
複数のcontentTypeを指定する場合は、半角スペースで区切ってください。

Max Request Body Size

リクエストボディの最大サイズ(Byte)を指定します。
contentTypeが application/x-www-form-urlencoded の場合は適用されません。

Max File Size

リクエストされるファイルの最大サイズ(Byte)を指定します。

Parameter Mappings
項目 内容

Parameter Name

パラメータマッピング機能における、パラメータ名を指定します。
パラメータマッピング を参照ください。

Map From

パラメータマッピング機能における、マッピング元を指定します。

Condition

パラメータマッピング機能における、マッピング処理を行う条件を指定します。

Execute Commands
項目 内容

Command Name

Action呼び出し時に実行されるCommandです。
Commandの設定 を参照ください。

Init Script

Commandのインスタンスの初期化ロジックが設定されているか否かを表示します。

Results
項目 内容

Status

Command実行結果スタータスです。
Resultsでは、Commandの処理結果とそれに対応する出力処理を定義します。 詳細は結果の設定 を参照ください。

Exception Class Name

例外クラス名です。 Command実行時に例外が発生した場合の出力処理を定義します。

Type

出力処理の種類を示します。

Value

出力処理の内容を示します。

Server Cache Criteria
項目 内容

Cache Criteria Type

サーバキャッシュの設定を行うことにより、 Actionの実行結果の出力(コンテンツ)をサーバ側でキャッシュすることが可能です。 機能の詳細は サーバキャッシュ設定 を参照ください。

サーバキャッシュ設定では、キャッシュする際の単位(キャッシュ基準)を定義する必要があります。
Cache Criteria Typeはキャッシュ基準のタイプの設定します。
以下のタイプを指定できます。

JavaClass

キャッシュ基準の定義をjavaクラスで実装します。

ParameterMatch

HTTPリクエストパラメータの値を利用してキャッシュ基準を定義します。

Script

キャッシュ基準の定義をGroovy Scriptで実装します。

Not Cache

サーバキャッシュを利用しないように設定します。

Time to Live (ms)

キャッシュの有効期間(ミリ秒)を設定します。
0以下を指定した場合は無制限になります。

Java ClassName

(Cache Criteria TypeがJavaClassの場合)
キャッシュ基準を定義する org.iplass.mtp.web.actionmapping.ActionCacheCriteria を実装する java classを指定します。

Matching Parameter Names

(Cache Criteria TypeがParameterMatchの場合)
キャッシュ基準となるパラメーターのキーを設定します。

Sctipt

(Cache Criteria TypeがScriptの場合)
キャッシュ基準を定義するscriptを設定します。

Cachable Result Status
項目 内容

Status

ここで指定したステータスがCommandから返却された際にキャッシュします。 * を指定した場合、すべてのステータスにおいてキャッシュします。

Cache Related Entities
項目 内容

Entity Name

キャッシュしたコンテンツをEntity更新時に無効化したい場合、その関連しているEntityを指定します。

Type

コンテンツとEntityの関連のタイプを指定します。 更新が発生した時にキャッシュをクリアするエンティティを設定します。

SPECIFIC_ID

oid単位で関連を管理します。当該oidのEntityが更新された場合、キャッシュをクリアします。

WHOLE

Entity全体で関連を管理します。当該Entityのいずれかのデータが更新された場合、キャッシュをクリアします。

Clear Cache
項目 内容

Clear Action Cache

当該アクションのコンテンツキャッシュをクリアします。

Clear Tenant Action Cache

テナント全体のアクションのコンテンツキャッシュをクリアします。

6.2. パラメータマッピング

リクエストに含まれるパラメータを別名にマッピングしたり、URLのパスの一部をパラメータにマッピングすることが可能です。

Parameter Nameに指定したパラメータ名に、Map Fromで指定されたパス、もしくは別パラメータをマッピングします。 Map Fromには、リクエストURLのパスの一部を表すパターン文字列、もしくは別パラメータ名を指定することが可能です。

パスのマッピング

パスをマッピングする場合、特別なパターン文字列を利用します。

${n}

${n} 形式でパス階層の一部をマッピング可能です。
nはAction名以降のパスの階層数を示します。
${0} とした場合Action名より1階層下層のパスの値が、 ${1} とした場合Action名より2階層下層のパスの値がマップされます。

${paths}

${paths} とした場合、Action名以降のサブパスがマップされます。

パスマッピング例

Action名が sample/act1 の場合、 sample/act1/path1/path2/path3?paramX=fuga を呼び出した場合、Map Fromに設定した値によって、 それぞれ次の値がパラメータにマップされます。

  • ${0} → path1

  • ${1} → path2

  • ${paths} → path1/path2/path3

マッピング条件の指定

Conditionを指定することにより、パラメータマッピングを実行する条件を指定することが可能です。 Conditionはgroovy Scriptで記述可能です。

次の変数がバインドされており条件判断に利用可能です。

変数名 説明

subPath

action名より下層のサブパスを/で分割したString配列

fullPath

action名含めたフルパスを/で分割したString配列

paramMap

リクエストパラメータのMap

たとえば、次のようなパラメータマッピング定義がある場合、

Name Map From Condition

defName

${0}

subPath.length==1

viewName

${0}

subPath.length==2

defName

${1}

subPath.length==2

action1に対するリクエストパスが、

action1/hogeだった場合

defName=hoge

action1/hoge/fugaだった場合

viewName=hoge, defName=fuga

となります。

6.3. Commandの設定

本Actionが呼ばれた際に実行するCommandとその処理方法を設定します。

項目 内容

Execute Command

Actionを呼び出された際に実行するCommandです。

Transaction Propagation

このCommand実行時のトランザクション制御方法を指定します。 次のいずれかを指定します。デフォルト値はREQUIREDです。

REQUIRED

トランザクションが開始されていなかったら、開始(およびコミット/ロールバック)します。すでにトランザクションが開始されている場合は、そのトランザクションのコンテキストで実行されます。

REQUIRES_NEW

新規にトランザクションを開始(およびコミット/ロールバック)します。既存のトランザクションが存在した場合は、一旦サスペンドされ当該処理完了後、レジュームされます。

NOT_SUPPORTED

トランザクション制御をしません。既存のトランザクションが開始されている場合は、一旦そのトランザクションがサスペンドされ当該処理完了後、レジュームされます。

SUPPORTS

トランザクションが開始されていない場合は、トランザクション制御しません。既にトランザクションが開始されている場合は、そのトランザクションのコンテキストで実行されます。

Rollback when exception

Command実行時に例外がスローされた場合、自動的にトランザクションをロールバックするか否かを指定します。

Throw Exception if setRollbackOnly

トランザクションが本Command処理用に新規作成された際、 且つCommand処理中にsetRoobackOnlyされた場合、かつ明示的に例外がスローされなかった場合、iPLAss側で例外扱い( org.iplass.mtp.transaction.RollbackException をスロー)にするか否かの設定です。

Init Script

Commandのインスタンスの初期化Script(Groovy Script)を指定可能です。

対象となるCommandのインスタンスは cmd としてバインドされています。
初期化Scriptの例を示します。

cmd.propA = 1000;
cmd.propB = true;
通常はインスタンスが複数のリクエストで共有されるため、この初期化処理は一度のみ実行されます。
ただしCommand定義にて、instantiated for each request 設定を有効化している場合、リクエストの都度、初期化処理が実行されます。

複合Commandの設定

1つのActionに対して複数のCommandを紐付けすることが可能です。

複数のCommandが紐付けされた場合、デフォルトでは次のような動作になります。

  • 定義された順番にCommandを実行

  • 最後に定義されたCommandの実行結果ステータスを全体の実行結果ステータスとする

条件により、処理順を変更するなど複雑な制御が必要な場合、Composite Command Configにて制御Scriptを記述可能です。

Composite Command Configの設定
項目 内容

Transaction Propagation

この複合Command実行時のトランザクション制御方法を指定します。

指定可能な値は、単一のCommand設定のTransaction Propagationの値と同様です。 デフォルト値はREQUIREDです。

Rollback when exception

この複合Command実行時に例外がスローされた場合、自動的にトランザクションをロールバックするか否かを指定します。

Throw Exception if setRollbackOnly

トランザクションが本複合Command処理用に新規作成された際、 且つCommand処理中にsetRoobackOnlyされた場合、かつ明示的に例外がスローされなかった場合、iPLAss側で例外扱い( org.iplass.mtp.transaction.RollbackException をスロー)にするか否かの設定です。

Initilize Script

複数のCommandの初期化処理のスクリプトを設定可能です。 あらかじめ変数の cmd にCommandのインスタンスが配列でバインドされています。

設定例
cmd[0].propA = 10
cmd[1].propB = 'hoge'

上記の場合、一覧の1番目(配列のindex=0)のCommandのプロパティpropAに10、 2番目(配列のindex=1)のコマンドのプロパティpropBにhogeといった値が設定されます。

複合Commandを構成しているCommand定義にて、instantiated for each request 設定を有効化しているものがひとつでも存在する場合、リクエストの都度、初期化処理が実行されます。

Execute Rule Script

Commandが複数定義された場合に、Commandの実行順やステータスによる処理分岐などの制御をGroovyScriptで記述することが可能です。
実行スクリプトが未指定の場合は定義されたCommandの順番に実行され、実行結果ステータスは最後のCommandの戻り値が利用されます。

あらかじめ変数の cmd にCommandのインスタンスが配列でバインドされています。 また、request の変数名でRequestContextのインスタンスがバインドされています。

記述例
if (cmd[0].execute(request) == 'OK') {
    return cmd[1].execute(request)
} else {
    return cmd[2].execute(request)
}

6.4. 結果の設定

Commandの実行結果に対応した出力内容を設定します。
設定は、実行結果ステータス、もしくは発生した例外クラスごとに設定することが可能です。

項目 内容

Status

Commandの execute() の戻り値のステータス文字列を指定します。
全ての戻り値で同一の出力を行う場合は * を指定します。

Exception Class Name

Exceptionのクラス名を指定します。
Commandの execute() 実行時に当該の例外が発生した場合、ここに定義された出力を行います。

Type

出力内容のタイプを指定します。 次のいずれかを指定します。

Template

Templateの内容を出力します。 Result: Template を参照ください。

DynamicTemplate

動的にTemplateを選択し、内容を出力します。 Result: DynamicTemplate を参照ください。

Redirect

HTTPリダイレクトします。 Result: Redirect を参照ください。

Stream

バイナリストリームを出力します。 Result: Stream を参照ください。

StaticResource

静的リソースを出力します。 Result: StaticResource を参照ください。

Result: Template

選択したTemplateを実行し、結果を出力します。 次の項目の設定をします。

項目 内容

Template

Template定義を指定します。

Layout Action

TemplateにLayout Actionを適用する場合は指定します。 Layout Actionについては Templateの部品化 を参照ください。

Template自体にLayout Actionが指定されている場合、本設定(Result: Templateでの設定)が優先されます。

Set Content Dissposition

有効化すると HTTPレスポンスに Content-Disposition ヘッダーが付与されます。

Content Dissposition Type

Attachment

Content-Disposition: attachment が設定されます。

Inline

Content-Disposition: inline が設定されます。

Default

WebFrontendService で定義されるデフォルト値が適用されます。

FileName AttributeName

Content-Dispositionヘッダーのfilename属性に設定する値を指定します。

ダウンロードファイルのファイル名を格納したRequestContext上のattribute名を指定します。
ファイル名自体は、Commandの処理等で事前にRequestContextに格納します。

ファイル名が未指定(RequestContextから指定attribute名で取得した値がnull、もしくはFileName AttributeNameが未設定)の場合は、Template名がファイル名として利用されます。

Result: DynamicTemplate

Templateを動的に選択し、その選択されたTemplateを結果として出力します。

出力するTemplateを選択するロジックはCommand内に記述します。 選択したTemplate名をRequestContextに格納します。

Commandでの実装例
public class SampleCommand implements Command {

    @Override
    public String execute(RequestContext request) {
        //do business logic
        :

        //resolve Template to output
        if (someDecision()) {
            request.setAttribute("templateName", "some/Template1"); (1)
        } else {
            request.setAttribute("templateName", "some/Template2");
        }

        return "SUCCESS";
    }

    :
}
1 RequestContextに、任意のattribute名でTemplate名を格納します。attribute名はResult: DynamicTemplate定義のTemplate AttributeNameに指定します。

Result: DynamicTemplateでは次の項目の設定をします。

項目 内容

Template AttributeName

RequestContextにTemplate名を格納する際のattribute名を指定します。

Layout Action AttributeName

RequestContextにLayout Aciton名を格納する際のattribute名を指定します。 Layout Actionについては Templateの部品化 を参照ください。

Template自体にLayout Actionが指定されている場合、本設定(Result: DynamicTemplateでの設定)が優先されます。

Set Content Dissposition

有効化すると HTTPレスポンスに Content-Disposition ヘッダーが付与されます。

Content Dissposition Type

Attachment

Content-Disposition: attachment が設定されます。

Inline

Content-Disposition: inline が設定されます。

Default

WebFrontendService で定義されるデフォルト値が適用されます。

FileName AttributeName

Content-Dispositionヘッダーのfilename属性に設定する値を指定します。

ダウンロードファイルのファイル名を格納したRequestContext上のattribute名を指定します。
ファイル名自体は、Commandの処理等で事前にRequestContextに格納します。

ファイル名が未指定(RequestContextから指定attribute名で取得した値がnull、もしくはFileName AttributeNameが未設定)の場合は、Template名がファイル名として利用されます。

Result: Redirect

HTTPリダイレクト(ステータスコード:302)を行います。

リダイレクト先のURL(String)はCommand内にて任意のattribute名にてRequestContextに格納します。

項目 内容

RedirectPath AttributeName

RequestContextにリダイレクト先のURL(String)を格納する際のattribute名を指定します。

set Allow ExternalLocation

有効化した場合、外部サイトへのリダイレクトが可能になります。

Result: Stream

ストリームデータを出力します。

Command内の処理にてRequestContextに格納されたストリームデータを返します。 ストリームデータは次のいずれかのインスタンスを指定可能です。

java.io.InputStream

指定されたInputStreamを出力します。InputStreamのcloseはiPLAssが自動的に行います。

byte[]

指定されたbyte[]を出力します。

org.iplass.mtp.entity.BinaryReference

BinaryReferenceの出力 を参照ください。

org.iplass.mtp.web.ResultStreamWriter

ResultStreamWriterの出力 を参照ください。

項目 内容

Stream AttributeName

RequestContextにストリームデータを格納する際のattribute名を指定します。

ContentType AttributeName

RequestContextにContentTypeを格納する際のattribute名を指定します。

指定されたストリームデータがBinaryReferenceの場合は、値を設定しなくともBinaryReferenceの情報から自動的に解決されます。

ContentLength AttributeName

RequestContextにContentLengthを格納する際のattribute名を指定します。

指定されたストリームデータがBinaryReference、byte[]の場合は、値を設定しなくと自動的に解決されます。

Accept Ranges

ファイルダウンロード時にRangeヘッダに対応します。 ファイルダウンロードのレジュームが可能になります。

Range対応する場合は、同一リクエストパラメータで同一の結果(コンテンツデータ)が返却されることが前提となります(参照透過性が必要)。
また、出力対象のコンテンツデータのサイズが既知(※)であることが前提となります。

※対象データが、BinaryReference、byte[]もしくは、RequestContextにContentLength AttributeNameに指定されるキーで、ContentLengthの値が設定されていること。

Set Content Dissposition

有効化すると HTTPレスポンスに Content-Disposition ヘッダーが付与されます。

Content Dissposition Type

Attachment

Content-Disposition: attachment が設定されます。

Inline

Content-Disposition: inline が設定されます。

Default

WebFrontendService で定義されるデフォルト値が適用されます。

FileName AttributeName

Content-Dispositionヘッダーのfilename属性に設定する値を指定します。

ダウンロードファイルのファイル名を格納したRequestContext上のattribute名を指定します。
ファイル名自体は、Commandの処理等で事前にRequestContextに格納します。

ファイル名が未指定(RequestContextから指定attribute名で取得した値がnull、もしくはFileName AttributeNameが未設定)の場合は次の値が設定されます。

ストリームデータがBinaryReferenceの場合

BinaryReferenceの情報からファイル名を設定します。

ストリームデータがBinaryReference以外の場合

Action名がファイル名として利用されます。

BinaryReferenceの出力

BinaryReferenceはEntityに定義されるBinaryReference型のプロパティの値です。 org.iplass.mtp.entity.EntityManager のapiを利用し、Entityから取得、 もしくはlobIdを指定して直接取得することが可能です。

以下にBinaryReferenceを利用してストリームデータを出力するCommand(groovy script)の例を示します。

実装例(groovy script)
import org.iplass.mtp.entity.BinaryReference;

def lobId = request.getParamAsLong("lobId");
BinaryReference br = em.loadBinaryReference(lobId);

request.setAttribute("resultStream", br); (1)

return "SUCCESS";
1 Stream AttributeNameに resultStream が定義されている場合
ResultStreamWriterの出力

ResultStreamWriterは、動的にストリームデータの出力処理を行いたい場合に利用します。 org.iplass.mtp.web.ResultStreamWriter を実装し、 そのインスタンスをストリームデータとしてRequestContextに格納します。

実装例
import org.iplass.mtp.command.Command;
import org.iplass.mtp.command.RequestContext;
import org.iplass.mtp.web.ResultStreamWriter;

public class SampleCommand implements Command {

    @Override
    public String execute(RequestContext request) {

        :

        ResultStreamWriter rsw = out -> { (1)

            //write data to out
            :

            out.write(binaryData);
            :

        };

        //set ResultStreamWriter and its metadata
        request.setAttribute("resultStream", rsw); (2)
        request.setAttribute("contentType", "image/svg+xml"); (3)
        request.setAttribute("fileName", "sample.svg"); (4)

        return "SUCCESS";
    }

}
1 ResultStreamWriterのインスタンスを生成します。
2 Stream AttributeNameに resultStream が定義されている場合
3 ContentType AttributeNameに contentType が定義されている場合
4 FileName AttributeNameに fileName が定義されている場合

Result: StaticResource

選択した静的リソース(Static Resource)を返します。 Static Resourceは単一のファイル、もしくはzipでまとめられた複数のファイルを表します。 Static Resource自体の詳細は、 Static Resource を参照してください。

Static Resourceがzipファイルの場合は、返却するファイルのzip内のパス文字列(entryPath)を指定する必要があります。 entrypathはRequestContext、またはリクエストパラメータから任意のキー名で取得されます。

項目 内容

StaticResource

別途定義されたStatic Resourceの名前を指定します。

EntryPath AttributeName

Static Resourceがzipファイルの場合、zip内のパス文字列(entryPath)を取得する際のキー名を指定します。

Static Resourceの場合、entryPathは、RequestContextのattribute、リクエストパラメータの両方から取得されます。

Set Content Dissposition

有効化すると HTTPレスポンスに Content-Disposition ヘッダーが付与されます。

Content Dissposition Type

Attachment

Content-Disposition: attachment が設定されます。

Inline

Content-Disposition: inline が設定されます。

Default

WebFrontendService で定義されるデフォルト値が適用されます。

ファイル名は、Static Resourceがzipファイルの場合はentryPathで指定されるファイルから適切に解決します。Static Resourceが単一ファイルの場合は、Action名がファイル名となります。

URLをダイレクトにマッピング

次のような定義を行うことで、StaticResourceのzip内のファイルをダイレクトにURLにマッピングすることが可能です。

  1. パラメータマッピング にて、パラメータ名: entryPath${paths} をマッピング

  2. Commandは未指定

  3. Result: StaticResourceのEntryPath AttributeNameに entryPath を指定。

上記の設定を行ったActionを sr の名前で作成した場合、

https://[server]/[tenantContext]/sr/path/of/entry.jpg

を呼び出した場合、 zip内の path/of/entry.jpg ファイルが出力されます。

URLダイレクトにマッピングした場合、当該Actionを参照可能なユーザーはzip内のファイルはすべて参照可能となることに注意してください。

6.5. サーバキャッシュ設定

レスポンス結果をサーバでキャッシュする方法を設定します。 キャッシュ基準、有効期間、キャッシュ可能な結果ステータス、関連するEntityを適切に設定する必要があります。

キャッシュ基準

サーバキャッシュ設定では、キャッシュする際の単位(キャッシュ基準)を定義する必要があります。 キャッシュ基準の定義の方法はいくつか存在します。

ParameterMatch

HTTPリクエストパラメータの一致をもって、キャッシュ単位を制御します。 指定されたパラメータ名の値が一致する場合、同一のキャッシュとみなします。 パラメータ名は複数設定が可能です。

JavaClass

キャッシュ基準の定義をjavaクラスで実装します。 org.iplass.mtp.web.actionmapping.ActionCacheCriteria を実装します。 ActionCacheCriteriaの実装では、 キャッシュを一意に特定するためのキー(文字列)を返却するように実装します。

実装例
import org.iplass.mtp.auth.AuthContext;
import org.iplass.mtp.auth.User;
import org.iplass.mtp.command.RequestContext;
import org.iplass.mtp.web.actionmapping.ActionCacheCriteria;

/**
 * Userのランクコードと、パラメータparamAの組み合わせ単位でキャッシュする
 */
public class SampleActionCacheCriteria implements ActionCacheCriteria {

    @Override
    public String createCacheKey(RequestContext request) {

        User user = AuthContext.getCurrentContext().getUser();

        if (user.isAnonymous()) {
            return null; (1)
        }

        StringBuilder sb = new StringBuilder();
        sb.append(user.getRank().getCode());
        sb.append(",");
        sb.append(request.getParam("paramA"));

        return sb.toString(); (2)
    }

}
1 nullを返却した場合、当該のリクエストの出力はキャッシュしません。
2 Userのランクコード、paramAの値を結合してキャッシュ用のキーを生成しています。
Script

キャッシュ基準の定義をGroovy Scriptで実装します。 キャッシュを一意に特定するためのキー(文字列)を返却するように実装します。

以下の変数がバインドされています。

変数名 説明

request

RequestContextのインスタンス

user

UserBindingのインスタンス。 UserBindingについては、 Groovy Script を参照ください。

auth

AuthContextのインスタンス

実装例
if (user.anonymous) {
    return null (1)
}

"${user.rank.code},${request.param.paramA}" (2)
1 nullを返却した場合、当該のリクエストの出力はキャッシュしません。
2 Userのランクコード、paramAの値を結合してキャッシュ用のキーを生成しています。

キャッシュに関連するEntity

キャッシュしたコンテンツをEntity更新時に無効化したい場合、その関連しているEntityを紐付けしておくことで、当該Entityが更新、削除された際にキャッシュが無効化されます。

紐付きの管理の仕方には以下が存在します。

SPECIFIC_ID

oid単位で関連を管理します。当該oidのEntityが更新された場合、キャッシュをクリアします。

WHOLE

Entity全体で関連を管理します。当該Entityのいずれかのデータが更新された場合、キャッシュをクリアします。

当該Actionの処理中のEntityManager経由のEntity操作は自動的に記録され、キャッシュに紐付けられます。 EntityManager経由で操作はしていないが、特定のEntityをActionのキャッシュに紐付けしたい場合、 org.iplass.mtp.web.actionmapping.ActionUtil で提供されるメソッドを利用して明示的に紐付けることも可能です。

Entity更新有無は、EntityManagerのapiを経由した更新処理を監視します。直接のDB更新した場合などは正常にキャッシュ制御されません。

6.6. Action定義(アノテーション)

JavaにてCommandを実装する場合、クラス自体にアノテーションでAction定義を設定することが可能です。 単一のCommandに複数のActionMappingをアノテーションすることも可能です。

アノテーションで定義されたAction定義はすべてのテナントで有効化されます。

Action定義を行うためのアノテーションは @ActionMapping です。設定可能な要素はAdminConsoleでの設定項目に準じます。 詳細はjavadocを参照ください。

Commandクラス以外のクラス、インタフェースに対して@ActionMapping定義することも可能です。ただし、この場合command属性もしくはcompositeCommand属性にてcommandClassを明示的に指定する必要があります。
アノテーションによる定義のサンプル
import org.iplass.mtp.command.annotation.action.ActionMapping;
:

@ActionMapping(name="tutorial",
    displayName="チュートリアルアクション",
    tokenCheck=@TokenCheck,
    paramMapping=@ParamMapping(name="view", mapFrom="{0}"),
    result={
        @Result(status="OK", type=Type.TEMPLATE,
                value="/template/okview"),
        @Result(status="NG", type=Type.JSP,
                value="/jsp/sample/ng.jsp",
                templateName="sample/ng",
                layoutActionName="sample/layout")
    }
)
@CommandClass(name="tutorial")
public class TutorialCommand implements Command {
    @Override
    public String execute(RequestContext request) {

        // 処理

        if ( ... ) {
            return "NG";
        } else {
            return "OK";
        }
    }
}

7. Transaction

カスタムロジック内でトランザクション制御を行う場合は、 org.iplass.mtp.transaction.Transaction インタフェースを利用します。

ActionやWebApiから呼び出されるCommandは自動的にトランザクション制御が開始されます。
現状、iPLAssはグローバルトランザクションをサポートしません。
Transactionインタフェースの操作は単一のJDBC Connectionに対するローカルトランザクションとして機能します。
Transactionの利用例
import org.iplass.mtp.transaction.Transaction;
:

EntityManager em = ...
:


//新規にトランザクションを起動
Transaction.requiresNew(t -> { (1)
    Entity e = new GenericEntity();
    e.setName("test");

    //ロールバック時に実行する処理を追加
    t.afterRollback(() -> {
        System.err.println("Rollback!");
    });

    em.insert(e);
}); (1)
1 この間のコードが別トランザクション( REQUIRES_NEW )で処理されます

Transaction インタフェースの詳細はjavadocを参照ください。

7.1. Propagation

トランザクションはPropagation(伝播方法)を指定して開始します。 org.iplass.mtp.transaction.Propagation に種別が定義されます。 また、それぞれのPropagationの種別で呼び出すためのメソッドが Transaction インタフェースに定義されています。

Propagationの種別
種別 説明

REQUIRED

トランザクションが開始されていなかったら、開始(およびコミット/ロールバック)します。すでにトランザクションが開始されている場合は、そのトランザクションのコンテキストで実行されます。

Transactionの利用例
Transaction.required(t -> {
    //トランザクション処理
    :

});

もしくは、

Transaction.with(Propagation.REQUIRED, t -> {
    //トランザクション処理
    :

});

REQUIRES_NEW

新規にトランザクションを開始(およびコミット/ロールバック)します。既存のトランザクションが存在した場合は、一旦サスペンドされ当該処理完了後、レジュームされます。

Transactionの利用例
Transaction.requiresNew(t -> {
    //トランザクション処理
    :

});

もしくは、

Transaction.with(Propagation.REQUIRES_NEW, t -> {
    //トランザクション処理
    :

});

NOT_SUPPORTED

トランザクション制御をしません。既存のトランザクションが開始されている場合は、一旦そのトランザクションがサスペンドされ当該処理完了後、レジュームされます。

Transactionの利用例
Transaction.with(Propagation.NOT_SUPPORTED, t -> {
    //トランザクション外の処理
    :

});

SUPPORTS

トランザクションが開始されていない場合は、トランザクション制御しません。既にトランザクションが開始されている場合は、そのトランザクションのコンテキストで実行されます。

Transactionの利用例
Transaction.with(Propagation.SUPPORTS, t -> {
    //トランザクション外の処理
    :

});

7.2. TransactionListener

トランザクション処理のコミット・ロールバック時に実行する追加の処理を実行可能です。
org.iplass.mtp.transaction.TransactionListener インタフェースを実装し、 Transaction のインスタンスに登録、もしくは関数インタフェースを直接 Transaction のインスタンスに登録します。

また、実行中のトランザクションのコンテキストに、紐付けて保持したい属性を Transaction#setAttribute()/getAttribute() で保持、取得可能です。

TransactionListenerの利用例
import org.iplass.mtp.transaction.Transaction;
import org.iplass.mtp.transaction.TransactionListener;
:

class SampleListener implements TransactionListener {
    @Override
    public void afterCommit(Transaction t) {
        String myInfo = (String) t.getAttribute("myInfo");
        System.out.println("commit:" + myInfo);
    }

    @Override
    public void afterRollback(Transaction t) {
        String myInfo = (String) t.getAttribute("myInfo");
        System.out.println("rollback:" + myInfo);
    }
}

:
:

void someMethod() {
    Transaction.required(t -> {
        t.addTransactionListener(new SampleListener()); (1)

        //トランザクション処理
        :
        :

        t.setAttribute("myInfo", "in transaction"); (2)
    });

}
1 TransactionのインスタンスにTransactionListenerを登録
2 TransactionListenerに渡す属性をセット
関数インタフェースでTransactionListenerを登録
import org.iplass.mtp.transaction.Transaction;
import org.iplass.mtp.transaction.TransactionListener;
:

void someMethod() {
    Transaction.required(t -> {

        t.afterCommit(() -> {
            String myInfo = (String) t.getAttribute("myInfo");
            System.out.println("commit:" + myInfo);
        });

        //トランザクション処理
        :
        :

        t.setAttribute("myInfo", "in transaction");
    });

}

8. UtilityClass

Groovyを利用してユーティリティ機能やCommandでの共通ロジックなどの処理を実装するためのメタデータです。

Groovyで作成したCommandやGroovyTemplateで作成したTemplateなど、Groovyベースの実装から利用することが可能です。 またJavaで作成したCommandなどから利用する方法も提供します。

8.1. UtilityClass定義

UtilityClassの作成

メニューを右クリックし「UtilityClassを作成する」を選択します。

UtilityClassの設定項目

共通設定
項目 内容

Name

UtilityClass定義名です。
.区切りで階層化可能です。階層はパッケージと同じです。
例: sample.util.SampleUtil

ここで定義した名前がUtilityClassのクラス名になります。

Display Name

表示名です。現状、AdminConsole上でのみ利用されます。

Description

Commandの概要文です。現状、AdminConsole上でのみ利用されます。

固有設定
項目 内容

Script

GroovyまたはGroovyScriptにて実装します。AdminConsoleより、コードを直接編集します。

UtilityClassにはバインド変数はありません。

実装サンプル1(Groovy)
package sample.util;

class SampleUtil {

    public String sample1() {
        return "サンプル1";
    }
}
パッケージ、クラス名については、UtilityClassのnameにあわせてください。 一致していない場合にもエラーにはなりません。呼び出し時は、nameに指定した値をクラス名として利用します。
実装サンプル2(GroovyScript)
def sample2() {
    return "サンプル2";
}
Commandからの呼び出しサンプル
import  sample.util.SampleUtil;
import  sample.util.SampleUtil2;

//ユーティリティクラスのインスタンス生成
SampleUtil util = new SampleUtil();
util.sample1();

SampleUtil2 util2 = new SampleUtil2();
util2.sample2();

8.2. Javaからの利用

Javaで実装したCommandで、処理の一部をUtilityClassで実装する場合など、JavaからUtilityClassを利用する方法を説明します。

例えば複数のテナントを利用する場合、Javaで実装するCommandは全てのテナントで共通した処理になりますが、 一部の処理をUtilityClassを利用することでテナント固有の処理を実行することも可能です。

JavaからUtilityClassを利用する場合は、以下の方法で行います。

  1. JavaにUtilityClassで実装する処理のインターフェースを定義

  2. UtilityClassはインターフェースを実装

  3. UtilityClassを利用する場合は、 UtilityClassDefinitionManager を利用

1.Javaでインターフェースを定義
package sample.util;

public interface SampleLogic {

    String doLogic();
}
2.UtilityClassはインターフェースを実装
package sample.util;

import sample.util.SampleLogic;    //実装するInterface(Javaクラス)

public class UtilityClassLogic implements SampleLogic {

    @Override
    public String doLogic() {    //Logicの実装
        return "hoge";
    }
}
3.JavaのCommandでUtilityClassを利用
package sample.util;

import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.utilityclass.definition.UtilityClassDefinitionManager;

import sample.util.SampleLogic;

:

UtilityClassDefinitionManager ucdm = ManagerLocator.manager(UtilityClassDefinitionManager.class);

SampleLogic logic = null;
try {
    //UtilityClassのインスタンスを取得(SampleLogicインターフェースとして)
    logic = ucdm.createInstanceAs(SampleLogic.class, "sample.util.UtilityClassLogic");
} catch (ClassNotFoundException e) {
    //指定したUtilityClassが定義されていなければJavaで実装したLogicを利用するなど
    logic = new JavaSomeLogic();
}

logic.doLogic();
利用しようとしているUtilityClassと同名のJavaクラスが存在する場合、Javaクラスが優先されます。 この場合、UtilityClassを登録しても利用できないのでUtilityClass名は注意してください。

9. Preference

Preferenceはテナント単位で設定を保存する機能です。 Name-Valueのペアで値を保持します。

service-configとカスタムServiceを利用した設定の管理と比較すると、(他のテナントを含めた)Webアプリケーション全体に反映されるservice-configに対して、テナント内部の設定値として管理するため、設定変更による影響範囲は小さくなります。 また、Preferenceは稼働中のWebアプリケーション上で設定を行うためすぐに反映されますが、反映にアプリケーションサーバの再起動が必要になる点がservice-configと異なります。

どちらの機能を利用するかは、開発するアプリケーションの特性に合わせて使い分けてください。

9.1. Preference定義

Preference定義の作成

Preferenceアイコンを右クリックして「Preferenceを作成する」を選択してください。

Preferenceの設定項目

固有設定

Preferenceを作成すると、Preference Attribute内に同名のルートノードが作成されます。 ノードをクリックすると編集可能な状態になり、Value等を設定できるようになります。

子ノードの追加

ノードには子ノードを追加することができます。 追加したいノードに対して右クリックし、「Add Preference」をクリックすることで子ノードが追加(複数可)されます。 子ノードの追加はルートノード以外でも可能で、階層構造を使って設定を管理することができます。 なお、子ノードを持つノードはアイコンがフォルダに変更されます。

Preference Setting Array
Runtimeクラスの利用

Preferenceに対応するPOJO、もしくはPreferenceAwareの実装クラスを作成し、ノードの「Runtime Class Name」に指定することで、任意のオブジェクトで設定値の管理ができるようになります。

9.2. 利用方法

PreferenceはPreferenceManagerを利用して取得します。

import org.iplass.mtp.prefs.PreferenceManager;
import org.iplass.mtp.prefs.Preference;

PreferenceManager manager = ManagerLocator.manager(PreferenceManager.class);
Preference pref = manager.get("sample/pref"); (1)
String value = pref.getValue(); (2)
1 PreferenceManagerのgetメソッドを利用してPreferenceを取得。
2 ノードのValueはPreferenceオブジェクトのgetValue()で取得可能
PreferenceSet

フォルダのアイコンになっている、子ノードを持つノードはPreferenceのサブクラスのPreferenceSetとなります。 PreferenceSetは子ノードをSubSetとして保持しています。

PreferenceManager manager = ManagerLocator.manager(PreferenceManager.class);
PreferenceSet prefSet = (PreferenceSet) manager.get("sample/array");
String value = prefSet.getValue(); (1)
for (Preference sub : prefSet.getSubSet()) { (2)
    String subValue = sub.getValue();
}
prefSet.getSubSet("name1")[0].getValue();(3)
1 PreferenceSet自体にも値は保持可能
2 getSubSet()で子ノードをまとめてList<Preference>として取得可能
3 subPathを指定することで任意のnameを配列で取得可能、「/」で区切ることで階層にも対応できる
RuntimeClass

Runtime Classを利用する際は以下のようになります。

import sample.SamplePreference;
import sample.SampleSubPrefrerence;

PreferenceManager manager = ManagerLocator.manager(PreferenceManager.class);
SamplePreference pref = manager.getRuntime("sample/runtimeclass"); (1)
String value = pref.getName(); (2)
SampleSubPrefrerence sub = pref.getSubPref(); (3)
String subValue = sub.getSubValue();
1 POJOとして取得する際にはgetRuntimeメソッドを利用
2 PreferenceのNameに対応するフィールドとgetter/setterでValueを取得
3 子ノードにもRuntime Class Nameを指定していればPOJOとして取得可能

10. 非同期処理(AsyncCommand)

AsyncCommandは、カスタムで作成したCommandを非同期で実行するためのメタデータです。

10.1. AsyncCommand定義(AdminConsole)

AsyncCommandの作成

AsyncCommandアイコンを右クリックして「非同期コマンドを作成する」を選択してください。

AsyncCommandの設定項目

固有設定
項目 内容

Exception Handling Mode

非同期タスクの処理中に例外が発生した場合の挙動を指定するモードです。以下の3つから選択します。

RESTART

非同期コマンドの処理をロールバックした後に再実行します。

ABORT

非同期コマンドの処理を中断します。

ABORT_LOG_FATAL

非同期コマンドの処理を中断し、FATALとしてログ出力します。

Queue Name

非同期実行する際のキューを指定します。未指定の場合はデフォルトキューを利用します。

GropuingKey Attribute Name

非同期処理実行時のgroupingKeyを利用する場合の、attribute名です。
グループキーを設定すると、そのグループのタスクは必ず同一のタスク実行Workerで実行されます。前後関係のある処理の場合に設定して下さい。
尚、タスクIDのカウンターにキャッシュを利用している場合、同一のタスク実行Worker内での順序が保障されなくなりますのでご注意ください。

Execute Commands

非同期実行するコマンドを選択します。
設定方法はActionと同様です。「Commandの設定」の章を参照下さい。

10.2. 利用方法

RdbQueueServiceの設定

非同期実行は、Queueを利用して管理します。 このため、service-configにてRdbQueueServiceのuseQueueをtrueにする必要あります。
詳細はRdbQueueServiceを参照してください。

AsyncCommandの実行

非同期コマンドは呼び出し元コマンドのロジック内からCommandInvokerを利用して実行します。

サンプル(非同期処理呼び出しコマンド)
import org.iplass.mtp.ManagerLocator;
import org.iplass.mtp.command.CommandInvoker;
import org.iplass.mtp.command.async.AsyncRequestContext;

:

public class SampleCommand implements Command {

    @Override
    public String execute(RequestContext request) {

        // 非同期処理コマンドのリクエスト設定
        AsyncRequestContext asyncRequest = new AsyncRequestContext(); (1)
        asyncRequest.setAttribute("key", "value");

        // 処理非同期処理呼び出し
        CommandInvoker invoker = ManagerLocator.manager(CommandInvoker.class);
        long taskId = invoker.executeAsync("TutorialAsync", asyncRequest); (2)

        return "OK";
    }
}
1 AsyncRequestContextは実行する際Serializeされ、一度DBに格納されます。 このためセットする属性は、 Serializable を実装している必要があります。
また大きなオブジェクトを渡す場合は、Entityなどの形で保存して、AsyncRequestContextへは そのキーであるoidを渡すようにしてください。
2 実行するとタスクIDが返ります。別途実行状態を確認する際に利用します。

実行状態の確認

AdminConsoleのToolsに用意されているQueueExplorerを利用して、Queue毎に積まれているタスクの一覧表示や、 過去の実行履歴、未完了のタスクのキャンセルといった操作が可能です。
詳細はQueueExplorer の説明を参照ください。

10.3. AsyncCommand定義(アノテーション)

JavaにてCommandを実装する場合、クラス自体にアノテーションでAsyncCommand定義を設定することが可能です。 単一のCommandに複数のAsyncCommandをアノテーションすることも可能です。

アノテーションで定義されたAsyncCommand定義はすべてのテナントで有効化されます。

AsyncCommand定義を行うためのアノテーションは @AsyncCommand です。設定可能な要素はAdminConsoleでの設定項目に準じます。 詳細はjavadocを参照ください。

Commandクラス以外のクラス、インタフェースに対して@AsyncCommand定義することも可能です。ただし、この場合command属性もしくはcompositeCommand属性にてcommandClassを明示的に指定する必要があります。
アノテーションによる定義のサンプル
import org.iplass.mtp.command.annotation.async.AsyncCommand;
:

@AsyncCommand(name="tutorial",
    displayName="非同期Commandサンプル",
    exceptionHandlingMode = ExceptionHandlingMode.ABORT_LOG_FATAL
)
@CommandClass(name="tutorial")
public class TutorialCommand implements Command {
    @Override
    public String execute(RequestContext request) {

        // 処理

        if ( ... ) {
            return "NG";
        } else {
            return "OK";
        }
    }
}

11. Static Resource

画面で利用する各種リソースファイルを管理します。 画像やテキストなどの様々な形式のリソースや、リソースファイルを格納したZip及びJar形式の圧縮ファイルなどを扱えます。 作成したStaticResourceはTemplateのようにActionの結果として利用できます。

11.1. StaticResource定義

StaticResourceの作成

メニューを右クリックし「静的リソースを作成する」を選択します。

StaticResourceの設定項目

固有設定
項目 内容

Content Type

リソースのコンテキストタイプを設定します。 (例:text/html; charset=utf-8) ファイルが選択されている時に未設定の場合、保存後に自動的に設定されます。

File TypeがSimpleの場合

レスポンスの Content-Type に設定されます。

File Type

リソースファイルのタイプを指定します。

Archive

Zip及びJar形式の圧縮ファイルの場合に指定します。

Simple

単一のリソースファイルの場合に指定します。

ファイルが選択されていない場合は変更できません。

File

File Typeで指定したリソースファイルを設定します。 リソースファイルを変更する必要がない場合は選択する必要はありません。 未指定の場合は、既に登録済のリソースファイルが利用されます。

Entry Text Charset

File TypeがArchiveの場合

リソースのMIMEタイプがテキストの時に文字セット(Charset)を指定する場合に設定します。

Entry Path Translator

File TypeがArchiveの場合

コマンドで指定されたEntry Pathに対し変換処理が必要な場合に設定します。 変換処理の方式を以下のタイプから選択します。

Java

変換処理が実装されたJavaクラスの完全修飾名を設定します。 Javaクラスは org.iplass.mtp.web.staticresource.EntryPathTranslator インターフェースを実装する必要があります。

Prefix

Entry Pathに付与されるプレフィックスの文字列を設定します。

Script

変換処理をスクリプトにより実装します。

MimeType Mappings

File TypeがArchiveの場合

レスポンスに設定するMIMEタイプを、読み込むリソースの拡張子から判断するための設定を行います。 設定がない場合は、リソースに応じたデフォルトのMIMEタイプが使用されます。 MIMEタイプが不明な場合は、 application/octet-stream となります。
MIMEタイプ設定を参照してください。

MIMEタイプ設定

File TypeがArchiveの場合に、呼び出すリソースの拡張子からレスポンスに設定するMIMEタイプを指定します。

項目 内容

Extension

拡張子を設定します。

MIME Type

MIMEタイプを設定します。

多言語設定

言語毎にリソースを異なるものに設定することが可能です。

項目 内容

Language

言語設定を行います。

そのほかの項目

File TypeとFileを設定します。

11.2. 利用方法

StaticResourceを利用するには、Action定義のResult設定でStaticResourceタイプを選択します。
Resultの設定方法については、Result: StaticResourceを参照してください。

12. カスタムService

設定ファイル(service-config)にはiPLAssが提供する各種Serviceクラスの定義が記述されています。 ここに独自のカスタムServiceを作成し、定義することが可能です。

設定ファイル(service-config)の書式の詳細は、 service-configファイルについて を参照ください。

12.1. カスタムServiceの作成

org.iplass.mtp.spi.Service を実装したJavaクラスを作成します。

カスタムServiceの実装例
package sample;

import org.iplass.mtp.spi.Config;
import org.iplass.mtp.spi.Service;

public class SampleService implements Service {
    private String strValue;
    private int intValue;
    private SampleBean sample;
    private List<SampleBean> arrays;

    @Override
    public void init(Config config) {
        //Serviceの初期化処理を記述
        strValue = config.getValue("strValue");
        intValue = config.getValue("intValue", Integer.TYPE, 10); (1)
        sample = config.getValue("sample", SampleBean.class); (2)
        arrays = config.getValues("arrays", SampleBean.class); (3)
    }

    @Override
    public void destroy() {
        //Serviceの破棄処理を記述
    }

    //...以下serviceに必要なメソッド、処理を記述
}
1 設定ファイルに設定されていなかった場合のデフォルト値を指定可能です
2 javaBean形式のクラスを指定可能です
3 同一名称の複数の設定項目の定義も可能です。
カスタムServiceで利用するBean定義例
public class SampleBean {
    private String name;
    private NestedBean nest;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public NestedBean getNest() {
        return nest;
    }
    public void setNest(NestedBean nest) {
        this.nest = nest;
    }
}

:

public class NestedBean {
    private int age;
    private String name;

    public NestedBean(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

:

public class ExSampleBean extends SampleBean {
    private String extraVal;

    public String getExtraVal() {
        return extraVal;
    }
    public void setExtraVal(String extraVal) {
        this.extraVal = extraVal;
    }
}

上記のカスタムServiceに対応するservice-configの定義は例えば、以下のように行うことが可能です。

service-configでの設定例
:

<service>
    <interface>sample.SampleService</interface>

    <property name="strValue" value="iPLAss" />
    <property name="intValue" value="10000" />

    <property name="sample"> (1)
        <property name="name" value="abc" />
        <property name="nest">
            <arg name="arg0" value="30" /> (2)
            <property name="name" value="fuga" />
        </property>
    </property>

    <property name="arrays"> (3)
        <property name="name" value="yy" />
    </property>
    <property name="arrays" class="sample.ExSampleBean"> (4)
        <property name="name" value="zz" />
        <property name="extraVal" value="ex" />
    </property>
</service>
1 Beanのプロパティは<property>をネストして定義することで設定します
2 <arg>指定でコンストラクタインジェクションが可能です
3 同一名の<property>を定義することで、List/配列のプロパティの設定が可能です
4 class属性で明示的に生成するクラスを指定可能です

Serviceのinitの実装では、Serviceの初期化処理を記述します。 service-configで設定された内容を保持した org.iplass.mtp.spi.Config のインスタンスが引数として渡されます。

インタフェースと実装の分離

Serviceのインタフェースと実装クラスを別に実装し、定義することが可能です。

インタフェースと実装を分離したカスタムService
package sample;

import org.iplass.mtp.spi.Config;
import org.iplass.mtp.spi.Service;

public interface SampleService extends Service {

    public boolean someMethod();

}

public class SampleServiceA implements SampleService {

    @Override
    public boolean someMethod() {
        //SampleServiceAでのsomeMethodの実装
        :
    }

    @Override
    public void init(Config config) {
        //Serviceの初期化処理を記述
        :
    }

    @Override
    public void destroy() {
        //Serviceの破棄処理を記述
    }

}

public class SampleServiceB implements SampleService {

    @Override
    public boolean someMethod() {
        //SampleServiceBでのsomeMethodの実装
        :
    }

    @Override
    public void init(Config config) {
        //Serviceの初期化処理を記述
        :
    }

    @Override
    public void destroy() {
        //Serviceの破棄処理を記述
    }

}

上記の実装がある場合、service-configにて実装の切り替えが可能です。

service-configでの設定例
:

<service>
    <interface>sample.SampleService</interface>
    <class>sample.SampleServiceB</class> (1)

    <property name="strValue" value="iPLAss" />
    :

</service>
1 <class>にて実装クラスを指定することが可能です。

依存Serviceの定義

Serviceが依存する別Serviceをservice-configに定義しておくことで、当該Serviceの初期化時に依存するServiceが事前に初期化されていることを保障することが可能です。

依存Serviceの定義例
:

<service>
    <interface>sample.SampleService</interface>
    <depend>org.iplass.mtp.impl.cache.CacheService</depend> (1)

    <property name="strValue" value="iPLAss" />

    :

</service>
1 <depend>で依存するサービスのサービス名(もしくはインタフェース名)を指定します
Serviceのinitにおける依存Serviceの取得例
package sample;

import org.iplass.mtp.spi.Config;
import org.iplass.mtp.spi.Service;

public class SampleService implements Service {
    private String strValue;

    private CacheService cacheService;

    @Override
    public void init(Config config) {
        cacheService = config.getDependentService(CacheService.class);

        :
        :

    }

}

ServiceInitListener

カスタムServiceに定義されるBeanにおいて、Serviceのライフサイクルに応じて初期化処理、破棄処理を行いたい場合、 org.iplass.mtp.spi.ServiceInitListener を実装します。

ServiceInitListenerを実装するBean
import org.iplass.mtp.spi.ServiceInitListener;
:

public class SampleBean implements ServiceInitListener<SampleService.class> {
    private String name;
    private NestedBean nest;

    @Override
    public void inited(SampleService service, Config config) {
        //SampleServiceの初期化時に呼び出される
        :

    }

    @Override
    public void destroyed() {
        //SampleServiceの破棄時に呼び出される
        :

    }

    :

}

12.2. Serviceの利用

Serviceのインスタンスは以下のように取得し、利用します。

import org.iplass.mtp.spi.ServiceRegistry;

SampleService service = ServiceRegistry.getRegistry().getService(SampleService.class);

service.someServiceMethod();
:

Serviceのインスタンスは、service-configに記述されている数だけが生成され、共有されます。 service名を個別に定義することにより、同一のServiceクラスを複数インスタンス定義することも可能です。

service名を利用した設定
:

<service name="service1">
    <interface>sample.SampleService</interface>

    <property name="strValue" value="iPLAss" />
    <property name="intValue" value="10000" />

    :

</service>

<service name="service2">
    <interface>sample.SampleService</interface>

    <property name="strValue" value="mtp" />
    <property name="intValue" value="500" />

    :

</service>
service名を指定したServiceの取得
import org.iplass.mtp.spi.ServiceRegistry;

//下記、service1とservice2は別インスタンス

SampleService service1 = (SampleService) ServiceRegistry.getRegistry().getService("service1");

SampleService service2 = (SampleService) ServiceRegistry.getRegistry().getService("service2");

:

13. EntryPoint

EntryPointを利用することで、Servletコンテナ外のコード上から直接iPLAssの初期化や破棄、また特定のテナントやユーザーを指定して処理を実行させることが可能です。 例えばバッチ処理やSpring等iPLAss以外のアプリケーション内のコードからiPLAssの処理を実行可能です。

EntryPointは当該クラスがロードされるクラスローダ単位に一つのみ存在可能です。

13.1. EntryPointの利用例

EntryPointを用いたバッチ処理の実装例です。

EntryPointBatchSample.java
import org.iplass.mtp.runtime.EntryPoint;
import org.iplass.mtp.auth.login.IdPasswordCredential;
  :
  :

public class EntryPointBatchSample {
    public static void main(String[] args) throws Exception {

        // テナントID
        int tenantId = 1;
        // 認証情報
        String id = "XXXXX";
        String password = "XXXXXXXXXX";
        Credential credential = new IdPasswordCredential(id, password);

        // EntryPointの初期化
        EntryPoint entryPoint = EntryPoint.builder()
                .config("/mtp-service-config.xml") (1)
                .build();

        // バッチ処理の実行
        entryPoint.withTenant(tenantId).withLang("en").withAuth(credential).run(() -> { (2)
            // バッチの処理を記述
            :

        });

        // EntryPointの破棄
        entryPoint.destroy(); (3)
    }
}
1 設定ファイル(service-config.xml)のパスを指定します。 未指定の場合のデフォルト値は、/mtp-service-config.xml です。
2 必要な情報を設定して処理を実行します。実装例では、テナントID、言語、認証情報をセットしています。
3 バッチ終了時にEntryPointを破棄し、リソースを解放します。

13.2. 設定ファイル

バッチの動作に必要な設定を、指定したファイルへ定義しておく必要があります。
設定の詳細については、設定(service-config)リファレンスを参照してください。

14. JSPカスタムタグ・EL関数

iPLAssが提供するJSPで利用可能なカスタムタグ・EL関数の説明です。 次の宣言により利用可能となります。

<%@taglib prefix="m" uri="http://iplass.org/tags/mtp"%>

14.1. <auth>

認可情報に従って制御を行うためのJSPタグです。 特定ロールの場合のみボディコンテンツを表示したり、ボディコンテンツの処理を特権実行するなどの制御が可能です。

利用例
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="m" uri="http://iplass.org/tags/mtp"%>

:

<m:auth role="roleA,roleB"> (1)
  this content only show with role:"roleA" or "roleB".
  :
  :
</m:auth>


<m:auth permission="<%=new ActionPermission("some/actionX", new MapActionParameter().put("defName","Hoge"))%>"> (2)
  this content only show with action permission:"some/actionX?defName=Hoge".
  :
  :
</m:auth>


<m:auth privileged="true"> (3)
  privileged contents.

  <%
    //some privileged execution
    :
    :

  %>

</m:auth>
1 roleAまたはroleBの場合のみボディコンテンツを表示します
2 some/actionXアクションのAction権限を保持する場合ボディコンテンツを表示します
3 ボディコンテンツの処理を特権実行します

指定可能な属性の説明

属性名 Script可 デフォルト値 説明

role

*

ロール名指定します。
当該ロールを保持する場合、ボディコンテンツが出力されます。 複数のロール名をカンマ区切りで指定することが可能です。 複数指定された場合、いずれかのロールを保持する場合にボディコンテンツが出力されます。

permission

*

Permissionのインスタンスを指定します。
当該権限を保持する場合、ボディコンテンツが出力されます。

privileged

*

false

trueが指定された場合、ボディコンテンツの出力処理を特権実行します。

14.2. <bind>

Commandの処理結果(Beanに格納されている値、関連するエラー)を画面に表示するためにpageContextにバインドするJSPタグです。 errorsタグをbindタグと組み合わせて利用することにより、紐付くプロパティ単位にエラーメッセージの出力制御が可能です。

利用例
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="m" uri="http://iplass.org/tags/mtp"%>

:

<form>
  <m:bind bean="${formBean}"> (1)

    <m:bind prop="userName"> (2)
      user name : <input type="text" value="${value}" name="${name}"> (3)
      <m:errors /> (4)
    </m:bind>

    :

    <m:bind prop="mailAddress">
      mail address : <input type="text" value="${value}" name="${name}"> <m:errors />
    </m:bind>

  :

  </m:bind>
</form>
1 formBeanという名前で参照(RequestやSessionから)されるBeanをバインドします。
2 formBeanのプロパティuserNameをバインドします。
3 bindタグ内では${value}、${name}でformに指定すべきvalue、nameが取得できます。
4 BeanParamMapperでの当該プロパティのマッピングエラー、バリデーションエラーを表示可能です。

指定可能な属性の説明

属性名 Script可 デフォルト値 説明

bean

*

バインドするBeanのインスタンスを指定します。

バインドされたBeanは、 bean という変数名でpageContextに公開されます。 公開する際の変数名を変更したい場合は、beanVariableNameにて変数名を変更可能です。

beanVariableName

bean

バインドされたBeanをpageContextに公開する際の変数名を指定可能です。

mappingResult

*

BeanParamMapperでのバインド結果である org.iplass.mtp.command.beanmapper.MappingResult のインスタンスを指定可能です。

mappingResultが指定された場合、当該Bean、プロパティに紐付くエラーがバインドされます。 当該属性が未指定の場合、かつautoDetectErrorsがtrueの場合、mappingResultは自動解決されます。 バインドされたMappingResultは mappingResult という変数名でpageContextに公開されます。 公開する際の変数名を変更したい場合は、mappingResultVariableNameにて変数名を変更可能です。

autoDetectErrors

true

エラー(mappingResult)を自動解決するか否かを指定可能です。

trueが指定された場合、requestから定数: org.iplass.mtp.web.WebRequestConstants.EXCEPTION をキーに org.iplass.mtp.command.beanmapper.MappingException のインスタンスを取得します。 インスタンスが存在した場合、その例外からMappingResultのインスタンスを取得します。

mappingResultVariableName

mappingResult

バインドされたMappingResultをpageContextに公開する際の変数名を指定可能です。

prop

*

バインドされているBeanのプロパティのパスを指定します。 EL式の記法によって、ネストされたプロパティを指定可能です。

EL式での指定例
userName
accout.mail
details[0].id

当該パスが指定されたbindタグの内側ではpageContextにプロパティ名、値、当該プロパティに関連するエラーがバインドされます。 pageContextに公開される際の変数名は、デフォルトでは以下の名前で公開されます。

name

HTTPのパラメータ名として利用可能な形のプロパティのパスです。BeanParamMapperのパラメータ名と同様の形式です。

value

プロパティの値の文字列表現です。文字列表現はhtmlEscape、formatter設定にて制御可能です。

rawValue

生のプロパティの値です。

errorValue

エラーが発生場合の生のプロパティの値です。

errors

当該プロパティに関するエラーが存在する場合、エラーメッセージの List<String> のインスタンスです。

公開する際の変数名を変更したい場合はそれぞれ、propertyNameVariableName、propertyValueVariableName、 propertyRawValueVariableName、errorsVariableNameにて変数名を変更可能です。

また、propには、scriptでの指定が可能なので、Bean内にネストされたリストをバインドしたい場合、例えば次のような記述が可能です。

JSTLのforEachを利用する例
<m:bind bean="${fb}">

  :

  <c:forEach var="item" items="${fb.children}" varStatus="stat">
    ${stat.index}.
    <m:bind prop="children[${stat.index}].name">
      child name : <input type="text" value="${value}" name="${name}">
      <m:errors />
    </m:bind>
  </c:forEach>

</m:bind>

prop指定と同時にbeanが指定された場合は、そのbeanのプロパティをバインドします。 beanが未指定の場合は、親タグに指定されるbeanのプロパティをバインドします。

htmlEscape

true

value(プロパティの値の文字列表現)を出力する際にhtmlエスケープ処理をするか否かを指定可能です。

このフラグによってエスケープ処理されるのはvalueのみです。name、rawValue、errorValue、errorsの値はエスケープされません。

formatter

*

DEFAULT_FORMATTER

value(プロパティの値の文字列表現)を出力する際のフォーマット処理を行う org.iplass.mtp.web.template.ValueFormatter のインスタンスを指定します。

未指定の場合は、 ValueFormatter.DEFAULT_FORMATTER で指定されるデフォルトの処理が適用されます。 デフォルト処理では値が文字列以外の場合に次のようにフォーマットします。

Integer、Double、BigDecimalなどの数値型

数値を10進数表現で文字列に変換します。

SelectValue型

SelectValueのvalueを出力します。

BinaryReference型

BinaryReferenceのlobIdを出力します。

Date型

yyyy-MM-dd形式で出力します。

Time型

HH:mm:ss形式で出力します。

Timestamp型もしくは、java.sql.Date、java.sql.Time以外のjava.utilDate型

yyyy-MM-dd’T’HH:mm:ss.SSSXXX形式で出力します。

beanが指定されているbindタグに指定した場合、配下のプロパティの値に一律適用されます。

formatterを利用せず個別にrawValueからフォーマットすることも可能です。

rawValueから直接出力する例
<m:bind prop="dateProp">
  <input type="text" value="${m:esc(m:nvl(errorValue, m:fmt(rawValue, 'yyyy/MM/dd')))}" name="${name}">
</m:bind>

propertyNameVariableName

name

バインドされたプロパティのHTTPパラメータ名をpageContextに公開する際の変数名を指定可能です。

propertyValueVariableName

value

バインドされたプロパティの値の文字列表現をpageContextに公開する際の変数名を指定可能です。

propertyRawValueVariableName

rawValue

バインドされたプロパティの生の値をpageContextに公開する際の変数名を指定可能です。

propertyErrorValueVariableName

errorValue

バインドされたプロパティがエラーの場合、そのエラー値が格納される変数名を指定可能です。

errorsVariableName

errors

バインドされたプロパティに関連するエラーメッセージの List<String> をpageContextに公開する際の変数名を指定可能です。

prefix

name(HTTPパラメータ名)を出力する際のprefixを指定します。

HTTPリクエストをBeanParamMapperでマッピングする場合、BeanParamMapperのparamPrefixの値と一致させる必要があります。

propertyDelimiter

.

name(HTTPパラメータ名)を出力する際のネストされたプロパティのデリミタを指定します。

HTTPリクエストをBeanParamMapperでマッピングする場合、BeanParamMapperのpropertyDelimiterの値と一致させる必要があります。

indexPrefix

[

name(HTTPパラメータ名)を出力する際のインデックス指定のプレフィックス文字を指定します。

HTTPリクエストをBeanParamMapperでマッピングする場合、BeanParamMapperのindexPrefixの値と一致させる必要があります。

indexPostfix

]

name(HTTPパラメータ名)を出力する際のインデックス指定のポストフィックス文字を指定します。

HTTPリクエストをBeanParamMapperでマッピングする場合、BeanParamMapperのindexPostfixの値と一致させる必要があります。

14.3. <errors>

エラーが存在する場合、エラー内容をフォーマットしてhtml出力するJSPタグです。 errorsタグが記述される場所、設定される属性値により、出力される内容が異なります。

  • bindタグ配下、かつprop指定がある場合

    当該プロパティに紐付くエラーがある場合、エラーを出力します。

    利用例
    <m:bind bean="${formBean}">
      :
    
      <m:bind prop="userName">
        user name : <input type="text" value="${value}" name="${name}">
        <m:errors /> (1)
      </m:bind>
      :
    
    </m:bind>
    1 formBeanのuserNameに紐付くエラーがある場合にエラー内容が出力されます。
  • bindタグ配下、かつprop指定がない場合

    当該Beanに紐付くエラーがある場合、そのすべてのエラーを出力します。

    利用例
    <m:bind bean="${formBean}">
      <m:errors /> (1)
      :
    
      <m:bind prop="userName">
        user name : <input type="text" value="${value}" name="${name}">
      </m:bind>
      :
    
    </m:bind>
    1 formBeanに紐付くすべてのエラー内容が出力されます。
  • bindタグ配下ではない場合

    requestから定数: org.iplass.mtp.web.WebRequestConstants.EXCEPTION をキーに例外を取得しそのメッセージを出力します。

    当該Exceptionが org.iplass.mtp.command.beanmapper.MappingException の場合

    その例外に保持されるMappingResultのメッセージを出力します。

    当該Exceptionが org.iplass.mtp.ApplicationException の場合

    その例外のメッセージを出力します。

    当該Exceptionがそれ以外の場合

    固定のシステム例外メッセージを出力します。

  • タグ属性にて明示的にerrorsを指定した場合

    指定されたインスタンスにより適切にメッセージ出力します。 出力内容については属性の説明:errorsを参照してください。

指定可能な属性の説明

属性名 Script可 デフォルト値 説明

errors

*

出力するエラー対象を指定します。 指定されたエラー対象により適切にエラーメッセージ出力します。

String の場合

指定されたStringを出力します。

org.iplass.mtp.command.beanmapper.MappingError の場合

指定されたMappingErrorのerrorMessagesを出力します。

org.iplass.mtp.command.beanmapper.MappingResult の場合

指定されたMappingResultが保持するMappingErrorのerrorMessagesを出力します。

org.iplass.mtp.command.beanmapper.MappingException の場合

指定されたMappingExceptionのMappingResultの内容を出力します。

org.iplass.mtp.ApplicationException の場合

指定されたApplicationExceptionのmessageを出力します。

Throwable の場合

固定のシステム例外メッセージを出力します。

List<String>、配列の場合

指定されたリスト、配列の内容を1件ずつ出力します。

それ以外の場合

指定されたインスタンスのtoString()を出力します。

delimiter

<br>

エラーメッセージが複数ある場合のデリミタを指定可能です。

header

<span class=\"error\">

エラーメッセージを出力する際、先頭に出力する内容を指定可能です。

footer

</span>

エラーメッセージを出力する際、最後に出力する内容を指定可能です。

htmlEscape

true

エラーメッセージを出力する際にhtmlエスケープ処理をするか否かを指定可能です。

errorsVariableName

errors

エラーをpageContextに公開する際の変数名を指定可能です。 また、この変数名は親のbindタグでpageContextに公開されたエラーを探す場合の変数名としても利用されます。

メッセージ出力内容をカスタムする

タグ内のBODYにJSPコードを記述することにより、エラーメッセージ出力内容をカスタマイズすることが可能です。

カスタマイズ例
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="m" uri="http://iplass.org/tags/mtp"%>

:

<m:errors>
  <span>
  <b>エラーが発生しました</b><br>
  エラー内容:${errors}
  </span>
</m:errors>

カスタマイズ出力する場合は、delimiter、header、footer、htmlEscapeの設定は利用されません。

14.4. <include>

JSP内に別Action、Templateの出力を取り込むためのJSPタグです。

利用例(Actionをinclude)
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="m" uri="http://iplass.org/tags/mtp"%>

:

<m:include action="your/action/path" />
利用例(Templateをinclude)
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="m" uri="http://iplass.org/tags/mtp"%>

:

<m:include template="your/template/path" />

指定可能な属性の説明

属性名 Script可 デフォルト値 説明

action

*

includeするActionの名前を指定します。 actionもしくは、templateのいずれかの指定が必要です。

template

*

includeするTemplateの名前を指定します。 actionもしくは、templateのいずれかの指定が必要です。

14.5. <renderContent>

LayoutアクションのJSPにおいて、実際のコンテンツを表示する箇所を指定するJSPタグです。

利用例
<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@taglib prefix="m" uri="http://iplass.org/tags/mtp"%>

:

<div id="main">
  <!-- ここにメインコンテンツが出力される -->
  <m:renderContent />
</div>

14.6. esc()

引数のStringをHTML出力用にエスケープします。

利用例
${m:esc(bean.user.name)}

引数

説明

String

HTMLエスケープしたいStringを指定します。

戻り値

エスケープ処理されたString。

14.7. escJs()

引数のStringをJavaScript出力用にエスケープします。

利用例
${m:escJs(bean.user.name)}

引数

説明

String

JavaScriptエスケープしたいStringを指定します。

戻り値

エスケープ処理されたString。

14.8. escXml()

引数のStringをXML(XHTML)出力用にエスケープします。

利用例
${m:escXml(bean.user.name)}

引数

説明

String

XMLエスケープしたいStringを指定します。

戻り値

エスケープ処理されたString。

14.9. token()

トランザクショントークンの値を出力します。

利用例
<input type="hidden" name="_t" value="${m:token()}">

引数

なし

戻り値

新規に発行されたトークン文字列。

14.10. fixToken()

固定トークン(セッション単位の固定値)の値を出力します。 CSRF(XSRF)対策用に利用可能です。

利用例
<input type="hidden" name="_t" value="${m:fixToken()}">

引数

なし

戻り値

セッション単位に固定のトークン文字列。

14.11. fmt()

指定の第一引数の値を第二引数で指定されるパターンでフォーマット出力します。

利用例
<input type="text" name="endDate" value="${m:fmt(dateVal, 'yyyy/MM/dd')}">

引数

説明

Object

フォーマット対象の値には、Dateのインスタンスもしくは、Numberのインスタンスを指定可能です。

String

値がDate型の場合は、SimpleDateFormatにて定義されるpattern、 Number型の場合は、DecimalFormatにて定義されるpatternを指定可能です。

戻り値

フォーマットされたString。

14.12. msg()

Message定義(メタデータ)として登録されているメッセージを出力します。

利用例
${m:msg('path/to/MessageCategory', 'M101')}

引数

説明

String

Message定義の名前(カテゴリ名)を指定します。

String

Message定義のメッセージのID指定します。

戻り値

当該カテゴリ、IDで特定されるメッセージ文言。

14.13. msgp()

Message定義(メタデータ)として登録されているメッセージを、指定のパラメータを埋め込み出力します。

利用例
${m:msgp('path/to/MessageCategory', 'M102', bean.messageParams)}

引数

説明

String

Message定義の名前(カテゴリ名)を指定します。

String

Message定義のメッセージのID指定します。

Object

メッセージに埋め込むパラメータ(単一のオブジェクト、もしくは配列、もしくはCollectionのインスタンス)を指定可能です。

戻り値

当該カテゴリ、IDで特定されるメッセージ文言パラメータ埋め込みした文字列。

14.14. nvl()

第一引数がnullであった場合、第二引数を返却します。

利用例
${m:nvl(testVal, 'testVal is null')}

引数

説明

Object

nullではなかった場合、この値が返却されます。

Object

第一引数がnullであった場合のデフォルト値を指定します。

戻り値

第一引数がnullであった場合、第二引数を返却。

14.15. prefs()

Preference定義の値を取得します。

利用例
${m:prefs('path/to/preferenceName')}

引数

説明

String

Preferenceを特定する名前を指定します。

戻り値

PreferenceにruntimeClassが指定されている場合は、そのクラスのインスタンスが取得されます。
runtimeClass指定がない場合、かつPreferenceSetの場合は、Mapが取得されます。
Preferenceの場合は、valueに定義されているStringが取得されます。

14.16. rc()

RequestContextのインスタンスを取得します。

JSPの暗黙変数 request から透過的にRequestContextの値を取得可能です。 この関数は、明示的にRequestContextのインスタンスを取得したい場合に利用可能です。
利用例
${m:rc().session.getAttribute('cart').count}

引数

なし

戻り値

org.iplass.mtp.command.RequestContext のインスタンス

14.17. rs()

指定された基底名、キーからResourceBundleに定義された文字列を返します。

利用例
${m:rs('resource-bundle-name', 'key')}

引数

説明

String

ResourceBundleの基底名(bundle name)を指定します。

String

ResourceBundleのキー名を指定します。

戻り値

ResourceBundleに定義された文字列。

14.18. rsp()

指定された基底名、キーからResourceBundleに定義された文字列を返します。 第三引数には、文字列に埋め込むパラメータを指定可能です。

利用例
${m:rsp('resource-bundle-name', 'key2', params)}

引数

説明

String

ResourceBundleの基底名(bundle name)を指定します。

String

ResourceBundleのキー名を指定します。

Object

メッセージに埋め込むパラメータ(単一のオブジェクト、もしくは配列、もしくはCollectionのインスタンス)を指定可能です。

戻り値

ResourceBundleに定義された文字列にパラメータ埋め込みした文字列。

14.19. tcPath()

テナントコンテキストパスを出力します。 テナントコンテキストパスは ServletContextPath + tenantURL で定義される、 APサーバ上でテナントまでを特定するルート相対パスです。

利用例
<a href="${m:tcPath()}/path/to/action">link</a>

引数

なし

戻り値

テナントコンテキストパス

15. Groovy Script

GroovyはApache Software Foundationが提供するJavaVM上で動作する動的言語です。 Java言語と同様の構文で記述することも可能で、Javaで作成されたクラスを呼び出すことも可能です。

Groovy言語の仕様については次のサイトを参照ください。

Groovyは、Java言語と異なり、クラスを定義せずともコードをScript形式で記述することが可能です。
iPLAssではメタデータ上に定義するカスタムコードをGroovy Script形式で記述可能な箇所があります。

15.1. Groovy Scriptにおける拡張

次のクラスについて、Groovy上でのコードの記述が簡便になるようにプロパティ、メソッドの拡張を行っています。

org.iplass.mtp.entity.GenericEntity

Entityのプロパティ操作を簡便化しています。
Entityにプロパティ propA を定義した場合 (GenericEntityを継承するクラスを作成し、getter/setter定義せずとも)、次のように記述可能です。

プロパティの取得

def value = entity.propA

プロパティの設定

entity.propA = 'val'

と記述可能です。

org.iplass.mtp.entity.EntityEventContext

EntityEventContext#getAttribute(String) 呼び出しを簡便化しています。

context.getAttribute('updateOption')
を、
context.updateOption
と記述可能です。

org.iplass.mtp.command.RequestContext

attributeの取得、設定を簡便化しています。

attributeの取得

request.getAttribute('beanX')
を、
request.beanX
と記述可能です。

attributeの設定

request.setAttribute('beanX', bean)
を、
request.beanX = bean
と記述可能です。

org.iplass.mtp.command.SessionContext

attributeの取得、設定を簡便化しています。

attributeの取得

session.getAttribute('beanX')
を、
session.beanX
と記述可能です。

attributeの設定

session.setAttribute('beanX', bean)
を、
session.beanX = bean
と記述可能です。

UserBinding

ログインユーザーへの参照を表すクラスです。 UserエンティティのプロパティもしくはAuthenticationProviderが提供するログインユーザーの属性を透過的にアクセス可能です。

ユーザー属性へのアクセス

user.name
user.accountId
の形式で取得可能です。

ユーティリティメソッドの提供

次のメソッドを提供します。

メソッド 戻り値 説明

isAnonymous()

boolean

ユーザーか無名ユーザー(未ログイン)か否かを返却します。

isAdmin()

boolean

adminユーザーか否かを返却します。

isLocalAdmin()

boolean

共有テナント上で、当該ユーザーが個別のテナントのadminユーザーか否かを返却します。

isOtherTenant()

boolean

共有テナント上で、当該ユーザーが個別のテナント所属か否かを返却します。

getTenantId()

int

テナントIDを返却します。

getGroupCodeWithChildren()

String[]

ユーザーが所属するGroup以下すべての階層のグループコードを返却します。

getGroupCodeWithParents()

String[]

ユーザーが所属するGroup以上の階層のグループコードを返却します。

getGroupOidWithChildren()

String[]

ユーザーが所属するGroup以下すべての階層のグループのoidを返却します。

getGroupOidWithParents()

String[]

ユーザーが所属するGroup以上の階層のグループのoidを返却します。

getGroupOid()

String[]

ユーザーが所属するGroupのoidを返却します。

memberOf(String groupCode)

boolean

ユーザーが指定のグループに所属しているか否かを返却します。サブグループに所属している場合もtrueが返却されます。

RequestContextBinding

参照専用のアクセスに限定したRequestContextのWrapperクラスです。 attribute、HTTPパラメータへのアクセスが可能です。

attributeの取得

request.attrX
のように、インスタンスのプロパティとして取得可能です。

paramの取得

request.param.paramA
のように、paramで取得されるMapインスタンス経由で取得可能です。

SessionBinding

参照専用のアクセスに限定したSessionContextのWrapperクラスです。 attributeへのアクセスが可能です。

session.attrX
のように、インスタンスのプロパティとして取得可能です。

ActionParameterBinding

参照専用のアクセスに限定したActionParameterのWrapperクラスです。

parameter.getValue('paramA')
を、
parameter.paramA
と記述可能です。

また、次のユーティリティメソッドを提供します。

メソッド 戻り値 説明

in(String name, Object…​ value)

boolean

nameで指定したActionParameterのvalueが、可変引数で指定した値のいずれかと一致した場合trueを返します。

WebApiParameterBinding

参照専用のアクセスに限定したWebApiParameterのWrapperクラスです。

parameter.getValue('paramA')
を、
parameter.paramA
と記述可能です。

また、次のユーティリティメソッドを提供します。

メソッド 戻り値 説明

in(String name, Object…​ value)

boolean

nameで指定したWebApiParameterのvalueが、可変引数で指定した値のいずれかと一致した場合trueを返します。

WorkflowParameterBinding

参照専用のアクセスに限定したWorkflowParameterのWrapperクラスです。

parameter.getValue('paramA')
を、
parameter.paramA
と記述可能です。

また、次のユーティリティメソッドを提供します。

メソッド 戻り値 説明

in(String name, Object…​ value)

boolean

nameで指定したWorkflowParameterのvalueが、可変引数で指定した値のいずれかと一致した場合trueを返します。

15.2. バインド変数

Groovy Scriptにおいて、暗黙変数(バインド変数)があり、それらは変数宣言せずとも利用可能です。 バインドされている値については、各メタデータの説明、AdminConsoleのnoteを参照ください。

16. GroovyTemplate

GroovyベースのJSPライクなテンプレート言語です。
GroovyのGStringTemplateEngineをベースに、iPLAssにて独自の機能を拡張しています。

GroovyTemplate形式は、Webページのレスポンス(Template)に利用されるだけではなく、 メールテンプレートやEQL文のテンプレートなど、メタデータ上に定義される文字列のテンプレートとして汎用的に利用されます。

GroovyTemplateの例
<%@page import="java.util.Date"%>
<%@page import="org.iplass.mtp.ApplicationException"%>
:

<!DOCTYPE html>
<html>
:

<%
if (session.info != null) {
    session.info.doSomething();

}
%>

<div>
    <nav>
        <a href="${tcPath()}/samples/home">$h{msg("samples/general", "breadcrumb.home")}</a>
        <span>$h{msg("samples/general", "samples.title")}</span>
    </nav>
</div>
<div>
    <h4>$h{msg("samples/general", "samples.title")}</h4>
    <form action="${tcPath()}/samples/doSubmit" method="post">
        <input type="hidden" name="_t" value="${token()}">
        <% bind("bean" : formBean) { %>
            <div>
                <% bind("prop" : "familyName") { %>
                <label for="${name}">Family Name</label>
                <input type="text" name="${name}" value="${value}" placeholder="Family name">
                <small class="form-text text-danger"><% errors() %></small>
                <% } %>
            </div>
            <div>
                <% bind("prop" : "firstName") { %>
                <label for="${name}">First Name</label>
                <input type="text" name="${name}" value="${value}" placeholder="First Name">
                <small class="form-text text-danger"><% errors() %></small>
                <% } %>
            </div>
            :

        <%}%>
    </form>
</div>
:

<script src="${tcPath()}/samples/resource/scripts/custom.js" type="text/javascript"></script>
:

</html>

次の書式をサポートします。

16.1. import宣言

<%@import [import target]%>
もしくは、
<%@page import="[import target]"%>

指定の[import target]をインポートします。

記述例
<%@import java.sql.Timestamp%>
<%@page import="java.sql.Timestamp"%>

16.2. Scriptlet

<% [groovy script] %>
JSPと同様、<% …​ %>内にGroovy Scriptを記述可能です。

記述例
<%
  if (a == 'OK') {
    out.println('a is OK.');
    includeTemplate('path/to/Tmpl');
  }
%>

16.3. Expression

<%= [groovy expression] %>
もしくは
${ [groovy expression] }

JSPと同様、<%= …​ %>内、${ …​ }内に値を返却する式を記述可能です。

記述例
<%=escXml('val=' + val)%>
${bean.propABC}

16.4. エスケープ処理付Expression

以下の形式でExpressionを記述することにより、出力する文字列にエスケープ処理を行うことが可能です。

Expression表現 エスケープ内容

$x{ …​ }

出力する文字はXML1.0ベースのエスケープ処理が行われます

$h{ …​ }

出力する文字はHTML4.0ベースのエスケープ処理が行われます

$j{ …​ }

出力する文字はJavaScript文字列としてのエスケープ処理が行われます

$s{ …​ }

出力する文字はEQL文字列としてのエスケープ処理('を''にエスケープ)が行われます

$sl{ …​ }

出力する文字はEQLにおけるLIKE文のワイルドカードのエスケープ処理('%_\''\%\_\\ にエスケープ)が行われます

16.5. バインド変数

各メタデータに定義するGroovyTemplateにおいて、暗黙変数(バインド変数)があり、それらは変数宣言せずとも利用可能です。
バインドされている値については、各メタデータの説明、AdminConsoleのnoteを参照ください。

17. GroovyTemplateの関数

GroovyTemplateにおいて、記述を簡便化するための関数を定義しています。 Scriptlet、Expressionにて利用可能です。

17.1. escEql()

引数の文字列をEQL出力用にエスケープします。
''' にエスケープします。また、引数がnullの場合は空文字を出力します。

利用例
user.accountId='${escEql(bean.aid)}'

引数

説明

Object

エスケープ対象を指定します。
引数がClosureの場合は、Closureの実行結果をエスケープ対象とします。
エスケープ対象がString以外の場合は、toString()された値をエスケープします。

戻り値

エスケープ処理されたString。

17.2. escEqlLike()

引数の文字列をEQLのLikeのパターン文字列用にエスケープします。
'%_\ をそれぞれ、 ''\%\_\\ とエスケープします。 また、引数がnullの場合は空文字を出力します。

利用例
user.name like '${escEqlLike(bean.userName)}%'

引数

説明

Object

エスケープ対象を指定します。
引数がClosureの場合は、Closureの実行結果をエスケープ対象とします。
エスケープ対象がString以外の場合は、toString()された値をエスケープします。

戻り値

エスケープ処理されたString。

17.3. escHtml()

引数の文字列をHTML出力用にエスケープします。

利用例
${escHtml(bean.user.name)}

引数

説明

Object

HTMLエスケープしたいObjectを指定します。
引数がClosureの場合は、Closureの実行結果をエスケープ対象とします。
エスケープ対象がString以外の場合は、toString()された値をエスケープします。

戻り値

エスケープ処理されたString。

17.4. escJs()

引数の文字列をJavaScript出力用にエスケープします。
引数がClosureの場合は、Closureの実行結果をエスケープ対象とします。
エスケープ対象がString以外の場合は、toString()された値をエスケープします。

利用例
${escJs(bean.user.name)}

引数

説明

Object

JavaScriptエスケープしたいObjectを指定します。
引数がClosureの場合は、Closureの実行結果をエスケープ対象とします。
エスケープ対象がString以外の場合は、toString()された値をエスケープします。

戻り値

エスケープ処理されたString。

17.5. escXml()

引数の文字列をXML出力用にエスケープします。

利用例
<sample val='${escXml(bean.user.name)}' />

引数

説明

Object

XMLエスケープしたいObjectを指定します。
引数がClosureの場合は、Closureの実行結果をエスケープ対象とします。
エスケープ対象がString以外の場合は、toString()された値をエスケープします。

戻り値

エスケープ処理されたString。

17.6. rs()

指定された基底名、キーからResourceBundleに定義された文字列を返します。 第三引数(可変引数)には、文字列に埋め込むパラメータを指定可能です。

利用例
${rs('resource-bundle-name', 'key1')}
${rs('resource-bundle-name', 'key2', bean.param1, bean.param2)}

引数

説明

String

ResourceBundleの基底名(bundle name)を指定します。

String

ResourceBundleのキー名を指定します。

Object…​

メッセージに埋め込むパラメータ(単一のオブジェクト、可変引数、もしくは配列、もしくはCollectionのインスタンス)を指定可能です。

戻り値

ResourceBundleに定義された文字列にパラメータ埋め込みした文字列。

17.7. fmt()

指定の第一引数の値を第二引数で指定されるパターンでフォーマット出力します。

利用例
<input type="text" name="endDate" value="${fmt(dateVal, 'yyyy/MM/dd')}">

引数

説明

Object

フォーマット対象の値には、Dateのインスタンスもしくは、Numberのインスタンスを指定可能です。

String

値がDate型の場合は、SimpleDateFormatにて定義されるpattern、 Number型の場合は、DecimalFormatにて定義されるpatternを指定可能です。

戻り値

フォーマットされたString。

17.8. msg()

Message定義(メタデータ)として登録されているメッセージを、指定のパラメータを埋め込み出力します。

利用例
${msg('path/to/MessageCategory', 'M101')}
${msg('path/to/MessageCategory', 'M102', bean.messageParams)}

引数

説明

String

Message定義の名前(カテゴリ名)を指定します。

String

Message定義のメッセージのID指定します。

Object…​

メッセージに埋め込むパラメータ(単一のオブジェクト、可変引数、もしくは配列、もしくはCollectionのインスタンス)を指定可能です。

戻り値

当該カテゴリ、IDで特定されるメッセージ文言パラメータ埋め込みした文字列。

17.9. nte()

引数がnullの場合は、空文字列をそれ以外の場合は、引数をそのまま返却します。

利用例
${'propX: ' + nte(bean.propX)}

引数

説明

Object

変換対象のObjectを指定します。
引数がClosureの場合は、Closureの実行結果を変換対象とします。

戻り値

引数がnullならから文字列。それ以外なら引数を返却。

17.10. prefs()

Preference定義の値を取得します。

利用例
${prefs('path/to/preferenceName')}

引数

説明

String

Preferenceを特定する名前を指定します。

戻り値

PreferenceにruntimeClassが指定されている場合は、そのクラスのインスタンスが取得されます。
runtimeClass指定がない場合、かつPreferenceSetの場合は、Mapが取得されます。
Preferenceの場合は、valueに定義されているStringが取得されます。

17.11. auth()

認可情報に従って制御を行うための関数です。 特定ロールの場合のみコンテンツを表示したり、コンテンツの処理を特権実行するなどの制御が可能です。
Scriptletにて利用可能です。
コンテンツはClosureにて定義します。

利用例
<%auth(role:'roleA,roleB') {%> (1)
  this content only show with role:"roleA" or "roleB".
  :
  :
<%}%>


<%auth(permission: new ActionPermission('some/actionX', [defName:'Hoge'])) {%> (2)
  this content only show with action permission:"some/actionX?defName=Hoge".
  :
  :
<%}%>


<%auth(privileged: true) {%> (3)
  privileged contents.

  <%
    //some privileged execution
    :
    :

  %>

</m:auth>
1 roleAまたはroleBの場合のみコンテンツを表示(Closureの実行)します
2 some/actionXアクションのAction権限を保持する場合コンテンツを表示(Closureの実行)します
3 コンテンツの処理(Closureの実行)を特権実行します

引数(名前付き)

名前 デフォルト値 説明

role

String

ロール名指定します。
当該ロールを保持する場合、コンテンツが出力(Closureが実行)されます。 複数のロール名をカンマ区切りで指定することが可能です。 複数指定された場合、いずれかのロールを保持する場合にコンテンツが出力されます。

permission

Permission

Permissionのインスタンスを指定します。
当該権限を保持する場合、コンテンツが出力(Closureが実行)されます。

privileged

Boolean

false

trueが指定された場合、コンテンツの出力処理(Closureの実行)を特権実行します。

17.12. esc()

引数のStringをHTML出力用にエスケープします。

Template定義でのみ利用可能な関数です。
利用例
${esc(bean.user.name)}

引数

説明

String

HTMLエスケープしたいStringを指定します。

戻り値

エスケープ処理されたString。

17.13. bind()

Commandの処理結果(Beanに格納されている値、関連するエラー)を画面に表示するためにGroovyTemplateの実行コンテキストにバインドする関数です。 errors関数をbind関数と組み合わせて利用することにより、紐付くプロパティ単位にエラーメッセージの出力制御が可能です。

Template定義でのみ利用可能な関数です。
利用例
<form>
  <%bind(bean: formBean) {%> (1)

    <%bind(prop: 'userName') {%> (2)
      user name : <input type="text" value="${value}" name="${name}"> (3)
      <%errors()%> (4)
    <%}%>

    :

    <%bind(prop: 'mailAddress') {%>
      mail address : <input type="text" value="${value}" name="${name}"> <%errors()%>
    <%}%>

  :

  <%}%>
</form>
1 formBeanという名前で参照(RequestやSessionから)されるBeanをバインドします。
2 formBeanのプロパティuserNameをバインドします。
3 bind関数のClosure内では${value}、${name}でformに指定すべきvalue、nameが取得できます。
4 BeanParamMapperでの当該プロパティのマッピングエラー、バリデーションエラーを表示可能です。

引数(名前付き)

名前 デフォルト値 説明

bean

任意

バインドするBeanのインスタンスを指定します。

バインドされたBeanは、 bean という変数名でClosure内に公開されます。 公開する際の変数名を変更したい場合は、beanVariableNameにて変数名を変更可能です。

beanVariableName

String

bean

バインドされたBeanをClosure内に公開する際の変数名を指定可能です。

mappingResult

MappingResult

BeanParamMapperでのバインド結果である org.iplass.mtp.command.beanmapper.MappingResult のインスタンスを指定可能です。

mappingResultが指定された場合、当該Bean、プロパティに紐付くエラーがバインドされます。 当該属性が未指定の場合、かつautoDetectErrorsがtrueの場合、mappingResultは自動解決されます。 バインドされたMappingResultは mappingResult という変数名でpageContextに公開されます。 公開する際の変数名を変更したい場合は、mappingResultVariableNameにて変数名を変更可能です。

autoDetectErrors

Boolean

true

エラー(mappingResult)を自動解決するか否かを指定可能です。

trueが指定された場合、requestから定数: org.iplass.mtp.web.WebRequestConstants.EXCEPTION をキーに org.iplass.mtp.command.beanmapper.MappingException のインスタンスを取得します。 インスタンスが存在した場合、その例外からMappingResultのインスタンスを取得します。

mappingResultVariableName

String

mappingResult

バインドされたMappingResultをpageContextに公開する際の変数名を指定可能です。

prop

String

バインドされているBeanのプロパティのパスを指定します。 EL式の記法によって、ネストされたプロパティを指定可能です。

EL式での指定例
userName
accout.mail
details[0].id

当該パスが指定されたbind関数のClosureの内側ではプロパティ名、値、当該プロパティに関連するエラーがバインドされます。 Closure内に公開される際の変数名は、デフォルトでは以下の名前で公開されます。

name

HTTPのパラメータ名として利用可能な形のプロパティのパスです。BeanParamMapperのパラメータ名と同様の形式です。

value

プロパティの値の文字列表現です。文字列表現はhtmlEscape、formatter設定にて制御可能です。

rawValue

生のプロパティの値です。

errorValue

エラーが発生場合の生のプロパティの値です。

errors

当該プロパティに関するエラーが存在する場合、エラーメッセージの List<String> のインスタンスです。

公開する際の変数名を変更したい場合はそれぞれ、propertyNameVariableName、propertyValueVariableName、 propertyRawValueVariableName、errorsVariableNameにて変数名を変更可能です。

また、Bean内にネストされたリストをバインドしたい場合、例えば次のような記述が可能です。

ネストされたリストを出力する例
<%bind(bean: fb) {%>

  :

  <%for (int i =0; i < fb.children.size(); i++) {%>
    ${i}.
    <%bind(prop: "children[${i}].name") {%>
      child name : <input type="text" value="${value}" name="${name}">
      <%errors()%>
    <%}%>
  <%}%>

<%}%>

prop指定と同時にbeanが指定された場合は、そのbeanのプロパティをバインドします。 beanが未指定の場合は、親タグに指定されるbeanのプロパティをバインドします。

htmlEscape

Boolean

true

value(プロパティの値の文字列表現)を出力する際にhtmlエスケープ処理をするか否かを指定可能です。

このフラグによってエスケープ処理されるのはvalueのみです。name、rawValue、errorValue、errorsの値はエスケープされません。

formatter

ValueFormatter

DEFAULT_FORMATTER

value(プロパティの値の文字列表現)を出力する際のフォーマット処理を行う org.iplass.mtp.web.template.ValueFormatter のインスタンスを指定します。

未指定の場合は、 ValueFormatter.DEFAULT_FORMATTER で指定されるデフォルトの処理が適用されます。 デフォルト処理では値が文字列以外の場合に次のようにフォーマットします。

Integer、Double、BigDecimalなどの数値型

数値を10進数表現で文字列に変換します。

SelectValue型

SelectValueのvalueを出力します。

BinaryReference型

BinaryReferenceのlobIdを出力します。

Date型

yyyy-MM-dd形式で出力します。

Time型

HH:mm:ss形式で出力します。

Timestamp型もしくは、java.sql.Date、java.sql.Time以外のjava.utilDate型

yyyy-MM-dd’T’HH:mm:ss.SSSXXX形式で出力します。

beanが指定されているbindタグに指定した場合、配下のプロパティの値に一律適用されます。

formatterを利用せず個別にrawValueからフォーマットすることも可能です。

rawValueから直接出力する例
<%bind(prop:'dateProp') {%>
  <input type="text" value="${errorValue ?: fmt(rawValue, 'yyyy/MM/dd')}" name="${name}">
<%}%>

propertyNameVariableName

String

name

バインドされたプロパティのHTTPパラメータ名をClosure内に公開する際の変数名を指定可能です。

propertyValueVariableName

String

value

バインドされたプロパティの値の文字列表現をClosure内に公開する際の変数名を指定可能です。

propertyRawValueVariableName

String

rawValue

バインドされたプロパティの生の値をClosure内に公開する際の変数名を指定可能です。

propertyErrorValueVariableName

String

errorValue

バインドされたプロパティがエラーの場合、そのエラー値が格納される変数名を指定可能です。

errorsVariableName

String

errors

バインドされたプロパティに関連するエラーメッセージの List<String> をClosure内に公開する際の変数名を指定可能です。

prefix

String

name(HTTPパラメータ名)を出力する際のprefixを指定します。

HTTPリクエストをBeanParamMapperでマッピングする場合、BeanParamMapperのparamPrefixの値と一致させる必要があります。

propertyDelimiter

String

.

name(HTTPパラメータ名)を出力する際のネストされたプロパティのデリミタを指定します。

HTTPリクエストをBeanParamMapperでマッピングする場合、BeanParamMapperのpropertyDelimiterの値と一致させる必要があります。

indexPrefix

String

[

name(HTTPパラメータ名)を出力する際のインデックス指定のプレフィックス文字を指定します。

HTTPリクエストをBeanParamMapperでマッピングする場合、BeanParamMapperのindexPrefixの値と一致させる必要があります。

indexPostfix

String

]

name(HTTPパラメータ名)を出力する際のインデックス指定のポストフィックス文字を指定します。

HTTPリクエストをBeanParamMapperでマッピングする場合、BeanParamMapperのindexPostfixの値と一致させる必要があります。

17.14. errors()

エラーが存在する場合、エラー内容をフォーマットしてhtml出力する関数です。

Template定義でのみ利用可能な関数です。

errors関数が記述される場所、設定される属性値により、出力される内容が異なります。

  • bind関数配下、かつprop指定がある場合

    当該プロパティに紐付くエラーがある場合、エラーを出力します。

    利用例
    <%bind(bean: formBean) {%>
      :
    
      <%bind(prop: 'userName') {%>
        user name : <input type="text" value="${value}" name="${name}">
        <%errors()%> (1)
      <%}%>
      :
    
    <%}%>
    1 formBeanのuserNameに紐付くエラーがある場合にエラー内容が出力されます。
  • bind関数配下、かつprop指定がない場合

    当該Beanに紐付くエラーがある場合、そのすべてのエラーを出力します。

    利用例
    <%bind(bean: formBean) {%>
      <%errors()%> (1)
      :
    
      <%bind(prop: 'userName') {%>
        user name : <input type="text" value="${value}" name="${name}">
      <%}%>
      :
    
    <%}%>
    1 formBeanに紐付くすべてのエラー内容が出力されます。
  • bind関数配下ではない場合

    requestから定数: org.iplass.mtp.web.WebRequestConstants.EXCEPTION をキーに例外を取得しそのメッセージを出力します。

    当該Exceptionが org.iplass.mtp.command.beanmapper.MappingException の場合

    その例外に保持されるMappingResultのメッセージを出力します。

    当該Exceptionが org.iplass.mtp.ApplicationException の場合

    その例外のメッセージを出力します。

    当該Exceptionがそれ以外の場合

    固定のシステム例外メッセージを出力します。

  • 引数にて明示的にerrorsを指定した場合

    指定されたインスタンスにより適切にメッセージ出力します。 出力内容については引数の説明:errorsを参照してください。

引数(名前付き)

名前 デフォルト値 説明

errors

Object

出力するエラー対象を指定します。 指定されたエラー対象により適切にエラーメッセージ出力します。

String の場合

指定されたStringを出力します。

org.iplass.mtp.command.beanmapper.MappingError の場合

指定されたMappingErrorのerrorMessagesを出力します。

org.iplass.mtp.command.beanmapper.MappingResult の場合

指定されたMappingResultが保持するMappingErrorのerrorMessagesを出力します。

org.iplass.mtp.command.beanmapper.MappingException の場合

指定されたMappingExceptionのMappingResultの内容を出力します。 org.iplass.mtp.ApplicationException の場合 指定されたApplicationExceptionのmessageを出力します。

Throwable の場合

固定のシステム例外メッセージを出力します。

List<String>、配列の場合

指定されたリスト、配列の内容を1件ずつ出力します。

それ以外の場合

指定されたインスタンスのtoString()を出力します。

delimiter

String

<br>

エラーメッセージが複数ある場合のデリミタを指定可能です。

header

String

<span class=\"error\">

エラーメッセージを出力する際、先頭に出力する内容を指定可能です。

footer

String

</span>

エラーメッセージを出力する際、最後に出力する内容を指定可能です。

htmlEscape

Boolean

true

エラーメッセージを出力する際にhtmlエスケープ処理をするか否かを指定可能です。

errorsVariableName

errors

エラーをClosure内に公開する際の変数名を指定可能です。 また、この変数名は親のbind関数でClosure内に公開されたエラーを探す場合の変数名としても利用されます。

メッセージ出力内容をカスタムする

Closure内にGroovyTemplateコードを記述することにより、エラーメッセージ出力内容をカスタマイズすることが可能です。

カスタマイズ例
<%errors() {%>
  <span>
  <b>エラーが発生しました</b><br>
  エラー内容:${errors}
  </span>
<%}%>

カスタマイズ出力する場合は、delimiter、header、footer、htmlEscapeの設定は利用されません。

17.15. token()

トランザクショントークンの値を出力します。

Template定義でのみ利用可能な関数です。
利用例
<input type="hidden" name="_t" value="${token()}">

引数

なし

戻り値

新規に発行されたトークン文字列。

17.16. fixToken()

固定トークン(セッション単位の固定値)の値を出力します。 CSRF(XSRF)対策用に利用可能です。

Template定義でのみ利用可能な関数です。
利用例
<input type="hidden" name="_t" value="${fixToken()}">

引数

なし

戻り値

セッション単位に固定のトークン文字列。

17.17. tcPath()

テナントコンテキストパスを出力します。 テナントコンテキストパスは ServletContextPath + tenantURL で定義される、 APサーバ上でテナントまでを特定するルート相対パスです。

Template定義でのみ利用可能な関数です。
利用例
<a href="${tcPath()}/path/to/action">link</a>

引数

なし

戻り値

テナントコンテキストパス

17.18. include()

GroovyTemplate内に別Actionの出力を取り込むための関数です。

Template定義でのみ利用可能な関数です。
利用例
<%include('your/action/path')%>

引数

説明

String

includeするActionの名前を指定します。

戻り値

なし

17.19. includeTemplate()

GroovyTemplate内に別Templateの出力を取り込むための関数です。

Template定義でのみ利用可能な関数です。
利用例
<%includeTemplate('your/template/path')%>

引数

説明

String

includeするTemplateの名前を指定します。

戻り値

なし

17.20. renderContent()

Layoutアクションのgroovy templateにおいて、実際のコンテンツを表示する箇所を指定する関数です。

Template定義でのみ利用可能な関数です。
利用例
:

<div id="main">
  <!-- ここにメインコンテンツが出力される -->
  <%renderContent()%>
</div>

:

引数

なし

戻り値

なし