Upload
mitsuru-ogawa
View
10.953
Download
5
Embed Size (px)
DESCRIPTION
2013/11/09 JJUG CCCでの発表資料です。
Citation preview
メンテナンス性の良いWebシステムを構築するために
Javaとフロントエンドでやるべきこと
2013/11/09 JJUG CCCHTML5jエンタープライズ部
小川充(@mitsuruog)
photo credithttp://www.ashinari.com/2013/09/06-381684.php
自己紹介
小川充(おがわみつる)
株式会社クレスコ 技術研究所
フロントエンジニア
・HTML5jエンタープライズ部 運営メンバー
・OSSドキュメント翻訳コミュニティ enja-ossメンバー
・Github:https://github.com/mitsuruog
・Twitter:https://twitter.com/mitsuruog
進化し続けるフロントエンド技術と
システム開発の現場をいかに融合させるか!
業務システムエンジニア目線で活動しています。
はじめに
サーバサイドにはうるさい業務系フロントエンジニアです。
2013/09/09にHTML5jエンタープライズ部とJJUGと共催で
「Web×Java」をテーマに勉強会を企画、開催しました。
業務系WebアプリケーションがStrutsから旅立つ日
http://www.slideshare.net/mitsuruogawa33/webstruts
「業務系システムは今すぐ脱Strutsを!」業務システムエンジニアのためのHTML5勉強会#04 活動報告
http://gihyo.jp/news/report/2013/09/1901
はじめに
話さないこと
・クライアントMV*系フレームワークの詳細
・Javaサーバ側実装の詳細
・CSS(←Webのメンテナンス性を語る上では重要な要素 )・JSF1.X・Richfaces、Primefaces・Scala、Groovy
昨今、UIがリッチになるに従い、サーバ側で実装されていたものがフロント側でも実装されるようになってきました。
その際にWebシステムのメンテナンス性の上で大切なことは、フロント側とサーバ側の役割分担を明確にし、影響しあう部分を局所化すること。
これからのJavaでのWeb開発において、フロント側とサーバ側の役割をどのように考えれば良いかお話します。
1.画面構築方式とアンチパターン
なぜ画面構築方式なのか?
・フロント側のロジックのほとんどは画面構築に関するもの。
・Ajaxの登場以来、画面の部分更新が多く行われるようになり、画面構築方法が複雑
化し、フロント側の実装量が増えてきた。
・画面構築の部分が、最もサーバ側との機能重複が発生しやすい箇所。
画面構築方式(従来型・画面遷移方式)
・画面はサーバ側で生成。
・レスポンスはHTMLベース
Contoller
HTML
View
Model
テンプレート
ロジック
Ajaxで画面を部分更新し始めると危険なパターン(よくある)
HTML
フロントエンド サーバサイド
画面構築方式(次世代型・REST API方式)
・レスポンスはJSONベース
・画面はフロント側で生成(データバインディング)
Contoller
View
Model Model
HTML
Contoller(View)
テンプレート
ロジック
サーバ側で画面を部分構築し始めると危険なパターン(あまりない、要員スキルなど途中で妥協した場合などに起こる。)
JSON
フロントエンド サーバサイド
VM*系フレームワーク
画面構築方式(まとめ)
・2つの方式も混ざり合わない間は問題ない。
・2つの方式が混ざり合う部分で機能的な重複が起こる。
・混ざり合う部分での方針やルールが定まっていない場合に混乱が起こり、機能重複
が起こる。
2.フロントエンドの役割とは何か?~Javascriptの場合~
フロントエンドの役割(従来型)
DOM操作(アニメーション)
Ajax
フロントエンド役割があまりなかった時代
フロントエンドの役割(次世代型)
テンプレートエンジン
MV*系フレームワーク
DOM操作(アニメーション)
Ajax
テンプレート
リソース同期
構造化
JAX-RSの場合はこの構成
フロントエンドの役割(JSFの場合)
DOM操作(アニメーション)
Ajax
テンプレート
リソース同期
構造化
JSF
サーバサイドに大きく依存しておりフロントとの役割分担の見極めが難しい
(アンチパターン)
フロントエンドの役割(まとめ)
・フロントエンドが求められる役割は主に5つ。(DOM操作、Ajax、テンプレート、データ同期、構造化)
・JSFの場合は、フロントエンドとの役割分担の見極めが難しくアンチパターンに陥りやすい。
3. JAX-RS、JSF(2.0+)それぞれとの組み合わせ方
~フロントエンド組み合わせの留意事項~
JAX-RSの場合
・画面構築方式は次世代型。画面はフロント側で生成。
・JAX-RSはREST仕様に則ったWebAPIが容易に作成可能。
例)サーバ側REST実装例
@RequestScoped@Path("hoge")public class HogeResource { @GET @Path("product") @Produces(MediaType.APPLICATION_JSON) public Product getProduct() { Product product = new Product(); product.setId(1); product.setName("Mattress"); product.setDescription("Queen size mattress"); product.setPrice(500); return product; }}
ルーティング、JSONシリアライズが直感的
呼び出すURLhttp://localhost:8080/web_root/webresources/hoge/product
JAX-RSの場合
・サーバとのREST API呼び出しを隠蔽するようなJavascriptMV*系F/Wと相性がよい。(個人的にはBackbone.js、Anguler.js推奨)
Java側の実装(URLは「hoge/product」)
@RequestScoped@Path("hoge")public class HogeResource { @GET @Path("product") @Produces(MediaType.APPLICATION_JSON) public Product getProduct() { Product product = new Product();
//省略
return product; }}
フロント側実装 (Backbone.js)
var Model = Backbone.Model.extend({ url: 'webresources/hoge/product'});var View = Backbone.View.extend({ initialize: function() { this.model = new Model(); this.model.fetch(); this.render(); //画面の再構築
}, render: function(){
//省略
}});//Viewの初期化
new View();
fetch()呼び出し時にGETリクエストを投げる受信後、F/W側で勝手にModelのデータを更新する
(Backbone.sync)
JAX-RSの場合(その他留意事項)
・フロント側に実装量が増えるため、JavascriptMV*系F/Wでの構造化が必須。
・フロント側にテンプレートエンジンが必要。
・初期表示時に表示データ取得用の余計なリクエストが1回飛ぶ。
(これをどう捕らえるか次第…)
・本格的にフロントエンジニアの参画が必要。
<f:ajax>でJavascriptを記述することなくAjax呼び出しが可能
JSF(2.0+)の場合
・画面構築方式は基本的に従来型。
・画面構築はサーバ側。Ajax通信時もサーバ側で画面構築する。
・Ajaxでの画面部分構築は<f:ajax>を使用すること。
例)Ajax入力チェック「JSF側」
<h:form id="form"> <h:inputText id="name" value="#{user.name}" validator="#{user.validateName}"> <f:ajax execute="name" render="nameError" event="blur" /> </h:inputText> <h:message for="name" id="nameError" style="color: red"/></h:form>
サーバ側のロジック
JSF(2.0+)の場合
・jQueryなどから画面部分更新したいケースは、JSFライブラリのAjax通信機能を使用すること。
⇒画面構築部分はJSFの影響力が強すぎるため、テンプレートとAjax部分は割り切って任せたほうが良い。(後述)
jQueryからフックする例)
$(document).on('click', '#form\\:validate', function(e) { jsf.ajax.request(e.target, e, { execute: 'form:name', render: 'form:nameError' }); e.preventDefault();});
正直、書き方が気持ち悪いw
そもそも、無理にフックする必要ない。そうなるようであれば設計を見直した方がいいかも。
JSF(2.0+)の場合
・JSFが持つ、テンプレートとUIコンポーネント化の仕組みが優秀。
⇒UIのコンポーネント化にTaglibのように面倒な手続きが不要。
・<f:metadata>の登場により、GETパラメータの扱いが容易になった。
UIテンプレート化<ui:insert>と<ui:define>
UIコンポーネント化<composite:interface>と<composite:implementation>
GETリクエストとの親和性向上<f:metadata>と<f:viewParam>
JSF(2.0+)の場合(その他留意事項)
・(注意)JSFのAjax通信のレスポンスはXML形式で、かつ独自色が強い。
例)先ほどの入力チェック時に返ってきたレスポンス
<?xml version='1.0' encoding='UTF-8'?><partial-response id="j_id1"> <changes>
<update id="form:nameError"> <![CDATA[<span id="form:nameError" style="color: red">必須入力です</span>]]> </update> <update id="j_id1:javax.faces.ViewState:0"> <![CDATA[8183146577291182963:-4484956516055255891]]> </update>
</changes></partial-response>
部分的なHTMLが返ってくる。
レスポンスを受けて、自前で何かしようとか思わないほうがいい。
JSF(2.0+)の場合(その他留意事項)
・サーバ側の依存度が高いため、Javascriptとの役割分担が難しい。
⇒むしろ、フロントエンドの出番はあまりない(ようにするべき)。
・JavascriptMV*系F/Wとの組み合わせるべきではない。
・Javascriptライブラリ選定はJSFと機能の包含関係を考慮して行うべき。
4.まとめ
まとめ(JAX-RS)
・サーバ側の役割はREST APIに徹する。
・フロント側の役割はテンプレートと画面構築を担う。
・別途、JavascriptMV*系F/Wなどで構造化が必須。
長所
・基本的にどんなUIにも対応可能。
・フロントエンドの分業が可能。
・様々なJavascriptMV*系F/Wやライブラリが選択可能。
・JSONベースの小さいデータのやり取りが主流であるため、通信環境の悪いモバイルに適している。
短所
・フロントエンジニア的にはないw。
・気をつけないと、 Javascriptがメモリリークしやすい。
・規模や難易度に見合うフロントエンジニアの調達・教育が課題。
まとめ(JSF2.0+)
・フロントエンドとの役割分担を見極めれば、非常に優秀はWebフレームワーク。
・JSFのテンプレートとAjax通信機能をフルで使う前提で設計するべき。
・むしろフロント側の役割は多く持たせるべきではない。
・JavascriptMV*系F/Wとの組み合わせるべきではない。
長所
・Javaエンジニアのみで、ある程度リッチな Webシステムを安全に構築可能。
・JSFの<f:ajax>タグを使っている範囲であれば、 Javascriptを意識する必要はない。
・テンプレート、UIコンポーネント化機能が優秀で、 UIの再利用性が高くなる。
短所
・リッチなUIには向かない。
・HTML/XMLベースのやり取りが主流であるため、モバイル環境には適していない場合がある。
・安易にAjaxの部分更新ができるため、更新する範囲のコントロールに注意が必要。
・フロントエンジニアにアンチファンが多い。
ご静聴ありがとうございました!
2013/11/09 JJUG CCCHTML5jエンタープライズ部
小川充(@mitsuruog)
photo credithttp://www.ashinari.com/2007/05/07-002031.php