Show Table of Contents
第4章 検証
Smooks では、ルールという言葉は一般的な概念を意味します。特定のカートリッジに固有なものではありません。
他のコンポーネントより RuleProvider を設定および参照できます。
注記
検証カートリッジは、ルール機能を使用する唯一のカートリッジです。
ルールは ruleBases より中央的に定義されます。単一の Smooks 設定は複数の ruleBase 定義を参照できます。ruleBase 設定には名前、ルール
src、およびルールプロバイダーがあります。
ルールソースの形式はプロバイダー実装に全体的に依存します。参照できるようにするため、各ルールに一意な名前 (単一ソースのコンテキスト内) を付けることのみが必要になります。
ruleBase 設定の例は次の通りです。
<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:rules="http://www.milyn.org/xsd/smooks/rules-1.0.xsd">
<rules:ruleBases>
<rules:ruleBase name="regexAddressing" src="/org/milyn/validation/address.properties" provider="org.milyn.rules.regex.RegexProvider" />
<rules:ruleBase name="order" src="/org/milyn/validation/order/rules/order-rules.csv" provider="org.milyn.rules.mvel.MVELProvider"/>
</rules:ruleBases>
</smooks-resource-list>
rules:ruleBase 設定要素の設定オプションは次の通りです。
- name: このルールを参照するために他のコンポーネントが使用します。必須のオプションです。
- src: ファイルまたは RuleProvider にとって意味のあるものになります。必須のオプションです。
- provider: 使用したい実際のプロバイダー実装になります。ここで異なる技術が実行されます。 上記の設定では、 1 つの RuleProvider が正規表現を使用しますが、 複数の ruleBase 要素を指定でき、これらの ruleBase は必要な数の RuleProviders を持つことができます。必須のオプションです。
ルールプロバイダは
org.milyn.rules.RuleProvider インターフェースを実装します。
Smooks には 2 つの RuleProvider 実装が事前設定されています。
- RegexProvider
- MVELProvider
独自の RuleProvider 実装を作成することも可能です。
名前の通り、 RegexProvider は正規表現を使用できるようにします。 フィルタされたメッセージの選択されたデータフィールドの形式に固有する低レベルなルールを定義できるようにします。たとえば、電子メールアドレスの正しい構文が含まれていることを検証するため、特定のフィールドに適用されることがあります。
次のコードは Regex ruleBase の設定方法を表しています。
<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:rules="http://www.milyn.org/xsd/smooks/rules-1.0.xsd">
<rules:ruleBases>
<rules:ruleBase name="customer" src="/org/milyn/validation/order/rules/customer.properties" provider="org.milyn.rules.regex.RegexProvider"/>
</rules:ruleBases>
</smooks-resource-list>
正規表現は標準の
.properties ファイル形式で定義されます。 以下は customer.properties の正規表現ルール定義ファイル (上記の例より) の一例になります。
# Customer data rules...
customerId=[A-Z][0-9]{5}
customerName=[A-Z][a-z]*, [A-Z][a-z]
MVEL プロバイダは、ルールを MVEL 表現として定義できるようにします。これらの表現は Smooks Javabean コンテキストの内容上で実行されます。そのため、 Smooks Bean コンテキストの Java オブジェクトにデータ (フィルタリングされたメッセージから) をバインドする必要があります。
これは、 メッセージ断片でさらに複雑なルールを定義できるようにします (例: ターゲットされた注文商品断片の製品は、注文ヘッダー詳細に指定された顧客の年齢資格制限内であるか)。
このコードは MVEL ruleBase の設定方法を表しています。
<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:rules="http://www.milyn.org/xsd/smooks/rules-1.0.xsd">
<rules:ruleBases>
<rules:ruleBase name="order" src="/org/milyn/validation/order/rules/order-rules.csv" provider="org.milyn.rules.mvel.MVELProvider"/>
</rules:ruleBases>
</smooks-resource-list>
MVEL ルールを CSV ファイルに保存する必要があります。これらのファイルを編集する最も簡単な方法は、LibreOffice Calc や Gnumeric などのスプレッドシートアプリケーションを使用することです。各ルールレコードには、以下で構成される 2 つのフィールドが含まれます。
- ルール名
- MVEL 表現
コメントヘッダーの行を追加するには、 最初のフィールドの前にハッシュマーク(#) を追加します。
Smooks 検証カートリッジはルールカートリッジによって提供される機能によって構築され、ルールベースの断片検証を提供します。
これにより、メッセージ断片上で詳細な検証を実行できるようになります。Smooks の他の機能と同様に、検証機能はサポート対象の全データ形式で使用可能です。そのため、XML データだけでなく EDI や JSON、CSV などにも強固な検証を実行することができます。
検証の設定は http://www.milyn.org/xsd/smooks/validation-1.0.xsd 設定名前空間によって定義されます。
Smooks は複数のルールプロバイダ タイプをサポートし、検証カートリッジはこれらのタイプを使用できます。各ルールプロバイダタイプは異なるレベルの検証を提供しますが、すべて全く同じように設定されます。Smooks の検証カートリッジはルールプロバイダを抽象リソースと見なし、メッセージ断片を検証するためメッセージ断片を目指します。
検証ルールの設定には以下を指定する必要があります。
- executeOn: ルールが実行される断片です。
- excecuteOnNS: executeOn が属する断片名前空間です。
- name: 適用されるルールの名前です。 ドット区切り形式の ruleBase と ruleName の組み合わせ (ruleBaseName.ruleName) を参照する複合ルール名です。
- onFail: 適合の失敗の深刻度を判断します。
検証ルールの設定例は次の通りです。
<validation:rule executeOn="order/header/email" name="regexAddressing.email" onFail="ERROR" />
Smooks フィルター操作ごとの検証最大失敗数を設定できます。最大値を越えると例外がスローされます。OnFail.FATALに設定された検証は常に例外をスローし、 処理を停止することに注意してください。
最大検証失敗数を設定するには、次のコードを Smooks の設定に追加します。
<params>
<param name="validation.maxFails">5</param>
</params>
検証設定の onFail 属性は実行するアクションを指定しました。これは、検証の失敗をどのように報告するかを決定します。
使用できるオプションは次の通りです。
- OK: これを使用して検証を okay として保存します。 ValidationResults.getOks を呼び出すとすべての検証警告が返されます。コンテンツベースのルーティングを使用する場合に便利なオプションです。
- WARN: 検証を warning として保存します。 ValidationResults.getWarnings を呼び出すとすべての検証警告が返されます。
- ERROR: 検証を error として保存します。 ValidationResults.getErrors を呼び出すとすべての検証エラーが返されます。
- FATAL: 検証の失敗が発生した直後に ValidationException をスローします。 ValidationResults.getFatal を呼び出すと致命的な検証失敗が表示されます。
ルールベースには次の形式の複合ルール名を使用します。
<ruleProviderName>.<ruleName>
- ruleProviderName はルールプロバイダを識別し、 ruleBase 要素の name 属性へマッピングします。
- ruleName はルールプロバイダの認識する特定ルールを識別します。src ファイルに定義されるルールである場合もあります。
Smooks.filterSource は検証の結果をキャプチャします。 filterSource メソッドが返される時、ValidationResult インスタンスにはすべての検証データが含まれます。
次のコードは Smooks がメッセージ断片の検証をどのように実行するかを表しています。
ValidationResult validationResult = new ValidationResult(); smooks.filterSource(new StreamSource(messageInStream), new StreamResult(messageOutStream), validationResult); List<OnFailResult> errors = validationResult.getErrors(); List<OnFailResult> warnings = validationResult.getWarnings();
上記のコードでは、 個別の警告とエラーの検証結果が OnFailResult インスタンスの形式で ValidationResult オブジェクトより使用できるようになります。 各 OnFailResult インスタンスは障害の詳細を提供します。
検証カートリッジを使用すると、検証の失敗に関連する現地語化メッセージを指定することもできます。 現地語化メッセージは標準の Java ResourceBundleファイルに定義します (
.properties 形式を使用)。
注記
検証メッセージバンドルのベース名はルールソース (src) が基になります。 ルールソースのファイル拡張子を省略し、 i18n という名前のフォルダーを追加します。たとえば、
/org/milyn/validation/order/rules/order-rules.csv の MVEL ruleBase ソースの場合、対応する検証メッセージバンドルのベース名は /org/milyn/validation/order/rules/i18n/order-rules になります。
検証カートリッジを使用すると、FreeMarker テンプレートを現地語化メッセージに適応できるため、Bean コンテキストからのコンテキストデータや、実際に発生したルールの失敗に関するデータがメッセージに含まれるようにすることが可能です。FreeMarker ベースのメッセージの前には
ftl: を付ける必要があり、標準の FreeMarker の表記法を使用してコンテキストデータを参照する必要があります。Bean コンテキストからの Bean は直接参照することが可能ですが、RuleEvalResult とルールの失敗のパスは ruleResult および path Bean を介して参照することが可能です。
RegexProvider ルールを使用する例は次の通りです。
customerId=ftl:Invalid customer number '${ruleResult.text}' at '${path}'. Customer number must match pattern '${ruleResult.pattern}'.
この例は Smooks を使用してメッセージ断片データを検証する方法を表しています。 2 種類の検証ルールを使用して 2 種類の検証を実行します。
.propertiesファイル RuleBase に定義された正規表現を使用したメッセージフィールド値/形式の検証。たとえば、フィールドを有効な電子メールアドレスとして検証することが可能です。.csvfile RuleBase に定義された MVEL 表現を使用したビジネスルールの検証。たとえば、ある注文の注文商品の合計価格 (価格に数量をかけた値) が事前定義されたビジネスルールに違反しないかどうかを検証することができます。
このルールを実行するには、ルートフォルダーの例に移動し、以下を実行します。
mvn clean installmvn exec:java
次の例では、注文商品が複数含まれた XML メッセージが存在します (この機能は、Smooks によってサポートされる他のデータ形式すべてに対して同様に動作します)。
<Order>
<header>
<orderId>A188127</orderId>
<username>user1</username>
<name>
<firstname>Harry</firstname>
<lastname>Fletcher</lastname>
</name>
<email>harry.fletcher@gmail.</email>
<state>South Dakota</state>
</header>
<order-item>
<quantity>1</quantity>
<productId>364b</productId>
<title>The 40-Year-Old Virgin</title>
<price>29.98</price>
</order-item>
<order-item>
<quantity>2</quantity>
<productId>299</productId>
<title>Pulp Fiction</title>
<price>29.99</price>
</order-item>
</Order>
注文メッセージデータに複数の検証を実行します。
提供されたユーザー名が、大文字の後に5 つ数字が続く (S12345 や G54321 など) 形式に従うことを確認します。この検証を実行するには、正規表現を使用する必要があります。
次に、提供された電子メールアドレスが有効な形式であることを確認する必要があります。ここでも正規表現を使用して確認を行います。
さらに、各注文商品の productId フィールドの形式 が 3 つの数字 (123 や 321 など) であることを確認する必要があります。ここでも正規表現を使用します。
最後に、各注文商品の合計が 50.00 を越えない (価格と数量を掛けた値が 50.00 を越えない) ことを確認する必要があります。この検証には MVEL 表現を使用します。
この検証を実行するには、正規表現ルールを分割し、個別の 2 つの
.properties ファイルに置きます。
ここで、これらのファイルを例の
rules ディレクトリに移動します。
MVEL 表現を
.csv ファイルと rules ディレクトリに置きます。
customer.properties ファイルに格納される顧客関係の正規表現ルールは次のようになります。
# Customer data rules...
customerId=[A-Z][0-9]{5}
# Email address...
email=^[\\w-\\.]+@([\\w-]+\\.)+[\\w-]{2,4}$
product.properties ファイルに格納される商品関係の正規表現ルールは次のようになります。
# Product data rules...
productId=[0-9]{3}
注文商品の合計をチェックする MVEL 表現は
order-rules.csv ファイルに格納されます。
注記
OpenOffice.org Calc や Gnumeric などの表計算アプリケーションを使用すると、最も簡単に .cvs ファイルを編集できます。
ここで、各ルールソースファイルに対してリソースバンドルの
.properties ファイルを作成します。
注記
これらのファイルの名前は、対応するルールファイルの名前を基にしていることに注意してください。
rules/customer.properties に定義されるルールのメッセージバンドルは、 rules/i18n/customer.properties ファイルにあります。
customerId=ftl:Invalid customer number '${ruleResult.text}' at '${path}'.
<!-- Customer number must begin with an uppercase character, followed by 5 digits. -->
email=ftl:Invalid email address '${ruleResult.text}' at '${path}'.
<!-- Email addresses match pattern '${ruleResult.pattern}'. -->
rules/product.properties に定義されるルールのメッセージバンドルは rules/i18n/product.properties ファイルにあります。
# Product data rule messages...
productId=ftl:Invalid product ID '${ruleResult.text}' at '${path}'.
<!-- Product ID must match pattern '${ruleResult.pattern}'. -->
rules/order-rules.csv に定義されるルールのメッセージバンドルは rules/i18n/order-rules.properties ファイルにあります。
# <!-- Order item rule messages. The "orderDetails" and "orderItem" beans are populated by Smooks bindings - see config in following section. -->
order_item_total=ftl:Order ${orderDetails.orderId}
<!-- contains an order item for product ${orderItem.productId} with a quantity of ${orderItem.quantity} and a unit price of ${orderItem.price}. This exceeds the permitted per order item total. -->
これらの検証ルールを適用するために使用する必要がある設定は次の通りです。
<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
xmlns:rules="http://www.milyn.org/xsd/smooks/rules-1.0.xsd"
xmlns:validation="http://www.milyn.org/xsd/smooks/validation-1.0.xsd"
xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.2.xsd">
<params>
<!-- Generate a ValidationException if we get more than 5 validation failures... -->
<param name="validation.maxFails">5</param>
</params>
<!-- Define the ruleBases that are used by the validation rules... -->
<rules:ruleBases>
<!-- Field value rules using regex... -->
<rules:ruleBase name="customer" src="rules/customer.properties" provider="org.milyn.rules.regex.RegexProvider"/>
<rules:ruleBase name="product" src="rules/product.properties" provider="org.milyn.rules.regex.RegexProvider"/>
<!-- Order business rules using MVEL expressions... -->
<rules:ruleBase name="order" src="rules/order-rules.csv" provider="org.milyn.rules.mvel.MVELProvider"/>
</rules:ruleBases>
<!-- Capture some data into the bean context - required by the business rule validations... -->
<jb:bean BeanId="orderDetails" class="java.util.HashMap" createOnElement="header">
<jb:value data="header/*"/>
</jb:bean>
<jb:bean BeanId="orderItem" class="java.util.HashMap" createOnElement="order-item">
<jb:value data="order-item/*"/>
</jb:bean>
<!-- Target validation rules... -->
<validation:rule executeOn="header/username" name="customer.customerId" onFail="ERROR"/>
<validation:rule executeOn="email" name="customer.email" onFail="WARN"/>
<validation:rule executeOn="order-item/productId" name="product.productId" onFail="ERROR"/>
<validation:rule executeOn="order-item" name="order.order_item_total" onFail="ERROR"/>
</smooks-resource-list>
例の
Main クラスより実行するためのコードは次の通りです。
protected static ValidationResult runSmooks(final String messageIn) throws IOException, SAXException, SmooksException {
// Instantiate Smooks with the config...
final Smooks smooks = new Smooks("smooks-config.xml");
try {
// Create an exec context - no profiles....
final ExecutionContext executionContext = smooks.createExecutionContext();
final ValidationResult validationResult = new ValidationResult();
// Configure the execution context to generate a report...
executionContext.setEventListener(new HtmlReportGenerator("target/report/report.html"));
// Filter the input message...
smooks.filterSource(executionContext, new StringSource(messageIn), validationResult);
return validationResult;
}
finally {
smooks.close();
}
}

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.