Contenu connexe
Similaire à Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~ (20)
Application Re-Architecture Technology ~ StrutsからSpring MVCへ ~
- 1. Copyright © 2016 NTT DATA Corporation
株式会社NTTデータ 技術革新統括本部
ソフトウェア工学推進センタ
Application Re-Architecture Technology
~ StrutsからSpring MVCへ ~
- 2. 2Copyright © 2016 NTT DATA Corporation
自己紹介
池谷 智行
NTTデータ社内標準アプリケーションフレームワークである
TERASOLUNA Frameworkの整備、展開を担当している。
Spring信者で、Spring MVCやSpring Batchを用いた実務開発経験あ
り。
「Spring徹底入門」を執筆。
倉元 貴一
長年、某金融機関のミッションクリティカルシステム向けJavaフ
レームワーク開発を担当していた。
現在はTERASOLUNAチームでバッチフレームワークに携わりつつ、
社内の様々なプロジェクトのサポートをしている。
「Spring徹底入門」を執筆。
- 3. 3Copyright © 2016 NTT DATA Corporation
TERASOLUNAとは
Process
Environment
Support
数多くのシステム開発で
培ったノウハウを盛り込
んだ
標準開発手順・管理手順
ソフトウェアを開発する際
の
雛形になるフレームワーク
と開発を支援するツール
蓄積されたノウハウ
を展開するための
研修や教育サービス
標準手順
サポート
開発環境
数多くのシステム開発実績をもとにした「標準手順」「開発環境」「サ
ポート」を
トータルで提供しており、TERASOLUNAを活用することで、高品質な
システム開発が実現できます。
TERASOLUNAとは、NTTデータのシステム開発を支える
オープン系システム開発のための総合ソリューション
- 4. 4Copyright © 2016 NTT DATA Corporation
TERASOLUNAフレームワークのコンセプト
業務アプリケーション
エンタープライズ利用における当社知見をベースに、
Springを最大限活用したフレームワークへ
Struts1 iBATIS
独自フレームワーク層
業務アプリケーション
Spring IO Platform
Spring
Security
Spring
MVC JPA
MyBatis
1. 各種OSSをベースとしつつも、
独自フレームワークの開発に注力
2. 機能説明書を提供
1. OSSを組み合わせ、独自部分を極小化
2. OSSの機能を最大限に活かして開発する
ためのベストプラクティスを提供するこ
とに注力
開発ガイドライン開発ガイドライン
- 5. 5Copyright © 2016 NTT DATA Corporation
TERASOLUNA Frameworkの構成要素
• Spring, MyBatisなどのOSSフレームワーク
ソフトウェアフレーム
ワーク
• エンタープライズ向けに必要な汎用的な部品共通ライブラリ
• OSSを利用したエンタープライズ向けアプリ
開発に
おけるベストプラクティスドキュ
メント
ガイドライン
• 基本的な開発方法を学ぶ学習教材チュートリアル
• 基本的な機能を実装したサンプルアプリサンプルAP
• プロジェクト構成のひな形ブランクプロジェクト
- 6. 6Copyright © 2016 NTT DATA Corporation
公開資材の一例
http://terasolunaorg.github.io/
開発ガイドライン
ポータルサイト
資材提供
- 7. 7Copyright © 2016 NTT DATA Corporation
ニュースリリース
2016/02/24 本格運用開始のニュースリリース
http://www.nttdata.com/jp/ja/news/release/2016/022400.html
エンドースメント頂いた会社様(敬称略)
• Pivotal
• 株式会社NTTデータ イントラマート
• 日本アイ・ビー・エム株式会社
• 日本オラクル株式会社
• 日本電気株式会社
• 株式会社日立製作所
• 富士通株式会社
• Red Hat Inc.
- 8. Copyright © 2015 NTT DATA Corporation 8
TERASOLUNA Frameworkの狙い
コモディティ化しつつある領域では
仲間を増やし、業界貢献することが重要
お客様 競合他社 開発者 OSSコミュニティ
- 9. 9Copyright © 2016 NTT DATA Corporation
(参考)ガイドラインへのアクセス数
公開から33万ユーザ以上にアクセスされ
毎日4000ページビュー以上閲覧されている
- 10. 10Copyright © 2016 NTT DATA Corporation
Springイベントのスポンサーおよび講演
Springの当社プレゼンスを向上するため
積極的に講演活動およびイベントスポンサーに取り組む
2015年に引き続き、世界最大のSpringプロジェクトイベント
「SpringOne Platform 2016」のシルバースポンサーとして協賛
イベント参加レポートはこちらから
Spring 5.0は来春リリース!クラウドネイティブ開発、マイクロサービス化など最新技術・事例にあふれた
4日間
http://codezine.jp/article/detail/9631
- 11. 11Copyright © 2016 NTT DATA Corporation
Springに関する書籍出版
好評につき
増刷決定!!
Spring徹底入門執筆
Spring初心者からSpring有識者まで
書籍の詳細はこちらから
http://www.shoeisha.co.jp/book/detail/9784798142470
- 12. Copyright © 2015 NTT DATA Corporation 12
INDEX
1. なぜ今移行なのか
2. 実プロジェクトでの取り組み
3. おわりに
- 14. 14Copyright © 2016 NTT DATA Corporation
Struts 1 の EOLがもたらしたこと
• 従来、JavaなエンタープライズシステムはStrutsで組まれていた
• Struts 1.x EOL(2013/4) → 脆弱性発覚(2014/4)
http://www.nttdata.com/jp/ja/news/information/2014/2014042801.html
- 15. 15Copyright © 2016 NTT DATA Corporation
Struts 1 を使い続けるということ
• Struts 1 を使い続けると…
• セキュリティへの対応が困難になる
• 機会損失を産んでしまう
- 17. 17Copyright © 2016 NTT DATA Corporation
http://zeroturnaround.com/rebellabs/java-tools-and-technologies-landscape-2016/
Springのシェアは高い!
- 18. 18Copyright © 2016 NTT DATA Corporation
Struts 1 から Spring へ
業務アプリケーション
当社もSpringを最大限活用したフレームワークへ舵を切った
Struts1 iBATIS
独自フレームワーク層
業務アプリケーション
Spring IO Platform
Spring
Security
Spring
MVC JPA
MyBatis
開発ガイドライン開発ガイドライン
- 20. Copyright © 2015 NTT DATA Corporation 20
業務アプリケーション
フレームワーク
ミドルウェア
OS/HW
ミドルウェア
OS/HW
システム更改パターン
開発 運用
開発 運用
開発 運用
2次(基盤更
改)
初期
3次(刷
新)
5~7 9~12 14~17経過年数
初期開発時に採用したフレームワークは
長期間利用される傾向がある
初回更改時は、システム基盤更改
(OS/HW/MWのEOL対応)
と簡単な機能追加に留まるケースが多
い
2回目の更改時は、システム全体の刷新
を
前提にした開発予算が計上されやすい
- 21. 21Copyright © 2016 NTT DATA Corporation
WebAPサーバ
Spring
JavaEEサーバ
EJB
WebAPサーバ
WebAPサーバ
FW移行の難しさ
• 更改周期と合わないが、外的要因で移行しなくてはならない
• 手軽に移行するソリューションが欲しくなる
• PRJ特化な手順 -> 汎用手順 -> 汎用ツール とできると理想
• ツール化は可能なのか?
• APのアーキテクチャはプロジェクトによりけり。特に、Strutsはフルス
タックなフレームワークではないため、ビジネスロジック以降の構成は
様々。
全てに対応することは困難。
Struts 1
Action
POJO Logic
JDBCres
req
Struts 1
Action
POJO Logic
JDBCres
req
WebAPサーバ
Struts 1
Action
Session Bean
Entity Beanres
req
Struts 1
Action
POJO Logic
O/R Mapperres
req
①Actionにビジネスロジックをベタ書き
②独自のレイヤリング
③EJB呼び出し
④SSH(Spring + Struts + Hibernate)構成
- 22. Copyright © 2015 NTT DATA Corporation 22
移行時に必要となる要素
計画 設計 製造 試験
移行
プロセス
移行時の
見積もり手法
移行の
実施要領
移行
ツール
見積も
り
ツール
移行ツール
マニュアル
等
移行では、効率化のための各種ツール、
ツールをベースとしたプロセスや実施要領、
移行案件の見積もり方法など、多岐にわたる
• 必要な物や内容は、プロジェクトごとに事情が異なる。
• そっと移行して延命すればいい。機能追加はほとんどない。
• ツール等で極力お金をかけずに処置したいという判断もあり得
る。
• 移行した後もアクティブに改修/機能追加する。
• それならばいっそ作りなおしたほうが良いという判断もあり得
- 23. Copyright © 2015 NTT DATA Corporation 23
移行の影響範囲
計画 設計 製造 試験
B
P
RD ED ID M/UT IT ST
システム基盤設計 システム基盤構築
業務
機能
処理
FW
コンポーネント
FWFW
コンポーネント
処理
機能
業務フロー
移行コストを最小限とするため、
プロジェクトに合わせて影響範囲を局所化する方策が必要
FW移行の
影響範囲
システム基盤更改の
影響範囲
- 24. 24Copyright © 2016 NTT DATA Corporation
移行作業の流れの一例
No 作業分類 作業対象
1 設定ファイルの移行 web.xml
データソース
ロギング
プロパティファイル
2 インフラストラクチャ層への
移行
DAO関連のI/F, 各種設定ファイル
3 ドメイン層への移行 ビジネスロジック
4 アプリケーション層への移行 アクションフォーム
Struts設定ファイル
アクション
5 設定ファイルの移行 Bean定義ファイル
6 アプリケーション層への移行 JSP
入力チェック
7 共通処理の移行 例外処理
メッセージ
8 セキュリティ対策 認証/認可
XSS対策・CSRF対策等
Struts 1 + Spring から Spring MVCに移行する際の作業の流れ
- 25. 25Copyright © 2016 NTT DATA Corporation
移行前後のAP資材比較(資材の関連)
Application
Layer
Domain
Layer
Infrastructure
Layer
struts-config.xml
validation.xml
ActionForm
sqlMa
p.xml
for MyBatis2
sqlMa
p.xml
for MyBatis3
MyBatis2
Business Logic
Struts
MyBatis3
Business Logic
Form Bean
(Bean
Validation)
Controller
Spring
MVC
JSP
with struts.tld
JSP
with JSTL, spling.tld
Struts 1.x(+Spring / MyBatis2) Spring MVC
Action
applicationContext.xm
l
- 26. 26Copyright © 2016 NTT DATA Corporation
移行前後のAP資材比較(資材の対応)
Application
Layer
Struts 1.x
Domain
Layer
Infrastructure
Layer
Spring MVC
validation.xml
ActionForm
Form Bean
(Bean Validation)
Controller
サービスIF
業務
サービス
業務
サービス
sqlMap.xml
for MyBatis2
sqlMap.xml
for MyBatis3
リポジトリIF
struts-config.xml
JSP
with struts.tld
JSP
with JSTL, spling.tld
概要
validation.xmlで定義する入力チェックを、
BeanValidationに移行。
・struts-config.xml等の設定を
@RequestMapping に移行。
・Actionの個々の処理をSpringMVCに合わせて
移行。
・Controllerに対するI/Fに変更。
・DAOのI/FをリポジトリIFに変更。
・その他実装は基本そのまま。
sqlMap.xmlのSQL定義をIFメソッドとして移行
する。
MyBatis2 からMyBatis3へ記法を移行する。
strutsのタグライブラリを、
JSTLやSpringタグライブラリに移行。
Action
サービスIF
applicationContext.xm
l
- 27. 27Copyright © 2016 NTT DATA Corporation
Application
Layer
Struts 1.x
Domain
Layer
Infrastructure
Layer
validation.xml
ActionForm
業務
サービス
sqlMap.xml
for MyBatis2
struts-config.xml
JSP
with struts.tld
Action
サービスIF
applicationContext.xm
l
移行のしやすさ
Spring MVC
Form Bean
(Bean Validation)
Controller
サービスIF
業務
サービス
sqlMap.xml
for MyBatis3
リポジトリIF
JSP
with JSTL, spling.tld
概要
○:
struts標準は汎用的に対処しやすい。
プロジェクト独自作成部分は個別対処。
×:
プロジェクト独自の要素が強いことが多く、
対処しにくい。
設定ファイルの内容を機械的に移植することは
可能だが、Action内の独自処理をそのまま移せ
るかどうかは要検討。
△:
元々レイヤリングされている状態ならば対処し
やすい。大半のロジックをそのまま流用するよ
うな工夫は必要。
○:
struts標準タグは汎用的に対処しやすい。
プロジェクト独自作成部分は個別対処。
△:
移行前後のライブラリによって難易度が変わる。
- 29. 29Copyright © 2016 NTT DATA Corporation
移行を実施するにあたって
• 基本的な考え方
• strutsにあって、spring mvcにない
• 場合によっては仕様変更を検討しつつ対処する。
• 対処漏れが起きにくい。
• strutsにあって、spring mvcにある
• 完全一致ではなく、微妙に違う仕様/挙動になることが多い。
• Struts と Spring MVC はアーキテクチャは似てるけど異なるもの。
• 両方共ActionベースのWebAPフレームワークではある。
• 差を意識しながら扱う必要がある。
以降、実際に起きた問題の一例を紹介します。
• アーキテクチャの差によるもの
• 機能差によるもの
- 30. 30Copyright © 2016 NTT DATA Corporation
セッション/リクエスト格納データの取得方法の違
い
発生した問題
• 画面表示したかったセッションスコープのデータが リクエストスコープの別
のデータに置き換わって表示されてしまった。
• requestスコープの値だけを更新したつもりが、同時にsessionスコープの変数
も更新されてしまい不整合なデータが表示されてしまった。
発生条件
• Struts1では、requestスコープとsessionスコープで同じキー名で異なる
データを
使用している。
• Spring MVCへActionFormを移行する際に、
@ModelAttributes、@SessionAttributesを使用している。
result: fuga
requestスコープ
業務AP
sessionスコープ
result=hoge
result=fuga
画面(JSP->HTML)
画面へ出力
期待していなかった、
値が表示されてしまった
イメージ
- 31. 31Copyright © 2016 NTT DATA Corporation
セッション/リクエスト格納データの取得方法の違
い
Struts1
• リクエスト
• ActionForm(scope=request)
• セッション
• ActionForm(scope=session)
Spring MVC
• リクエスト
• @ModelAttributes、@QueryParam、@RequestAttribute(Spring 4.3~)、etc...
• セッション
• @SessionAttributes、Session Scoped Bean、@SessionAttribute(Spring 4.3~)
@ModelAttributesや
@SessionAttributesを
使用した場合の話
- 32. 32Copyright © 2016 NTT DATA Corporation
Model
セッション/リクエスト格納データの取得方法の違
い
Struts1
Spring MVC
HttpServlet
Request
HttpSession
ActionForm1
(request版)
HttpServlet
Request
HttpSession
Spring MVC
ActionForm1
(session版)
リクエスト・セッション格納データの入力フロー
Application2
(Action)
Application1
(Action)
Application2
(Controller)
Application1
(Controller)Form
Object1
ActionFormとScopeが
明確に分かれており、
同名ActionFormでも
別物として管理される
FormObjectのScopeの違いは
アプリケーションからは透過的な思想なため
同名キーのリクエストとセッションのデータ
が
同一FormObjectにマッピングされてしまう
Struts1
Application2で取得したいデータ
- 33. 33Copyright © 2016 NTT DATA Corporation
セッション/リクエスト格納データの取得方法の違
い
Struts1
Spring MVC
リクエスト・セッションへのデータ出力フロー
JSP
(request出力)
Struts1
Taglibs
JSP
(session出力)
Struts1
Taglibs
HttpServlet
Request
HttpSession
ActionForm1
(session版)
Application2
(Action)
Struts1
ModelHttpServlet
Request
HttpSession
Spring MVC
Application2
(Controller)
Form
Object1
専用のTaglibsを使用することで、
同名のActionFormに対しても
scopeを指定してActionFormを選択可
能
JSP
(request出力)
JSP
(session出力)
格納先に問わず、画面表示するデータは
リクエストスコープを経由して画面描画
に
使用する思想のため、
リクエストスコープで画面表示データが
元々存在した、偶然に同名キーのリクエストデータ
セッションへ格納しつつ
画面出力したいデータ
- 34. 34Copyright © 2016 NTT DATA Corporation
Model
セッション/リクエスト格納データの取得方法の違
い
Spring MVC
HttpServlet
Request
HttpSession
Spring MVC
本問題への解決方法
Application2
(Controller)
Application1
(Controller)Form
Object1
Application2で取得したいデータ Form
Object2
ModelHttpServlet
Request
HttpSession
Spring MVC
Application2
(Controller)
Form
Object2
JSP
(request出力)
JSP
(session出力)
元々存在した、偶然に同名キーのリクエストデータ
セッションへ格納しつつ
画面出力したいデータ
各業務処理で使用するFormObjectを洗い出し、
FormObjectの名前(キー名)を、
業務処理毎にユニークな名前に定義しなおす。
@ModelAttributes(“formObject2”)
@SessionAttributes(“formObject2”)
各業務処理で使用するFormObjectを洗い出し、
FormObjectの名前(キー名)を、
ユニークな名前に定義しなおす。
@ModelAttributes -> @ModelAttributes(“formObject2”)
@SessionAttributes -> @SessionAttributes(“formObject2”)
- 35. 35Copyright © 2016 NTT DATA Corporation
リクエストスコープへのデータ反映タイミングの
違い
発生した問題:
• 1リクエストで複数のビジネスロジックを呼び出した際、前段のビジネスロジック
の処理結果が引き継げない。
発生条件
• Struts1で、複数Actionをチェインし複数ビジネスロジックを実行していた
• Struts1では同じActionFormを複数Action間で共有することができる
イメージ
result1:
result2:
result3: piyo
Request scope
result2=fuga
result1=hoge
画面(JSP->HTML)
最後にチェインしたビジネスロジックからの
出力結果しか画面に表示されない
Action1
result3=piyo
Action2 Action3request
response
- 36. 36Copyright © 2016 NTT DATA Corporation
リクエストスコープへのデータ反映タイミングの
違い
Struts1
• 1リクエストで複数のビジネスロジックを実行させる方法
• Actionを<forward>でチェイン
• リクエストスコープのActionFormに
画面表示データを格納
Spring MVC
• 1リクエストで複数のビジネスロジックを実行させる方法
• Controllerをforwardでチェイン
• Modelに画面表示データを格納
今回行っていた方法
<action path="/result1
type=“com.example.HogeAction"
name=“hogeActionForm"
scope="request">
<forward name="success" path="/result2"/>
</action>
<action path="/result2 ...
@RequestMapping(“/result1”)
public String result1() {
// ...
return “forward:/result2”;
}
@RequestMapping(“/result2”)
public String result2()...
- 37. 37Copyright © 2016 NTT DATA Corporation
リクエストスコープへのデータ反映タイミングの
違い
Struts1
Spring MVC
リクエストへのデータ出力フロー
画面出力したいデータは、Action内で
ActionFormに累積して格納
Action1Struts Action2 Action3
ActionFormreq.setAttribute()
Controller1Spring Controller2 Controller3
リクエストス
コープ
Model
forward
forward
forward
forward
Model
model.addAttribute()
model.addAttribute()
Model
model.addAttribute()
forward
req.setAttribute()
JSP
JSP
view resolvereq.setAttribute()
Modelからリクエストスコープへのデー
タ反映のタイミングはViewの解決時のみ
+ModelがForward毎に初期化されるため、
Forwardチェイン時にデータが消失する
(BindingResultも同様)
原因
- 38. 38Copyright © 2016 NTT DATA Corporation
Model
リクエストスコープへのデータ反映タイミングの
違い
Spring MVC
本問題への解決方法
ControllerSpring Module2 Module3
リクエス
トスコー
プ
model.addAttribute()
model.addAttribute()
model.addAttribute()
JSP
view resolvereq.setAttribute()
Forwardでチェインさせる方式をやめ、
1Controller内でModelやBindingResultを
持回るようにメソッドコールする
Method call
Method call
Module1
Method call
Spring MVCではforwardによるチェインは一般的ではないことを考慮し、
複数ビジネスロジックの呼び出し方法を変える必要があった。
- 39. 39Copyright © 2016 NTT DATA Corporation
その他、個別機能で発生した問題の一例
• Spring MVCではStruts1のTransactionTokenに代わる機能がないた
め、一部の画面遷移の挙動が変わってしまった。
TERA5で同等の機能を用意したため、現行と同様の遷移を維持した。
http://terasolunaorg.github.io/guideline/5.2.0.RELEASE/ja/ArchitectureInDetail/WebApplicationDetail/DoubleSubmitProtection.html
- 40. 40Copyright © 2016 NTT DATA Corporation
• 入力チェックがstruts-validator(commons-validator)から
Spring Validator(Bean Validator)に変更する際に、対応しにくい
チェックルールが見つかった。
• 正規表現
• Struts 1 : mask / Bean Validation : @Pattern
• 空文字(“”)はチェックの対象外→対象となってしまう。
• 同じ挙動にするため、正規表現の先頭に |を記載した。 例:@Pattern(regexp = "|^[a-z]+$")
• 日本語用の独自チェックルール
• 各プロジェクトでcommons-validatorの拡張ルールを実装している事が
多い
• TERA5が用意した文字列チェックアノテーション(@ConsistOf)を活用
し、
特定のコードポイント集合に含まれることをチェックするようにした
(※1)
• ただし、プロジェクトによってはユーザーから受け付ける値の仕様が
変わるため、既存のチェックルールをそのまま流用して、
BeanValidation経由でコールするようにしたケースもあった。
※1: 詳細は、以下を参照
7.6.2.5.5. Bean Validationと連携した文字列チェック
http://terasolunaorg.github.io/guideline/5.2.0.RELEASE/ja/ArchitectureInDetail/GeneralFuncDetail/Str
ingProcessing.html#stringprocessinghowtousecodepointsvalidator
- 42. 42Copyright © 2016 NTT DATA Corporation
まとめ
• 移行プロジェクトでは独特なスキルが必要になる。
• プロジェクト特性に合わせた開発プロセスを考え、
影響範囲を局所化できるかどうかがポイントになる。
• ソースの対応を取りながら移していく。
移行前後の差を都度検証しながら進めていくことが大事。
現行をそのまま再現しようとすると、
アーキテクチャや機能の差が出てきて当たり前。
• 小規模な移行案件からナレッジをためていく地道な作業が一番効
果的。
- 43. 43Copyright © 2016 NTT DATA Corporation
最後に
今回の話やTERASOLUNAに興味がある方は下記までご連絡くだ
さい
TERASOLUNA窓口
E-mail: terasoluna@am.nttdata.co.jp
電話: 050-5546-2482(平日10時〜18時)
今後もSpringを中心に各種OSSの
ベストプラクティスを提供し続けます
Springをエンタープライズシステム開発で積極的に活用
し、
情報交換やコミュニティ活動を活発化して
さらなるSpringの発展、繁栄に向けて共に歩んでいきま
しょう。
- 44. Copyright © 2011 NTT DATA Corporation
Copyright © 2016 NTT DATA Corporation
「TERASOLUNA」及びそのロゴは、日本及びその他の国おける株式会社NTTデータの商標または登録商標です。
その他、記載されている会社名、商品名、サービス名等は、各社の商標または登録商標です。