[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
SlideShare a Scribd company logo
メンテナンス性の良い
Webシステムを構築するために
Javaとフロントエンドでやるべきこと

2013/11/09 JJUG CCC
HTML5jエンタープライズ部
小川充(@mitsuruog)
photo credit
http://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
はじめに
昨今、UIがリッチになるに従い、サーバ側で実装されていたものがフロント側でも
実装されるようになってきました。
その際にWebシステムのメンテナンス性の上で大切なことは、フロント側とサーバ側
の役割分担を明確にし、影響しあう部分を局所化すること。
これからのJavaでのWeb開発において、フロント側とサーバ側の役割をどのように
考えれば良いかお話します。
話さないこと
・クライアントMV*系フレームワークの詳細
・Javaサーバ側実装の詳細
・CSS(←Webのメンテナンス性を語る上では重要な要素 )
・JSF1.X
・Richfaces、Primefaces
・Scala、Groovy
1.画面構築方式とアンチパターン
なぜ画面構築方式なのか?
・フロント側のロジックのほとんどは画面構築に関するもの。
・Ajaxの登場以来、画面の部分更新が多く行われるようになり、画面構築方法が複雑
化し、フロント側の実装量が増えてきた。
・画面構築の部分が、最もサーバ側との機能重複が発生しやすい箇所。
画面構築方式(従来型・画面遷移方式)
サーバサイド

フロントエンド

Model

Contoller

HTML
テンプレート

View

ロジック

HTML

・画面はサーバ側で生成。
・レスポンスはHTMLベース

Ajaxで画面を部分更新し始めると危険なパターン
(よくある)
画面構築方式(次世代型・REST API方式)
サーバサイド

フロントエンド
VM*系フレームワーク
Contoller
(View)

Model

Contoller
JSON

HTML

View

テンプレート
ロジック

・レスポンスはJSONベース
・画面はフロント側で生成(データバインディング)

サーバ側で画面を部分構築し始めると危険なパターン
(あまりない、要員スキルなど途中で妥協した場合などに起こる。)

Model
画面構築方式(まとめ)
・2つの方式も混ざり合わない間は問題ない。
・2つの方式が混ざり合う部分で機能的な重複が起こる。
・混ざり合う部分での方針やルールが定まっていない場合に混乱が起こり、機能重複
が起こる。
2.フロントエンドの役割とは何か?
~Javascriptの場合~
フロントエンドの役割(従来型)
DOM操作
(アニメーション)

Ajax

フロントエンド役割があまりなかった時代
フロントエンドの役割(次世代型)
DOM操作
(アニメーション)

Ajax
テンプレートエンジン
テンプレート

リソース同期
MV*系フレームワーク

構造化

JAX-RSの場合はこの構成
フロントエンドの役割(JSFの場合)
DOM操作
(アニメーション)

Ajax

テンプレート

リソース同期

JSF

構造化

サーバサイドに大きく依存しており
フロントとの役割分担の見極めが難しい
(アンチパターン)
フロントエンドの役割(まとめ)
・フロントエンドが求められる役割は主に5つ。
(DOM操作、Ajax、テンプレート、データ同期、構造化)
・JSFの場合は、フロントエンドとの役割分担の見極めが難しくアンチパターンに陥りや
すい。
3. JAX-RS、JSF(2.0+)
それぞれとの組み合わせ方
~フロントエンド組み合わせの留意事項~
JAX-RSの場合
・画面構築方式は次世代型。画面はフロント側で生成。
・JAX-RSはREST仕様に則ったWebAPIが容易に作成可能。
例)サーバ側REST実装例

ルーティング、JSONシリアライズが直感的

@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;
}
}

呼び出すURL
http://localhost:8080/web_root/webresources/hoge/product
JAX-RSの場合
・サーバとのREST API呼び出しを隠蔽するようなJavascriptMV*系F/Wと相性がよい。
(個人的にはBackbone.js、Anguler.js推奨)
フロント側実装 (Backbone.js)

Java側の実装(URLは「hoge/product」)

@RequestScoped
var Model = Backbone.Model.extend({
@Path("hoge")
url: 'webresources/hoge/product'
public class HogeResource {
});
@GET
var View = Backbone.View.extend({
@Path("product")
@Produces(MediaType.APPLICATION_JSON)
initialize: function() {
public Product getProduct() {
this.model = new Model();
Product product = new Product();
this.model.fetch();
this.render(); //画面の再構築
//省略
},
render: function(){
return product;
}
//省略
}
}
});
fetch()呼び出し時にGETリクエストを投げる
//Viewの初期化
受信後、F/W側で勝手にModelのデータを更新する
new View();

(Backbone.sync)
JAX-RSの場合(その他留意事項)
・フロント側に実装量が増えるため、JavascriptMV*系F/Wでの構造化が必須。
・フロント側にテンプレートエンジンが必要。
・初期表示時に表示データ取得用の余計なリクエストが1回飛ぶ。
(これをどう捕らえるか次第…)
・本格的にフロントエンジニアの参画が必要。
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>

サーバ側のロジック

<f:ajax>でJavascriptを記述することなくAjax呼び出しが可能
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'
正直、書き方が気持ち悪いw
});
e.preventDefault();
そもそも、無理にフックする必要ない。
});
そうなるようであれば設計を見直した方がいいかも。
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>

部分的なHTMLが返ってくる。

<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>

レスポンスを受けて、自前で何かしようとか思わないほうがいい。
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 CCC
HTML5jエンタープライズ部
小川充(@mitsuruog)
photo credit
http://www.ashinari.com/2007/05/07-002031.php

More Related Content

メンテナンス性の良いWebシステムを構築するためにjavaとフロントエンドでやるべきこと