Java
spring-boot
spring-webflow

時代遅れかもしれないSpring Web Flow入門 1

More than 1 year has passed since last update.


Spring Web Flow


Spring Web Flow概要

本家サイト

多分、昔からのSpring MVC(Grails)使いなら、経験もあるだろうProject。

ターゲットとなるアプリは

* 開始と終了のある一連の業務フローを実行する。

* ユーザーは定義された順序で複数画面を経由して操作を行う。

* 最終的なフローが終了されるまで、変更は反映されない。

* フローが終了すると、そのフローは繰り返されない。

上位のような場合、従来はHTTPセッションにキャッシュしておいて、フロー終了時にコミットする、というのが一般的だと思います。(要件によってはDBに一時情報を入れる場合もあり。)

ただ、戻るボタン、複数タブ、セッションクリアのタイミング等々、色々とバグの温床になります。

そういった課題に対して解決策を提示してくれているのがSpring Web Flowです。

よさそう、よさそうと思っていたけど、試していなかったので、やってみます。

JSFとも連携できますが、この記事ではSpring MVCを前提にします。


フロー定義

Spring Web Flow では、Spring MVCのようなコントローラは記述しません。フロー定義と呼ばれるxmlに画面(View)と処理(Action)の遷移を記述します。フロー定義に基づいて、フレームワークが提供するコントローラが画面遷移と処理を実行します。

フロー定義の例


sample-flow.xml

<?xml version="1.0" encoding="UTF-8"?>

<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
>

<!-- フォームオブジェクトの初期化 -->
<var name="sampleForm" class="sample.SampleForm"/>

<!-- 初期画面「start」ステート。 event1が発行された場合、「action」ステートに遷移する。
イベント発生時には、modelで指定されたオブジェクトにパラメータをバインドさせる。
-->

<view-state id="start" view="start" model="sampleForm">
<transition on="event1" to="action"/>
</view-state>

<!-- 「action」ステート 処理を実行し、実行結果に基づいてステートを遷移させる。 -->
<action-state id="action">
<!-- アクションの実行 -->
<evaluate expression="sampleAction.execute(sampleForm,messageContext)"/>
<transition on="success" to="end">
<!-- アクションの結果を「actionResult」の名前でフロースコープに保存。 -->
<set name="flowScope.actionResult" value="currentEvent.attributes.result"></set>
</transition>
<transition on="error" to="start" />
</action-state>

<!-- 「end」ステート。フローの終了 -->
<end-state id="end" view="end"></end-state>
</flow>


アクセスするURLはフロー定義が配置されたパスによって決まります。

フロー定義配置の例

* ルートフォルダ(設定可能)

|

|-flow-sample-「sample-flow.xml」

上記の例では「/flow/sample」が当該フローを示すURLとなります。初期画面はフロー定義の先頭に記述されたステートです。フロー内部の遷移はリクエストパラメータに応じて行われます。URLは常に「/flow/sample」です。


画面

画面は「view-state」によって定義します。view属性に指定したパスに存在するJSP,もしくはTemplateが「view-state」に紐づく画面になります。


処理

フロー内部での処理は、ステート内部の「evaluate」要素に記述します。Java言語と同じように、インスタンス名.メソッド名で処理を呼び出します。インスタンスはSpringのコンテナに管理されているBeanを利用できます。


Spring Web Flowのメリット

HTTPは基本的にはステートレスで、一回の通信で終わりであるため、HTTPにフィットしたコントローラの処理は、1リクエスト毎に記述するしかありません。

Spring Web FlowはそうしたHTTPの特徴を隠して、複数リクエストにまたがるフローを一つの処理であるかのようにフロー定義上に表現できます。


Spring Web Flowのデメリット

昨今のWeb開発の潮流はコントローラ部分はクライアントサイドで行い、サーバ側は可能な限り、ステートレスであろうとしているようです。これは大量アクセス、画像や動画、音声などのコストの高いデータのやり取りをするようになったことや、よりリッチなUIが求められるようになったことによるものでしょう。

そうした潮流からみると、サーバ上で状態を管理するSpring Web Flowは時代遅れなのかもしれません。

Jsonフォーマットを使った軽量なWebサービスにおいて、複数リクエストにまたがるフローを表現する方法として、HETEOASなどが提案されています。

Spring HETEOAS