Playとの激しい戦いの第4週がありました! フレームワーク2.1 + Java。 勝利は容赦なく近づいていましたが、完全な降伏には程遠いものでした。Play!の開発に関するニュースを奨励した後 2.1、たとえば
LinkedInでは、1つの新しいプロジェクトで試してみることにしました。 いわば、ビジネスでそれをテストすることです。 何から来たの? 私とPlayの間の小さな戦争だったと思います! 2.1。 なんで? カットの下の詳細が、せっかちな人のために:
簡単な結論
攻撃のために、コードネームScalaと呼ばれる秘密の武器を取る必要がありました。 Playに直面した場合! フレームワーク2.1と「あなたはScalaフレームワークです!」と大声で叫んでください。そうすれば、彼はそのような直接性を恐れ、大きなチャンスの世界への扉をささやかに開けます。「Scalaを知らない?」-「Play 1.2を使用する」
「Scalaに精通していますか?」-「Play 2.1を試してみてください。 しかし、まだ我慢してください。
背景
剣と盾を備えたマウスとキーボードを使って7年間、私は惑星ジャワのさまざまな国を訪れました。 これらはエンタープライズの古代遺跡であり、生命はまだ暖かく、咲いているスプリングランド、彼の家臣であるグラヴィランディアとグライルス市の首都、かつては先進的でエキゾチックなPleiterra Pervoe、そして他の多くの州、都市、さらには遠隔地でした。 しかし、Pleiterra IIでのキャンペーンは予想外に困難でした。約9か月間、私はPlay 1.2.xを使用して1つのプロジェクトに取り組みました。 Spring Framework 3の後でも、これは巨大なJava EE 5 + JSFは言うまでもなく、開発のスピードと容易さの頂点のように見えました。
その後、短い休憩があり、Grails 2.xを3か月間集中的に使用して、JavaがGroovyに比べて利便性と構文機能の点でどの程度遅れているかを理解しました。 そして、そのGrailsは、純粋なSpring Framework 3 + Javaよりも開発がやや簡単で高速です。
しかし、新しいプロジェクトのフレームワークを選択する時が来ました。その選択はPlay 2.1に落ちました。 これは正しい決断でしたか? 確かに興味深いが、正しいもの-それはまだ時間を表示します。
それまでの間、Play 2.1での作業の印象を共有したいと思います。 Play 1.2.xとの多くの比較があり、Javaと感情についてうめきます。 コードはほとんどなく、一般に受け入れられている用語や概念はロシア語に翻訳されません。 たとえば、
ステートレスフレームワーク 。
印象
ドキュメントの欠如
プレイテールIIの支配者によって提供されたマップは、完全にはほど遠いものでした。 主要道路は非常に正確に示されていますが、これらの道路の周りは通れません。 迷わないようにするために、私は地元の人々をつかみ、彼らに多くの質問をしなければなりませんでした。 ところで、彼らはとても喜んで答えました。公式文書はかなりけちです。
Play 2 with Javaと
Play 2 with Scalaの 2冊の本があります。 最初のJavaについては、初心者向けのコメント付きの公式ドキュメントをほぼ繰り返しています。 2番目のScalaについては、もう少し便利で、たとえば、第8章JSONを使用した単一ページのJavaScriptアプリケーションの作成など、必要なトピックをカバーしています。
もちろん、大規模で活発なコミュニティが
あります 。Googleグループと
Stackoverflowの両方で助けを求めたり、質問をしたりでき
ます 。 しかし、一見単純な質問に対する答えを常に探す必要がある場合、開発の喜びはいくらか失われます。
ドキュメントの改善にも参加しました(
こちら )が、さらに詳しく説明したい場所がまだたくさんあります。
Play 1.2.xでは、ドキュメントはより完全で便利になりました。 StackoverflowとGoogleグループでの検索には、本当に珍しいことしかありませんでした。
コンパイル速度
ここの道路は理想からかけ離れています。 時々私は何時間も走り、泥にandれ、あきらめずに速く走るように馬に懇願しました。 大軍の移籍には非常に長い時間がかかります。 どこでもチェックポイントとチェックの道路。多くの人にとって、これはニュースではありませんが、ここでのコンパイルは遅いです。 Play 1.2.xよりもはるかに遅い。 ここでは、単純なJavaクラスからScalaテンプレートやコーヒースクリプトまで、ほとんどすべてがコンパイルされることを理解しています。 しかし、これは長い時間です。 正気のエラーメッセージが発行されますが、これは長い時間です。 超高速の理想的な
ヒットリフレッシュワークフローは失速し、迷惑です。
データベースを操作する
有名な居住者は、要塞を独立して構築する方法を知りません。 彼らは言うことはできません:「別の塔を建てますが、すぐに!」。 いや 彼らには詳細な計画が必要です。組み込みのデータベース進化エンジンがあります。 ただし、これらのスクリプトの生成には問題があります。 Ebeanは完全なスクリプトを作成できますが、インクリメンタルスクリプトにはすでに問題があります。 残念ながら、Ebeanのアナログ
jpa.ddl=update
は見つかりませんでした。 誰かが私に言ったら、私は非常に幸せになります。
LiquiBaseのDiffのアナログまたは適応も非常に役立ちます。
雇われた採餌者は見知らぬ男であることが判明した。 うまくいくように見えますが、供給の中断を常に待っています。概念としての
Ebeanは非常に優れています。 主な利点:
- セッションの欠如(Session、EntityManagerなど)。これはステートレスフレームワークに適しています。 ただし、そのため、パーシステントコンテキストがあります。
- より効率的なクエリを作成するための部分オブジェクトのサポート。
物議を醸す問題:
- 部分的な JPAサポート。 このサポートが終了する場所を正確に知り、理解する必要があります。
- ドキュメントの不足と使用例。
- Hibernateほど活発な開発ではなく、コミュニティの規模も大きくありません。
ここにもトランザクションがあります。 コントローラメソッドを
@Transactional
としてマークすることもでき
@Transactional
。 ただし、コントローラーメソッドまたはコントローラー自体のみです。 サードパーティのクラスの場合は、これを自分で処理する必要があります。
一般的に、Ebeanは非常に興味深いライブラリであり、HibernateまたはJPAよりも単純で理解しやすい場合もありますが、成長中のプロジェクトのすべてのニーズを満たす十分な可能性があることを疑うことはありません。
もちろん、標準のJPAを使用できますが、Play 1.2.xの
Model.find("byName", name)
または
Spring Data JPA 1との統合はありません。 数年前に戻ってきたような気がします。
ところで、Ebeanにはいくつかの重大な欠点があります
。EbeanORMの
使用ページの
警告セクションでそれらについて詳しく読むことができます。 また、クラスにそのような手書きメソッドが少なくとも1つある場合、Play 2.1はgetter / setterの生成を停止するため、
get
または
set
始まるメソッドの名前を避ける必要があります。 getterの場合、
get
という単語を省略して、
byEmail
または
byEmail
を呼び出し
byEmail
。
しかし、
PagingListはステートレスフレームワークには適用されないため、Ebeanの
キラー機能と言っても
過言ではありません。 ああ、ああ。
NoSqlデータベースの操作に関しては、Elasticsearch、MongoDB(数個でも)、OrientDBのプラグインを簡単に見つけることができます。 私は自分で使ったことがないので、これらのプラグインの品質については何も言えません。
テスト中
軍隊の状態を確認することは、敵のスパイによって常にイライラします。 地元の動物は運動の組織を妨害します。サルはココナッツを投げ、ツタは足を組み、時には神風のスカンクが見つかります。モデルの単純な単体テストからコントローラーのテスト、Seleniumの使用まで、多くの可能性があります。
私のテストでは、ドキュメントに記載されているようにメモリ内データベースを使用しようとしました。
@Before public void setUp() throws Exception { start(fakeApplication(inMemoryDatabase(""))); }
しかし、私にはすぐに2つの問題がありました。大小です。
小:テストでトランザクションを処理する方法 SpringやGrailsの
@Transactional
ようなものは見つかりませんでした。 テストでトランザクションを開いてロールバックするだけです。 不便で未熟。
大きな問題:メインベースがMySqlであるという事実と、インメモリH2テストの競合。 そのため、H2はMySqlの進化スクリプトを理解することを拒否しますが、次のようなデフォルト以外のデータベース構成を使用します。
start(fakeApplication(inMemoryDatabase("login-test")));
構成を指定せずに
save()
メソッドを使用すると、データの保存先が不確実になります。
私はこの問題の解決策について漠然とした説明を見てきましたが、そこには単純さはありません。
テストでデータベースの作業を整理する方法に関する公式文書には何も記載されていません。
良いの。 ソースコードを変更するたびに機能する便利なコマンド
~test
または
~test-only
があります。 テストの実行に必要な時間を節約します。
セキュリティ
ステートフォージには最も単純な鎧しかありません。 職人はもっと良いものを作ります。承認および認証機能はPlay 1.2.xのままでした。
@With
アノテーション付きの
アクションコンポジションがあり、
Security.Authenticator
とその使用方法の良い例があります:
認証ページの
追加、認証システムの実装セクション。
サードパーティのプラグインはより多くの機能を提供します。 たとえば、
Deadboltまたは
SecureSocialですが、小さなプロジェクトにはあまりにも
きつすぎるように思えたので、手書きの認証を完全に管理しました。
ところで、これは驚くべきことですが、Play 2.
0は Authenticity Tokenなどの便利な機能を失いましたが、失われた能力を補う
サードパーティのプラグインがあります。 ただし、Play 2.1では、バージョン2.1のプレスリリースで言及されているが、ドキュメントがほとんどない
filters
がいくつか追加されました。
CSRFFilter
だけに言及されたフィルターの中で。 彼について見つかった唯一のことは、ScalaでCSRFフィルターを使用する方法を説明するこの
投稿です。 Play 2.1 + Javaに適用する方法と適用するかどうかは、まだ把握する必要があります。
不安定性
途中で気楼に出くわすこともありました。 彼らが近づくと、彼らは姿を消した。 マップには奇跡はありませんでした。数回、完全に機能するコードが機能しなくなりました! どうやら、ゲッター/セッターのコンパイルと生成が常に正しく動作するとは限りません。
play clean
、プロジェクトを再起動するのに役立ちました。
私が遭遇した最も奇妙なことは、
JDK 7
有効なコードタイプ
JDK 7
次のとおり
JDK 7
です。
catch (IndexOutOfBoundsException | ArrayStoreException e)
Play 2.1を完全に混乱させました。エラーもメッセージもありません。これらの行でサーバーがフリーズするだけで、それ以上何も起こりません。
ここで質問し、回答を待った。
パターン
彼らは彼らの頭で吸うことができるような沼地があります。 そして、彼らは吸うことはできません。率直に言って、テンプレートを効果的に使用するには、Scalaを十分に理解するか、少なくともScalaの内容を理解する必要があります。 そうでなければ、これはすべてコードの理解できないトリックになります。 そして、次のように機能するため、非常に注意する必要があります。
@main(title = "Home") { <h1>Home page</h1> }
そのため、新しい行に
{
が原因で既にエラーが発生しています。
@main(title = "Home") { <h1>Home page</h1> }
または別の例:
Play 2.0でScalaテンプレートについて初めて読んだとき、.Netの非常に便利なRazorのように見えたので、とても嬉しかったです。 私の意見では、Javaの世界の多くのテンプレートエンジンよりも本当に便利です。 ただし、すべての入力パラメーターを最初の行として宣言する必要があることを忘れないでください。 また、コード内で
fullName
変数を宣言するには、次のようにします。
@defining(user.getFirstName() + " " + user.getLastName()) { fullName => <div>Hello @fullName</div> }
そして、いくつかのことをインポートするために必要なもの:
@import helper._
。 さらに多くの「ifs」と「buts」があり、その中であなたはあまり自由ではないと感じます。
主な利点は、Scalaテンプレートがコンパイル段階でコンパイルおよびチェックされることです。これにより、未承諾のエラーや攻撃的なタイプミスの数が減ります。
一般に、Play 2.1でScalaテンプレートが良いか悪いかは重要ではありませんが、Javascript MVCフレームワークが人気を集めており、次のことが重要になるため、背景に隠れています。
JSONを使用する
それから勇敢な戦士は一般的に動揺し、居酒屋で飲みに行きました。私の意見では、Play 2.1はPlay 1.2.xに少し負けています。 主な理由は、Gsonの代わりに、JavaでJSONを操作するためのメインライブラリとしてJacksonが使用されていることです。 Play 1.2.xでGSONを使用するのが好きでした。便利で柔軟でした。 ジャクソンはまったく異なる方法で働く必要があります。 どうやら、私はまだ彼を楽しむためにジャクソンのそのレベルの理解に達していません。 そして、JSON文字列のフィールド名を二重引用符でエスケープする必要があるという事実は、ため息をつく原因でした。
return ok(Json.parse("{\"status\": \"success\"}"));
読みやすさはほとんどありません。 特に、GrailsでのJSONの扱いやすさと比較すると:
render([result: 'fail'] as JSON)
もちろん、すべてがそれほど悪いわけではありませんが、Javaでできる最善のことは
2のようなものです:
ObjectNode result = Json.newObject(); ArrayNode arrayNode = result.putArray("photos"); for (Photo photo : photos) { ObjectNode photoAsJson = arrayNode.addObject(); photoAsJson.put("id", photo.id); photoAsJson.put("guid", photo.guid); } return ok(arrayNode);
かなり耐えられる。
ただし、Scalaの場合、Play 2.1のJSONサポートは大幅に改善されています。
Json.obj( "users" -> Json.arr( Json.obj( "name" -> "bob", "age" -> 31, "email" -> "bob@gmail.com" ), Json.obj( "name" -> "kiki", "age" -> 25, "email" -> JsNull ) ) )
しかし、Groovyでは、より短くシンプルに見えます。 それでも、ScalaがXMLのようにネイティブJSONサポートを追加することが望まれます。
私は自分の人生を単純化することに決め、静的メソッドを備えた2つの追加クラスを追加しました。1つは
Tuple2
アナログである
Pair
、もう1つは
Map
に
Pair
を置くクラスです。 その結果、私にとっては簡単になりました。
return ok(toJson(map( pair("status", "fb-logged-in"), pair("user", map( pair("id", fbUser.id), pair("facebookUserId", fbUser.facebookUser.userId), pair("fullName", fbUser.fullName()) )) )));
タプルについて話しているので、Play 2.1ではJava機能のサポートがPlay 1.2.xのライブラリ
play.libs.F
からコピーされます。 ただし、これについての公式文書には言及されていません。
Play 1.2.xのドックを監視する必要があり
ます。もう1つ:Play 1.2.xからXMLサポートも移行されました。XMLの操作に
play.libs.XPath
を使用
play.libs.XPath
と非常に便利です。
メールで作業する
伝書鳩とカラスはすべてここに輸入されます。 簡単に入手できます。 そして、プレテールIIの支配者がすべての鳥を撃ったという噂があります。Play 1.2.xではなく、Play 1.2.xでメールを送信するための組み込みサポートがあったため、メールについて少し言いたいと思います。
メール用の公式
プラグインがあり
ます 。 ここ
では、作成者自身がメールサポートを追加しないことに決めたと言っています。 伝えられるところでは、それは誰もが自分でできるほど簡単でシンプルです。 Googleグループの多くの質問とinりがこの観点に反論しています。人々はPlay 2.1にPlay 1.2.xよりも機能が劣らないことを期待しています。
構成
以前の契約が巻物に書かれていた場合、現在は別の葉に書かれています。注目に値する主なことは、彼らが
framework ID
を削除したことです。 ここで、1つの大きな構成ファイルの代わりに、いくつかの個別の構成ファイルが必要です。 議論の余地がある点として、各アプローチには長所と短所があります。 以前に
production
を開始した場合:
play run --%production
これは次のようになります。
play -Dconfig.resource=prod.conf start
また、
prod.conf
は、プレフィックスなしのすべての設定オーバーライドが含まれています。
IDE統合
私の最高の馬が地元の道路に足を押し込みました!すべてのIDEの
すべてのOdessaについてはお話ししませんが、私の愛するIntellij IdeaはPlay 2.xをサポートしており、理想とはかけ離れています。 コードナビゲーションは、多くの場合、見たり見たりする必要のない生成されたクラスにつながります。時にはscalaテンプレートの編集に問題があり、SBTの完全なサポートはバージョン13でのみ利用できます。 ここに私が見つけて報告したものがあります:
youtrack.jetbrains.com/issues/SCL?q=reported+by%3A+Andrey.Volkov+コードを書く喜びだけでは十分ではありません。 Play 2.xはそれほど前にリリースされておらず、IDEのサポートに大きなリソースを費やすほど人気がないかもしれないことを理解しています。 IDEからのヘルプをあまり期待しないでください。
Play 1.2.xでは、これははるかに優れています。
シンプルさがなくなった
Playterre Iの国が奇跡に満ちていて、魔法の杖の波で多くのことが行われた場合、Playterra IIには魔法はなく、シャベルと、盾と剣しかありません。Play 1.2.xは非常にシンプルで便利でした。 何とかそれ自体で多くのことが行われ、うまくいきました。 はい、Play 1.2.xであまりにも多くが発生し、生成されすぎて通常のJavaの世界とはまったく異なるという意見を聞きましたが、それは簡単、簡単、迅速に機能しました。 すべての複雑さは普通のユーザーから隠されていて、最も細心の注意を払ったプログラマーだけが複雑なソースコードを掘り下げる必要がありました。
Play 2.1では、ほとんどすべての「魔法」はScalaに委ねられています。 そしてこれはもはや魔法ではなく、これはScalaの明確に定義された作品です。 プログラマーは常につまずく必要があります。 また、Scalaの基礎さえ知らないと、理解するのは非常に困難です。
楽しみのために比較してください:
public static void index() { render() }
そして
public static Result login() { return ok( login.render() ); }
最初のコードはよりシンプルですが、いくつかの規則を知って従う必要があり、2番目のコードはより冗長ですが、何かを知って従う必要があります。 2番目の方法はより柔軟ですが、単純ではありません。 私は個人的に最初のものが好きです。
ところで、
login
2番目の例で
login
どう思い
login
か? これは、scalaテンプレートから生成されたクラスです。 これは、この非常にscalaテンプレートのコンパイル後にのみ表示されます。 つまり IDEは、そのようなクラスが存在しない、または何かを変更するとメソッドシグネチャが一致しないと文句を言います。 コンパイル後、苦情は消えますが、IDEのヒントを使用すると問題が生じます。
Playterre Oneは、翼のある妖精と元気でいっぱいでした。 Playterra IIには、各ギアを見ることができるメカニカルゴーレムしかありません。紛れもない利点
多くの奇妙なことにも関わらず、欠陥とは言わないまでも、Play 2.1には多くの否定できない利点があります。
フォームと検証の操作
とても快適です。 JSR-303(Bean Validation)の完全サポートに加えて、特定のチェック用に独自の
validate
メソッドを追加する機能。 公式ドキュメントの例を書き換えません。
ここで完全に見ることができ
ます 。
テンプレートの場合、
input
フィールドの組み込み生成があり、Twitter Bootstrapのマークアップをすぐに生成できます。 唯一の残念は、バージョン1.4の場合です。 カスタムジェネレーターを記述する必要があり
ます(独自のフィールドコンストラクターの記述セクション)。
Authenticity Tokenが削除されておらず、Twitter Bootstrap 2.3フィールドが生成されていた場合、ほぼ理想的です。
Akkaおよびその他の非同期のもの
地元の居酒屋や居酒屋は非常に高速なサービスを提供しています。 そして、キューはありません。非同期性とマルチスレッドのサポートに関しては、馬に乗って2.1をプレイします。
非同期HTTP要求のネイティブ
サポート とAkkaとの
統合があります。 関数を操作するときに、Javaの冗長性のみが公式ドキュメントにも記載されていない場合...
ただ比較してください。 Java:
public static Result index() { Promise<Integer> promiseOfInt = play.libs.Akka.future( new Callable<Integer>() { public Integer call() { return intensiveComputation(); } } ); return async( promiseOfInt.map( new Function<Integer,Result>() { public Result apply(Integer i) { return ok("Got result: " + i); } } ) ); }
Scala:
def index = Action { val futureInt = scala.concurrent.Future { intensiveComputation() } Async { futureInt.map(i => Ok("Got result: " + i)) } }
Scalaに切り替えるもう1つの理由。 または何か他のものですが、Javaよりも「機能的」です。
ただし、競合他社は眠っていません。Grails2.3では、非同期コンピューティングのサポートが非常に優れています(
公式ブログに投稿 )。 さらに、非同期コンピューティングはJavaよりもGroovyの方が便利です。クロージャーのサポートが役割を果たします。
スケーラビリティとクラウド
ここの土地は肥沃で、ほとんどすべての人口を養うことができます。 そして、さまざまな形や大きさの雲が空に浮かんでいます。非同期でステートレスな性質のため、Play 2.1は非常にうまくスケーリングすると言われています。 これまでのところ、私のプロジェクトはそのようなニーズに成長していないため、自分の経験からこれを確認することはできません。
はい。Play2.xは多くのクラウドホスティングサイトでサポートされています。 さらに、ネイティブサポート、つまり WARファイルを作成してTomcat / Jettyの下にデプロイする必要はありません。
それでもwarファイルを収集する必要がある場合は、
サードパーティのプラグインを使用してのみこれを行うことができます。
CoffeeScriptと少ないサポート
小さな悪魔がここで飼いならされ、今では人々に忠実に仕えています。CoffeeScriptおよびLessのネイティブサポート。 ここで何を追加または説明できるかさえわかりません。 便利に。 そうです。 すべてを縮小したとしても、どこも単純ではありません
.min.js
ではなく
.min.js
をロードするだけです。
これにはまだ問題はありません。
コンソール
Playterra IIの入り口の税関は、新しい労働者を雇いました。 誰も気にしないが、とにかく彼らの作品を見ることはない。 彼らがうまく働くようにすると、誰も彼らに注意を払うことはありません。コンソールは、Play 1.2.xよりもはるかに便利で機能的になりました。 しかし、これはPlay 2.1自体よりもSBT(Scala Build Tool)の功績です。
便利になったものから、
~
で始まるコマンドについて言及したいと思います。これらのコマンドは、ソースコードが変更されるたびに実行されます。 上記の
~test
の例。
結果は何ですか?
Playterra IIで休暇をとることは興味深いです。 そこでの移行に関する問題はまだ未解決のままです。私自身のために、私は次の結論を出しました。
- Play 2.1を最大限に使用するには、Scalaを十分に理解する必要があります。
- JavaでWebアプリケーションをすばやく作成する必要がありますか? Play 1.2.xを使用してください。 またはGrails。 GroovyはScalaほど理解しにくいものではありません。
- Scalaを学ぶ必要があります。 JavaやGroovyとの違いも非常に大きいため、勉強する必要があります。
- Javaは他のプログラミング言語にほとんど絶望的に遅れています。 関数型プログラミングを始めた後、Javaのみでコードを書くことに戻ることは非常に困難です。 たぶん、Java 8は状況を救うでしょう。
[1]-正直なところ、SpringをPlay 2.1に統合することは可能ですが、
それほど難しくはありません 。 つまり Spring Data JPAおよびSpring Dataの他のプロジェクトは理論的には追加できますが、このテーマに関する具体的な例や記事は見つかりませんでした。 彼の手も届きませんでした。
[2]-記事の準備中に、彼はJSON処理用のJava APIをJava EE 7に実装する必要があることを発見しました。 Oracleブログのこの
投稿から判断すると、この例よりも便利で優れています。 GroovyのJSONサポートに十分近い。 将来的にはこれだけ。