Challenge Engineer Life !

エンジニア人生を楽しみたい!仕事や趣味で学んだ技術的なことを書いていくブログです。

Payara-Examplesで始めるJava EE 環境準備編

この記事はJava EE Advent Calendar 2017の 18 日目です。

今日と明日のエントリでは、PayaraがGitHubで公開している「Payara-Examples」でJava EEを体験する方法について書きたいと思います。今日はまず初めに環境構築についてNetBeansを例に紹介します。

github.com

Payaraとは?

「Payara」はGlassFish から派生した新しい Java EE アプリケーションサーバーです。イギリスに本社があるPayara Services Ltdが提供しています。

今年Payaraメンバーが来日してPayara Meetupのイベントを開催したり、GlassFishユーザグループの会長である蓮沼さん(@khasunuma)がPayaraにジョインされたり、日本語のパンフレットブログを提供したり、と徐々に盛り上がりをみせています。

kikutaro777.hatenablog.com

Payara x IDE

Payaraを使った開発環境の構築手順は「Beginner's Guides」にまとまってます。メジャーなIDE記事について以下にピックアップします。

IntelliJ IDEA

blog.payara.fish

NetBeans

blog.payara.fish

上記NetBeansの例ではPayaraプラグインを入れてますが、プラグインなしでも設定可能です。Java EEもPayaraもNetBeansも初めて、という方を対象にプラグインを使わずに設定する手順を次に紹介します。

Payara x NetBeans

※確認環境はWindows 10 Pro, JDK 1.8.0 u112, NetBeans 8.2です。

Payaraプラグインを使わない場合

1. Payaraサーバをダウンロードします。
f:id:kikutaro777:20171217132531p:plain

2. メニューの「ツール」から「サーバー」を選択します。
f:id:kikutaro777:20171217132155p:plain

3. 「サーバーの追加」を押します。
f:id:kikutaro777:20171217132241p:plain

4. サーバーの「GlassFish Server」を選択して、名前を付けます。ここでは「Payara」としました。
f:id:kikutaro777:20171217132318p:plain

5. 最初にダウンロードしたPayaraサーバの解凍先の中にあるPayaraフォルダを指定します。NetBeansが認識すると「次」ボタンが押せるようになります。
f:id:kikutaro777:20171217132348p:plain

6. ドメインはデフォルトで作成されているdomain1のまま「終了」します。別名を付けた新しいドメインを作成しても構いません。
f:id:kikutaro777:20171217132604p:plain

7. サーバの追加完了です。
f:id:kikutaro777:20171217132644p:plain

アイコンがGlassFishですが、これで設定完了です。

Payaraプラグインを使う場合

Payaraプラグインをインストールすると、サーバーの選択画面でPayara Serverが選択できるようになります。
f:id:kikutaro777:20171217134746p:plain

追加後のアイコンもPayaraです。
f:id:kikutaro777:20171217134812p:plain

プラグインのインストールは手間がかからないので、お試しではなく、がっつり使う予定の方は最初からこちらをインストールしておくのが良いと思います。

Visual Studio CodeでJavaを書いてみる

この記事は「Visual Studio Code Advent Calendar 2017」の7日目の記事です。

昨日は@74thさんの「Visual Studio Codeの各言語、環境のデバッグの仕方を集めたサイトを作ってる」でした。
明日は@Maxfield_Walkerさんです。

私からは「Visual Studio CodeでJavaを書いてみた話」をしたいと思います。

なんでVisual Studio CodeでJava書くの?

Javaのコードを書くとき、通常であればIntelliJ IDEAEclipseNetBeansなどのIDE(統合開発環境)を使います。コード補完やJavaDoc、ビルド、ユニットテストなど、様々な機能と周辺ツールを利用可能で、効率良く開発ができるためです。

私はJava EE開発をやっていたので、ずっとNetBeansをメインに使ってきたのですが、最近Visual Studio CodeでJavaを書く機会が増えてます。そのきっかけは11/24に参加した「Spring Fest 2017」でRed Hatの方がデモにVisual Studio Code使っていたのを見たためです。

そのときは「へー、Visual Studio CodeでJava書けるんだ」ぐらいの印象だったのですが、実際に使ってみたところ「軽い!」と動作のサクサク感に感動しました。

私が普段利用してるノートPCはVAIO Duo13という少し古い機種ではありますが、インテル Core i7-4650U (1.70 GHz)・メモリ8G・SSDでそこまで悪いSpecではありません。それでもNetBeansの起動は少し遅く感じます。

ちょっとしたお試しコードであればサクッとVisual Studio Codeで書いて動かす、というのは1つの選択肢になるのではないかなと思います。

Visual Studio Codeとは?

Visual Studio Code Advent Calendarなので、今さら書く必要がないと思いますが、Java方面だと名前は知ってるけど触ったことない、という方もいらっしゃる可能性があるため少しだけ触れておきます。

Visual Studio Codeは2015年にMicrosoftがリリースしたエディタです。Visual Studioという名前からWindowsでの動作をイメージを浮かべてしまいがちですが、Windows、Linux、macOSのプラットフォームで動くエディタであるのが特徴です。また、拡張機能(Extensions)は種類が豊富で開発も盛んです。
marketplace.visualstudio.com

f:id:kikutaro777:20171126023412p:plain

Visual Studio Code x Java

Visual Studio Codeを使ってJavaを書いてみようと思った方は一度公式サイトのドキュメントを参照ください。
code.visualstudio.com

以下、簡単に紹介します。

Java Extension Pack

Java Extension Packという拡張機能がMicrosoftから提供されています。基本的にはこちらをインストールするだけでOKです。
marketplace.visualstudio.com
f:id:kikutaro777:20171126023905p:plain

依存関係をみると以下の2つがあって、Red HatとMicrosoftが提供元となっています

Dukeかわいい。
f:id:kikutaro777:20171207005226p:plain

なんでテントウムシなんだろう…。J2SE 1.3.1のコードネームがLadybird=テントウムシらしいけど、それなのかな…。
f:id:kikutaro777:20171207005329p:plain

この2つはJava Extension Packをインストールすれば自動的にインストールされます。

Java Test Runner

12月1日にVisual Studio CodeがJUnitに対応したというアナウンスがありました。(ただしJUnit4)
blogs.msdn.microsoft.com

早速Publickeyで日本語記事になっていましたね。
www.publickey1.jp

こんな感じで今後もJavaに関連した拡張が増えていくと嬉しいなぁ。

実行結果

以下の簡単な例を試す手順をまとめます。(Mavenは入ってる前提)

  • Java Extension Pack x Spring Boot
  • Java Test Runner
Java Extension Pack x Spring Boot

Spring InitializrでWebのDependencyだけ入れたプロジェクトを落として解凍します。
f:id:kikutaro777:20171207011057p:plain

Visual Studio Codeの「ファイル」メニューから「フォルダーを開く」を選択し、解凍したフォルダを指定します。
f:id:kikutaro777:20171207011209p:plain

f:id:kikutaro777:20171207011438p:plain

開きました。
f:id:kikutaro777:20171207011548p:plain

「デバッグ」メニューから「デバッグの開始」を選びます。(F5キーを押してもよいです)
f:id:kikutaro777:20171207011754p:plain

すると環境の選択メニューが表示されるので「Java」を選びます。
f:id:kikutaro777:20171207012044p:plain

暫く待つと、launch.jsonが自動生成されるので必要なパラメータを指定します。今回はportの部分を空文字から8080に変更しました。
f:id:kikutaro777:20171207012242p:plain

再度「デバッグの開始」(またはF5)を実行すると、無事にSpring Bootのロゴが表示されてアプリケーションが実行されました。
f:id:kikutaro777:20171207012436p:plain

こんな感じで非常に簡単です。

Java Test Runner

こちらも簡単で、JUnitのテストコードを書くと下図のようにテストメソッドの上に「Run Test」「Debug Test」が表示されます。Debug Testはブレークポイントを置いてテストコードをデバッグできる実行方法です。
f:id:kikutaro777:20171207014436p:plain

右側のチェックマークやバツマークはテストの成功可否を表します。

その他機能

最低限の機能は揃ってます。

コード補完
f:id:kikutaro777:20171207014846p:plain

インポートの補助
f:id:kikutaro777:20171207012755p:plain

JavaDocのツールチップ表示&Help表示
f:id:kikutaro777:20171207013613p:plain

ウォッチ式
f:id:kikutaro777:20171207013929p:plain

定義への移動や
f:id:kikutaro777:20171207014935p:plain

参照の検索
f:id:kikutaro777:20171207015031p:plain

ステップイン・ステップアウト・ステップオーバー
f:id:kikutaro777:20171207015143p:plain

まだまだ機能的に足りない点はあると思いますが、ちょっとしたJavaコードを書く場合などには軽量でサクッと動くVisual Studio Codeを利用するのもありではないかなと思います。Visual Studio CodeはLinuxでもMacでも動くので、Java開発者の方は是非お試しください。

最後にVisual Studio Codeと全然関係ないのですが、来月以下のイベントを開催するので、興味がある方は是非ご参加ください!!
sendgrid.kke.co.jp

エンジニアと法律家の勉強会「StudyCode」に参加したきっかけ

この記事は、エンジニアと法律家の勉強会 #StudyCode Advent Calendar 2017 の 3日目の記事です。

1日目はHidemi Araiさん
hidemi.hatenablog.com

昨日の2日目はshibacowさんでした。
visualized-laws.hatenablog.com

今回のエントリではエンジニアである自分がStudyCodeに参加しようと思ったきっかけについて書きたいと思います。

エンジニアに法律の知識なんているの…?

私は受託開発のシステム経験を10年くらいしてきて、昨年からサービス系の業務(米国サービスの日本代理店でテクニカルサポートなど)を担当してます。今まで仕事では法律を意識する機会は少なく、知識も株のインサイダーとかコンプライアンス関連など入社時に学んだ基本的なこと+αぐらいな気がします。

受託開発だと少し前に改正民法関連で瑕疵担保の話を意識したぐらいでしょうか。ただ、この辺も実際には営業やプロジェクトの上位レベルって感じで末端で開発してる自分は当事者意識が薄めだったり…。
itpro.nikkeibp.co.jp

で、一番意識したのが自分の趣味でWebサービスを作ろうと思っていたときです。今まで作ってきたアプリは個人情報を取得するようなものがなかったのですが、今作ってるものはメールアドレスは登録してもらう形で

ふと、あれ、メアドって個人情報になるんだっけ…?

と思ったのが法律、というか個人情報保護法を意識したきっかけでした。

メアドは個人情報なの…?

総務省のページに同様のQAがあるのですが「メールアドレスには、個人情報に該当するものとしないものがあります」と何か微妙な線引きがある様子。
f:id:kikutaro777:20171203020828p:plain
総務省|行政機関・独立行政法人等における個人情報の保護|<3 個人情報の該当性>
法令・ガイドライン等

登録時にこの線引きの判定入れるのはナンセンスなので、基本的には個人情報と考えたほうが良さそうです。

ちなみに今年5月30日から施行された「改正個人情報保護法」では今まで対象外だった5,000人以下の個人情報を取り扱う小規模事業者も対象となって、気を付けるべき点が増えてるので、この辺も要チェックです。

PDF直リンですが、わりとわかりやすいガイドが経済産業省から出てます。
http://www.meti.go.jp/policy/it_policy/privacy/downloadfiles/01kaiseikojinjohopamphlet.pdf

利用規約とかプライバシーポリシーってどうやって作るの…?

じゃあ利用規約とかプライバシーポリシーを用意するかー、と思ったのですが

あれ、趣味レベルのサービスなんだけど、何をどこまで書く必要があるの…?

と手が止まりました。ググると、利用規約やプライバシーポリシーのテンプレートなんかも結構あるので、そういうのを上手くベースにするのが良いのかなぁと思いつつ、企業向けが多いので中々使いにくかったりも…。

そんなこんな調べてるとき、以下の書籍を買いました。
良いウェブサービスを支える「利用規約」の作り方

利用規約を何のために用意するのか、とかわかりやすく書いてあって勉強になりました。そして、エンジニアもある程度、法律のこと知っておかないといかんのだなぁと改めて。

ちなみに作ろうとしてるサービスは英語ページも用意する予定なんですが、利用規約やプライバシーポリシーを英語でも準備するの大変だなぁ…とか、EUの個人情報保護法(一般データ保護規則(GDPR))って厳しくなったって聞くけど、その辺は気にするべきなのどうなの?とか、他にも知っておかないと…という状態です。

相談相手がいない!

こういう趣味レベルのサービスで定義するものだと、相談できる人がいないし、中々学ぶ場もないなぁ…と思ってSNSに書いたところ、タイミングよく「StudyCode」(=クリエーター・エンジニアからプログラミングを教わり、法律家から法律を学ぶ街角勉強会)を主催されてる方から今度こういうの始めます、と教えていただき参加することにしました。

studycode.connpass.com

勉強会はエンジニアの方以外に、企業で知財関係を担当されてる方、行政書士や弁護士の方など幅広く参加してて面白いです。今後セッションで困ってることを共有するような話もあるといいなぁと。

特許庁&GitHub

エンジニアと法律が交わる面白い話の1つが先日あった以下のニュースです。
it.impressbm.co.jp

タイトルに「官公庁」「DevOps」「GitHub」と並ぶだけでなんともすごいw

ちなみに記事の写真真ん中にいらっしゃる足立さんもStudyCode主催メンバーをされてて、0回目、1回目ともに非常に面白い話をされてました。

今までの様子

StudyCodeのツイートは以下にまとめてます。

togetter.com
togetter.com

次回は来年2月頃を予定?とのことです!

SalesforceからSendGridを利用してメール送信する!

この記事は「SendGrid Advent Calendar 2016」の13日目の記事です。
昨日は @azumakuniyuki さんの「SendGridへリレーする方法、MTA3種盛り。」でした。
明日は @nakansukeさん の「Amazon SESとの比較」です。

Salesforce World Tour Tokyo 2016

本日からSalesforce World Tour Tokyo 2016が開催されますね。SendGridチームは明日12/14(水)、開発者向けの「Developer Forest*1に出展します!私もスタッフとして立っていると思うので、もしご興味ある方は是非ご参加ください!

ということで、今日はSalesforceにおけるメール送信について書いてみたいと思います。

なお、私自身、Salesforceを触ったり、連携するシステム開発の経験はありますが、Salesforce系の資格とか、ゴリゴリApex書いたとか、の経験はありません(>_<;今回のエントリは、自分で調べた範囲の知識にて、もし間違いがあった場合などはご指摘いただけると嬉しいです(^^;

Salesforceにおけるメール送信

Salesforceでは、リードや取引先責任者へメールを送ったり、ワークフローの承認でメールを送ったり、様々な用途、タイミングでメールが利用されます。メール送信に関しては、ざっと調べた範囲でも以下の選択肢があると思います。

機能カテゴリ 機能
Salesforce標準*のメール送信機能 リードへの一括メール送信
取引先責任者への一括メール送信
ワークフロー・承認申請のメールアラート
メール to ケース
メール to Salesforce
Apex(メールサービス) Apexプログラムによるメール送信
メールリレー 既存SMTPサーバをリレーサーバとして利用
AppExchange Sendmail(Salesforce Labs)
Autobahn for AppExchange
Synergy!LEAD
外部サービス(Lightning限定) Gmail
Office 365

他にもあるかもしれません。

せっかくなので、表の中のいくつか試してみます。

取引先責任者への一括メール送信

取引先責任者のツールメニューに「取引先責任者の一括メール送信」があります。

f:id:kikutaro777:20161212162253p:plain

宛先にする責任者をビューから選択します。

f:id:kikutaro777:20161212162307p:plain

メールテンプレートはSalesforceで標準にあったものから適当に選びました。

f:id:kikutaro777:20161212162323p:plain

一括メール送信名を入れて、「送信」ボタンを押すだけです。

f:id:kikutaro777:20161212162334p:plain

ちなみにこの一括メール送信名によって、管理メニューの「監視」->「一括メール送信」の一覧を識別できるようです。

f:id:kikutaro777:20161212183308p:plain

f:id:kikutaro777:20161212183336p:plain

送信完了を確認したら

f:id:kikutaro777:20161212162352p:plain

メールが届いているか確認します。おー、来てますね。

f:id:kikutaro777:20161212162454p:plain

さすが標準機能、手軽です。

外部サービス(Gmail)

表の一番下に入れた「外部サービス」はLightningだけで使える機能なんですね。せっかくなので、これもちょっと試してみました。管理メニューの「メール管理」から「外部サービス」メニューを選択します。

f:id:kikutaro777:20161212161442p:plain:w100

GmailとOffice 365が選べるのですが、今回はGmailを選択しました。右のボタンを「ON」に切り替えます。

f:id:kikutaro777:20161212160921p:plain

あとは「Lightning Experienceに切り替え」ます。

f:id:kikutaro777:20161212161206j:plain

ちなみにLightningへの切替は事前に環境を確認して行ってくださいm(_ _)mまぁSalesforce側で設定変更前に色々確認メニューでるので、ここではこの程度にしておきます。

切り替えた後、取引先責任者一覧へ。

f:id:kikutaro777:20161212165442p:plain

Lightningめっちゃ綺麗(/・ω・)/

メールの部分をみると、Gmailの選択肢がでます!

f:id:kikutaro777:20161212165730p:plain

メールエディタが組み込まれます。
f:id:kikutaro777:20161212170204p:plain

試しに送信すると、ちゃんと届きます。
f:id:kikutaro777:20161212170416p:plain

すごい。便利w

これらの機能はSalesforceで標準的に用意されており、統合された機能として使いやすいです。一方で、一部ガバナ制限を受けるケースがあったり、テンプレートを作成する際に、Web上でのエディタのようなものがなく少し手間だったり、という点もあるかと思います。ここはここでAppExchangeでカバーされる製品もあるとは思います。

なお、どういう制限があるのか、などQA的なものは以下が良さそうでした。

Salesforceのメール送信 ポイント集
help.salesforce.com

では次に、ここに挙げた選択肢以外でどのようなものがあるのか?というところで、SendGridを利用した方法を試したいと思います。

SalesforceでSendGridを利用したメール送信

SalesforceでSendGridを利用する方法としては、以下の選択肢があると思っています。

方式 方法 利用可能有無 補足
メールリレー × 一番シンプルな方法と思いますが、こちらにあるようにSalesforce側がID/Passの認証対応が現状できないようです。このスレ、相当みなさん文句言っていて面白い…
Apex sendgrid-apex 実はSendGridからApex用のラッパーライブラリがGitHubで公開されてます。詳細は後程。
SendGrid APIを直接叩く 今回時間がなくて試せなかったのですが、Apexでhttpコールができるのであれば、普通にSendGridのAPIをコールすることも
API連携 一番堅実で、SalesforceのSOAPかRESTのAPIで取引先責任者とかメアド取ってきて、SendGridのAPIで送信という形です。

Salesforceのメールリレーの設定は以下のようになっていています。

f:id:kikutaro777:20161212172412j:plain

SendGridでは、SMTPサーバにログインして直接使うこともできるのですが、当然ながらSMTPサーバのユーザIDとパスワードが必要です。しかし、Salesforceの設定ページでは特にそういう設定部がなく…現状、以下ページに書かれているように対応されていないようです。

success.salesforce.com

3つ目のApexでREST APIをコールする部分は今回調べきれなかったです。JavaでいうHttpClientとかJersey Clientみたいなライブラリがつかえると楽なのでしょうが…この辺Apexはどうなっているんでしょうか。。。

また、4つ目のAPI連携は下図のようなイメージです。

f:id:kikutaro777:20161213151606p:plain

今回のAdventでは細かく触れませんが、SalesforceのAPIをJavaで触ったとき(SOAP APIですが)のエントリは前に書いたので、興味ある方はどうぞm(_ _)m

kikutaro777.hatenablog.com

この方法が一番堅実だと個人的には思います。

Apex with SendGrid

さきほど、Apexで利用可能なライブラリがGitHubにあると書きましたが、以下となります。ただ、最終コミットの日付をみていただくとわかるのですが、数年前で止まったままとなっております。

github.com

以降で書くのは、あくまでも私がサンプル的に試したものであり、公式に利用可能であるということは保証できないのでよろしくお願い致します。実際、SendGridでは既にv3というAPIに移行していますが、このApexラッパーのコードを確認すると、v2のラッパーとなっていたりします。

色々ガードはってしまいましたが、早速、試してみましょう。

Salesforceにログインした状態で、GitHubのInstallationの下に表示されているURLをクリックします。
f:id:kikutaro777:20161212171942j:plain

今回は管理者のみでインストールしました。
f:id:kikutaro777:20161212173316j:plain

アクセスの承認をします。ここの2個目はちょっとよくわからず、とりあえず1個目だけチェックしています。
f:id:kikutaro777:20161212173329j:plain

「インストール完了!」と出ればOKです。
f:id:kikutaro777:20161212173340j:plain

開発者は通常EclipseとかでApex触るのだと思いますが、今回は簡単なサンプルなので「開発者コンソール」で進めます。
f:id:kikutaro777:20161212173504j:plain

Apexクラスを作成します。「SendGridController」クラスにしました。
f:id:kikutaro777:20161212173534j:plain

中身は以下のような感じ。お試しされる方は、ID/パスワード/メアドは本物に置き換えてください。
f:id:kikutaro777:20161212173544j:plain

public class SendGridController {

    public void sendMail() {
        SendGrid sendgrid 
            = new SendGrid('sendgridのログインID', 'sendgridのログインパスワード');
        
        SendGrid.Email email = new SendGrid.Email();
        email.addTo('テストで送る宛先メールアドレス');
        email.setFrom('送信元fromのメールアドレス');
        email.setSubject('SalesforceのApexからテスト送信');
        email.setText('Salesforceからこんにちは');
        
        sendgrid.send(email);
    }

}

続いてページを作成します。「Visualforce Page」を選択します。
f:id:kikutaro777:20161212173655j:plain

「SendGridPage」という名前にしました。
f:id:kikutaro777:20161212173703j:plain

中身は以下のように定義。Java EEなどでJSFに慣れていると楽ですね(^^;

<apex:page controller="SendGridController">
    <apex:form>
        <apex:commandButton id="btnSendMail" 
            action="{!sendMail}" value="SendGridでメール送信" />
    </apex:form>
</apex:page>

ページを開いてみます。URLで「https://x.xx2.visual.force.com/apex/SendGridPage」のようにページ名を直接打ってもいいです(xxの辺りはSandboxごとに異なる)し、設定メニューの「ビルド」->「開発」->「Visualforceページ」を選択して
f:id:kikutaro777:20161213141717p:plain:w100

矢印マークからページを起動することもできます。
f:id:kikutaro777:20161213141728p:plain

こんな感じ。
f:id:kikutaro777:20161212174109p:plain

ボタンを押すと、宛先で指定したメールアドレスに送信されます。簡単ですね。

ただ、実際の業務系では、メアドを直接Apexに埋め込むようなコードは書かないですし、こんな画面のユースケースはないと思います。

そこで、取引先責任者のテーブルを作り、メール送信用ボタンをカラムに配置してみたいと思います。その前に、素のままだと見た目があまりにもダサすぎるので、今回VisualStrapを使いました。BootstrapをVisualforceで簡単に使えるようにしてくれるものです。以下ブログが詳しかったです。

tyoshikawa1106.hatenablog.com

先ほどと同じようにApexのクラス(コントローラ)とVisualforceページを以下のように作成しました。今度は先にビューの定義から

<apex:page controller="SendGridTableController">
    <vs:importvisualstrap />
    <vs:visualstrapblock >
        <vs:pageheader title="SendGridによるメール送信" subtitle="デモ" />
        <apex:form >
            <vs:panel >
                <apex:dataTable value="{!contacts}" var="contact" styleClass="table table-striped table-bordered">
                    <apex:column >
                        <apex:facet name="header">取引先担当責任者名</apex:facet>
                        <apex:outputText >{!contact.name}</apex:outputText>
                    </apex:column>
                    <apex:column >
                        <apex:facet name="header">メールアドレス</apex:facet>
                        <apex:outputText >{!contact.email}</apex:outputText>
                    </apex:column>
                    <apex:column >
                        <apex:commandLink styleClass="btn-sm btn-primary" id="btnSendMail" action="{!sendMail}" value="SendGridでメール送信">
                            <apex:param name="email" value="{!contact.email}"/>
                            <apex:param name="name" value="{!contact.name}"/>
                        </apex:commandLink>
                    </apex:column>
                </apex:dataTable>
            </vs:panel>
        </apex:form>
    </vs:visualstrapblock>
</apex:page>
public class SendGridTableController {
    public List<Contact> listContacts;
    
    public void sendMail() {
        String mailTo = System.currentPageReference().getParameters().get('email');
        String name = System.currentPageReference().getParameters().get('name');
        
        //ホントはここで毎回newしないようにするべき
        SendGrid sendgrid
            = new SendGrid('sendgridのログインID', 'sendgridのログインパスワード');
        
        SendGrid.Email email = new SendGrid.Email();
        email.addTo(mailTo);
        
        email.setFrom('送信元fromのメールアドレス');
        email.setSubject('SalesforceのApexからテスト送信');
        
        List<String> subs = new List<String> {name};
        email.addSubstitution('name', subs);
        
        email.addCategory('Salesforce');
        
        email.setHtml('メールコンテンツ');
        sendgrid.send(email);
    }
    
    public List<Contact> getContacts() {
        if(listContacts == null) {
            listContacts = [SELECT Name, Email FROM Contact];
        }
        return listContacts;
    }
}

上記コードにありますが、差し込み(Substitution)カテゴリなどもちゃんと使えます。

で、画面を開くと以下のように取引先責任者一覧が表示されて、各行にメール送信のボタンが付きます。これで送りたい相手のボタンを押せば送れます。ホントはチェックボックス付けたり、がいいのでしょうけど…。
f:id:kikutaro777:20161212182129p:plain

よく考えたらVisualStrapじゃなくて、Lightningで作ってみればよかったな(^^;このVisualforceページをLightningでみたらどうなるんだろう‥と思って切り替えてみたのですがLightning内から開くとVisualforceページが別ウィンドウで呼ばれるんですね(^^;なるほど。

ちなみに、メールの中身ですが、このApexを利用して、以下のようなレスポンシブメールも送信できました!(上記コード内の「email.setHtml('メールコンテンツ');」の部分を変えて)

PC
f:id:kikutaro777:20161213154615j:plain

モバイル

f:id:kikutaro777:20161213142401p:plain:w250

ホントはこの部分もどのようにやったか書こうと思ったのですが、この辺はまたどこかで別途紹介したいと思います。

ちなみに上のサンプルメールはSendGridのマーケティングキャンペーンに関するものをサンプルとしたのですが、最近リリースされた機能なので是非お試しください。以下関連ブログですー。

sendgrid.kke.co.jp

sendgrid.kke.co.jp

*1:SendGridブースへお越しいただく方は、虎ノ門ヒルズフォーラム5Fなので、プリンスパークタワーへ行かないようご注意ください…

PrimeFacesのTimelineコンポーネントで1年を振り返ろう!

この記事は「Java EE Advent Calendar 2016」の8日目の記事です。
昨日は@sudoyuさんの「Spring系の2016年の現行プロジェクトをまとめてみる」でした!
明日は@megascusさんです!

自分にとってJava EE Advent Calendarは中々思い入れの強いイベントです。というのも、はじめてお誘い頂いた当時の自分は「アドベントかれんだー?なにそれ…おいしいの?」って感じでして、、

で、はじめて書いたAdventが

kikutaro777.hatenablog.com

です。2012年か…懐かしい。

atnd.org

ということで、4年を経て、改めてPrimeFacesで書いてみます。

実はPrimeFacesは、今もまだしっかりと継続して機能拡張が続いています。バージョンは6.0で、これはOSS版として誰でも自由に使えます。もう1つelite版という有償版があるのですが、そちらは6.0.8となっています。

バージョン6.0が出たとき、いくつかコンポーネントが追加となりました。

PrimeFaces 6.0 Released |

といっても元々PrimeFaces Extensionにあったコンポが統合された形なのですが。6.0.8ではOrganigramなど新しいコンポが増えてたりして、まだまだ拡張されそうです。

ということで、6.0で増えたTimelineコンポーネントというのを使って、自分のこの1年の仕事を振り返ってみました。

f:id:kikutaro777:20161207225040j:plain

うん。色々と心が折れるに十分な1年でしたね。

ソースはこちらにあるので、是非皆さんも1年をJava EEのコードで振り返ってみてください!

github.com

ちなみに、こんなカラフルにしたり

f:id:kikutaro777:20161208000649j:plain

左にある項目をドラッグ&ドロップで投げ込んだり

f:id:kikutaro777:20161208000713j:plain

上下のTimelineで連動させたり

f:id:kikutaro777:20161208000907j:plain

意外と多機能なコンポーネントとなっています!!

Java EE Advent Calendar 2016の8日目が空いてしまってたので、急きょ入れたため、非常に雑なネタとなってしまいました。すみません…。

Spring BootのAutoConfigureには実はSendGridが含まれている!

この記事は「SendGrid Advent Calendar 2016」の5日目の記事です。
昨日は @ayakomuro さんの「First time using SendGrid」でした。
明日は公式ブログさんですw

Spring Bootの勢い

私は仕事で長らくJava EEを使ってきたのですが、もちろん、常にSpring Frameworkの存在は気になっていました。特にSpring Bootが出て以降、周囲で良い評判を耳にする機会がさらに増え、浮気心が沸いてます。そういった中、先月「Spring Day 2016」に参加したのですが、人の多さやイベントの盛り上がり方、多くの有名企業が発表するセッションなどを目の当たりにして「うぉー」ってなりました(^^;

そんなわけで、最近、改めてコツコツとSpring Bootを触り始めています。ちなみに私みたいなSpring Boot初心者は、最初に以下の本を読むのが良いです。色々と手を動かしながら学べます。薄いけど内容濃くて、持ち運び便利なのも好きな所です。

ちなみに自分はこちらも買ってコツコツ読んでいる所です(^^;

Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発
株式会社NTTデータ
翔泳社
売り上げランキング: 12,616

Spring Boot with NetBeans

自分はJava EEやってたこともあって、IDEはNetBeans派なのですが、以下のプラグイン

plugins.netbeans.org

を使うと

f:id:kikutaro777:20161204231555j:plain

f:id:kikutaro777:20161204231649j:plain

こんな感じでNetBeansからもSpring Initializrでプロジェクトの雛形作成することができて便利です。普段Java EEでNetBeans触ってる方は是非一度お試しを(^^;

SendGridのAutoConfigure

では本題へ。

Spring BootにはAutoConfigureというものがあってSpringが提供してる機能やその他ライブラリなどを簡単に使えるようになっているとのことです。AutoConfigureについては以下の情報がかなり詳しく、実際アノテーションを追っていきながら読んでみると非常に面白かったです。

qiita.com

上記解説の中にAutoConfigureの一覧がありますが、よくみると…

……

おぉ、今日のAdvent CalendarのテーマであるSendGridが!(わざとらしい

f:id:kikutaro777:20161205173837j:plain

GutHubだとここで確認できます。

f:id:kikutaro777:20161205180733j:plain

それにしても、眺めてみると有名なものがたくさん並んでいますね(^^;

f:id:kikutaro777:20161204224834j:plain

couchbase,flyway,mongoなどのDB関連や、freemarker,mustache,thymeleafなどのテンプレートエンジン、hazelcastやkafka,solrなどなど…これらと一緒に並んでいるのをみて、個人的には胸熱です。

Mandrill(MailChimp)などはないですしw

ということで、Spring Bootから簡単にSendGridを利用したメール送信をすることができます。@Beanなどが不要で、application.propertiesかapplication.ymlにAPI Keyを記述するだけで@AutoWiredにてDIされます。

application.properties

spring.sendgrid.apiKey = #SendGridで取得したAPI Keyを指定

または

application.yml

spring:
    sendgrid:
        apiKey : #SendGridで取得したAPI Keyを指定

依存性にSendGridから提供されているJavaライブラリを追加します。

<dependency>
    <groupId>com.sendgrid</groupId>
    <artifactId>sendgrid-java</artifactId>
    <version>3.1.0</version>
</dependency>

あとは、サンプルと合わせて以下のような感じに。今回はRest APIで「/send」を指定したらメールが飛ぶようなサンプルです。

package com.example;

import com.sendgrid.Content;
import com.sendgrid.Email;
import com.sendgrid.Mail;
import com.sendgrid.Method;
import com.sendgrid.Request;
import com.sendgrid.Response;
import com.sendgrid.SendGrid;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SendGridController {
    
    @Autowired
    private SendGrid sendGrid;
    
    @GetMapping("send")
    public Response send() {
        Email from = new Email("test@example.com");
        String subject = "Hello World from the SendGrid Java Library!";
        Email to = new Email("test@example.com");
        Content content = new Content("text/plain", "Hello, Email!");
        Mail mail = new Mail(from, subject, to, content);

        Request request = new Request();
        Response ret = null;
        try {
            request.method = Method.POST;
            request.endpoint = "mail/send";
            request.body = mail.build();
            ret = sendGrid.api(request);
        } catch (IOException ex) {
            //TODO:例外処理
        }
        return ret;
    }
}

mainはテンプレのまま。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootSendGridApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootSendGridApplication.class, args);
	}
}

SendGridのアカウントを取得して、API Keyを発行していることを前提に書きましたが、Keyの発行自体は非常に簡単です。

APIキーの管理 - ドキュメント | SendGrid
APIキー認証でセキュリティを強化しよう | SendGridブログ

Spring Bootを使ったサービス開発で「メールサーバ構築めんどくさいなぁ」とか「気軽にメール送れるサービスないかなぁ」と考えている方は是非一度お試し頂きたいなーと思います(^^)

サービスを動かす環境としてCloud Foundryも手軽です!

SendGrid x Spring BootをPivotal Web Services(Cloud Foundry)で試す - BLOG.IK.AM
Pivotal Web ServicesからのSendGrid利用 | SendGridブログ

Happy Sending!

Salesforce Driver by JavaFX

この記事は、JavaFX Advent Calendar 201524 日目の記事です。

昨日は id:kozake (@s_kozake) さんの 「続・AndroidでJavaFXを動かしてみたよ!」 でした。
明日は id:skrb (@skrb) さんがトリを飾られます(^^)!!


今年1年を振り返ってみると、技術的に新しいものを探したり・触ったりする余裕がない1年でした。逆に言えば真面目に仕事をしていたというか(^^;

そんなわけで、残念ながらJavaFXに関してもあまり新しいネタはありません。(すみません…

ということで、今日は実際の仕事でJavaFXをこんな風に使ってみた、というネタにしたいと思います。

現場 x JavaFX

ちょうど昨日のJavaFX Adventでこざけさんが「JavaFXは僕の好きな技術ですが、イマイチ現場で使われている感がありません。」と書かれていました(^^;

皆さんの現場ではどうでしょう(^^;?

ちなみに自分の所(部門)では、デスクトップアプリを作る際はWindows FormやWPFといった.NET技術を使っています(C#)

JavaFXは存在は知っているものの(多分…)、最終的には使い慣れた技術のほうが実案件で選ばれるのは仕方がない…という所でしょうか(^^;

元々Windows系が多いので、あえてJavaFXを選択するラインがないです。

また、会社全体でみると、同様に.NET系が多いようですが、Javaの場合だと、やっぱりSwingが主力みたいなところは普通にあるようです。

仮配属にきた新人さんへJavaFXを少し触ってもらったのですが、本配属先ではSwingでした、というのが今年はありました。

テストドライバ x JavaFX

実案件は難しいけど、脇で使ったり、直接お客さんが触るものでない所でJavaFXを…と思って1年くらい経つのですが、少し前にちょうどいい感じの仕事が出てきました。

その仕事は、Salesforceと連携して使う、とあるWebシステム構築案件です。

Salesforceをご存じの方はわかると思いますが、Salesforceは非常にカスタマイズ性が高く、Apexという言語で画面作ったり、ボタンで複雑な処理を呼び出したり、色々なことができます。

うちは導入ベンダなどではないので、Salesforce部分は専門ベンダさんが構築で、うちが作るWebと連携する形です。

f:id:kikutaro777:20151224185907p:plain

当初連携ではSalesforceのRESTを使おうとしてましたが、最終的にはSOAPを使っています(詳細は以下エントリ)

kikutaro777.hatenablog.com

実際やってみるとSOAP使った連携は楽だよなぁと。SFDCのWSDLからクラス自動生成できますし。

さて、本題です。

今回のシステムでは、Salesforce側でうちのWeb画面を呼び出す前に色々とオブジェクトを操作する流れがあります。その後、うちのシステム側に情報が来て、加工して、SOAP APIで更新する、みたいな。更新するには先にSaleforceのロジックでオブジェクトが作成されていないといけない、などですね。

連携とかの開発ではよくある話だと思いますが、両社の開発過程では、まだ色々出揃ってないのでドライバやスタブなどが必要となります。

ドライバやスタブがわからない場合は情報処理試験の本以下ページにある図などがイメージしやすいかと。

What is the difference between stubs and drivers in software testing? - Quora

実際Salesforce上のApexなどでドライバが作れれば最高なわけですが、今回は期間的にもドライバを相手方に作ってもらう時間や、うちがApexを習得して自前でドライバを作る余裕はありませんでした。

なので、Javaで普通にSOAP APIを叩いて、Salesforce上で何かの操作をした後のオブジェクト構造とかを作り出すドライバを作りました。

f:id:kikutaro777:20151224190748p:plain

せっかくなので、JavaFXで作って、ドライバで作ったデータをすぐ確認できるように、WebViewもつけてます。以下のような感じ。

f:id:kikutaro777:20151224191326j:plain

ドライバでテストデータを作って、ブラウザ使わずともWebViewでみれたり。

f:id:kikutaro777:20151224191340j:plain

現場への導入第一歩としては良い感じではないかなーと(^^;

JavaFX使うと何がどこまでできるのか、とかも徐々にナレッジが溜まりそうですし。

書いてるコード

このプロジェクトで作ってるドライバは、非常に簡単なコードの集まりです(^^;

以下に、明日トリを飾る@skrbさんが以前JJUGでハンズオンをされたときの資料がありますが、これを1回やれば普通にできるレベルです。

上記ハンズオン資料は非常に細かく手順も書かれているので、新人さんでも普通にこなせます。
実際、プログラミング経験がほとんどない新人さんにやってもらったりもしてるので。

NetBeansでunpackingが遅い

ドライバ作ってるときにちょっと出会ったネタを最後に1つだけ。

自分はNetBeansでMavenを利用してJavaFXアプリを作っています。画面はSceneBuilderで。

で、今回のドライバはSalesforceのライブラリを使ったり、その他、諸々と依存性があったのですが

ビルドが超遅い(^^;

コンソールみると

f:id:kikutaro777:20151224192542j:plain

unpackingをすごいしています。調べると、java -jarで実行可能なjarファイルを作ってくれてて、そのために依存ライブラリをいれてるっぽい。

で、以下に同じ話がありました。

stackoverflow.com

上記StackOverflowにあった解決案としてprofileを作成するというのがあって、自分はそうしました。

NetBeans(ちなみに8.0.2) & Mavenで自動作成されたpom.xmlには

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.2.1</version>
    <executions>
        <execution>
            <id>unpack-dependencies</id>

            <phase>package</phase>
            <goals>
                <goal>exec</goal>
            </goals>
            <configuration>
                <executable>${java.home}/../bin/javafxpackager</executable>
                <arguments>
                    <argument>-createjar</argument>
                    <argument>-nocss2bin</argument>
                    <argument>-appclass</argument>
                    <argument>${mainClass}</argument>
                    <argument>-srcdir</argument>
                    <argument>${project.build.directory}/classes</argument>
                    <argument>-outdir</argument>
                    <argument>${project.build.directory}</argument>
                    <argument>-outfile</argument>
                    <argument>${project.build.finalName}.jar</argument>
                </arguments>
            </configuration>
        </execution>
        <execution>
            <id>default-cli</id>
            <goals>
                <goal>exec</goal>                            
            </goals>
            <configuration>
                <executable>${java.home}/bin/java</executable>
                <commandlineArgs>${runfx.args}</commandlineArgs>
            </configuration>
        </execution>
    </executions>  
</plugin>

のような定義があるので、これを

<profiles>
    <profile>
        <id>executable</id>
        <build>
            <plugins>
                <plugin>
                    <!-- <groupId>以降をここへ移動 -->
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

これで、通常ビルドではunpackingせずに、実行可能なjarを作成したいときは以下プロファイルを指定してビルドすればいいような形になりました。

f:id:kikutaro777:20151224193022j:plain

明日は@skrbさんがトリを飾られます(^^)!!!

JSFでもモダンなUIが作りたい!

この記事は「Java EE Advent Calendar 2014」の23日目のエントリーです。
昨日は@den2snさんの「JSFのバリデーション - DENの思うこと」でした。明日は@HirofumiIwasakiさんです。

受託でエンプラ

私の仕事は受託開発がメインで、主に製造業のお客様向けに販売管理システムの構築を行っています。
(製造業で複雑な製品扱っている所は営業さんが見積作るの大変なので、その辺をコンフィグレータ使ってうまいことするシステム)

見積業務もお客様によってそれぞれ異なるので、要件に合わせて毎回要件定義して、システムも裏にERPがいたり、フロントでCRMがいて連携したり、色々です。まぁ、いわゆるエンプラなシステムです。

昨今、Web系への憧れというのは当然あって、受託やエンプラで負のネタをみるたび「ですよねー」と思ったりも(^^;;

……

おっと、愚痴でなくAdventでした。

そんなWeb系、フロントとバックで色々と違うのでしょうが、フロント側というのは、素のHTMLは当然のこと、HTML5やCSS、JavaScriptはバリバリで、特に昨今のJavaScriptフレームワークなんかは色々と使いこなせるエンジニアなんだろなぁと勝手にそんなイメージでいます(^^;

一方自分はというと、Web系システムやってるけど全然違います(^^;

最近では、AngularJSとか勉強して、業務でもやってみたいとは思いつつ、周囲をみてもJavaScript書けるエンジニアは一人もいませんし、チームとしての学習コストや保守性を等を考えると中々上長の承認も難しいのかなと(この辺がエンプラ的…)

とはいえ、昨今、お客さんの目が肥えているのは事実で、モダンなWebを求められることはあるわけです。

最近のケースだと、お客さんがNulabさんのBacklogを使っていて「クリックするとダイアログじゃなくてパネルが出てきて、こういう動きとか」みたいな感じでお話があったり。

JSF + PrimeFaces

私の所では、Java EEのJSF(JavaServer Faces)をここ2年くらいメインにしていて、さらにPrimeFacesと呼ばれるリッチコンポーネントを利用しています。

ちょうど初めてJava EE Advent Calendarに参加した2012年がそのネタでした。

JSFイケてないよね、というのは散々あちこちで聞きますし、もう言われ疲れたので、その辺の議論は置いておいて(^^;
今日はJSFだとこんな感じに、という所を書きたいなと思います。

NulabさんのBacklog

ここ1年くらいですが、仕事での課題管理は、社内開発された障害管理システムやTracからNulabさんのBacklogへ移行しています。

以前にnulabさんのカンファレンスnuconに参加しましたが、利用してる会社は相当多いですよね(^^;すごい

せっかくなので、今日はBacklogを参考に、JSFだとどんな風に作れるか、少し遊んでみました。

Backlogはメイン画面がこんな感じです。
f:id:kikutaro777:20141223221613j:plain
ちなみにこれは、会社の社内公募(コンペ)のチームで使ったときのものですが、昨日に社内で結果発表があって何と最優秀に選ばれました!わーい(^^)/

この画面をJSF+PrimeFacesでちょっと作ってみました(^^;
時間の都合で、簡易版ですが…
f:id:kikutaro777:20141223223541j:plain

また、Backlogではどう作られているか、という所までは時間の都合上みれていないです。すみません。

Sticky

Backlogの上段にあるメニューバーは常に最上段に表示されていて、課題のフィードとかが長くなったときでもちゃんと利用できます。
f:id:kikutaro777:20141223222722j:plain

最近だとよくあるものですが、業務系だと…どうでしょう(^^;
マウスで戻らせるものも多々ある気が…。

PrimeFacesにはStickyというコンポーネントがあって、これで同じことができるようになっています。

f:id:kikutaro777:20141223223625j:plain

faceletsの定義は簡単でstickyコンポを置いて、target属性で、固定したいコンポーネントのidを指定するだけです。
今回の例ではツールバーを固定しています。

<p:sticky target="tlbHeader" />

<p:toolbar id="tlbHeader">
    <f:facet name="left">
        <p:commandButton id="btnHomeMenu" icon="ui-icon-home" />
    </f:facet>
    <f:facet name="right">
        <p:themeSwitcher effect="fade">
            <f:selectItems value="#{backlogBean.listTheme}" />
        </p:themeSwitcher>
    </f:facet>
</p:toolbar>

Overlay PanelとTooltip

Backlogの左上にあるアイコンをクリックすると
f:id:kikutaro777:20141223222301j:plain

同じ画面に吹き出し形のパネルが表示されます。
また、画像にマウスオーバーするとツールチップも吹き出しの形で出てますね。
f:id:kikutaro777:20141223222316j:plain

こういうパーツはここだけでなく結構いろんな所で使われています。
ユーザ的にはダイアログ表示より手軽に付加情報がみれていいですよね。

PrimeFacesだとOverlay Panelを使うのが良さそうです。
ツールチップはTooltipコンポーネントがあります。

ボタンがあって
f:id:kikutaro777:20141223223918j:plain

クリックするとパネル表示。ツールチップは吹き出しではないですが。
f:id:kikutaro777:20141223223924j:plain

faceletsはこんな感じで、overlayPanelのfor属性で、先ほどのツールバーに置いてあるボタンのidを指定しています。

<p:overlayPanel for="btnHomeMenu" showEffect="slide" hideEffect="slide" dynamic="true">
    堀北真希さん写真集 絶賛発売中
    <h:panelGrid columns="3">
        <h:graphicImage id="imgCastella" value="/resources/images/castella.jpg" />
        <h:graphicImage id="imgDramatic" value="/resources/images/dramatic.jpg" />
        <h:graphicImage id="imgS" value="/resources/images/s.jpg" />
    </h:panelGrid>
    <p:tooltip for="imgCastella" showEffect="fade" hideEffect="fade"
               value="出版社: ワニブックス ISBN-10: 4847029283 発売日: 2006/3/25" 
               trackMouse="true" />
    <p:tooltip for="imgDramatic" showEffect="fade" hideEffect="fade"
               value="出版社: マガジンハウス ISBN-10: 483872604X 発売日: 2013/9/26" 
               trackMouse="true" />
    <p:tooltip for="imgS" showEffect="fade" hideEffect="fade"
               value="出版社: マガジンハウス ISBN-10: 4838719159 発売日: 2008/10/10" 
               trackMouse="true" />
</p:overlayPanel>

パネルの表示と隠れる際にエフェクトを指定することもできます。ここではslideにして、横からスライドしてくるような表示です。
また、tooltipも色々と属性があって、trackMouseをtrueにすると、マウスカーソルの移動にあわせてツールチップが付いてくるような動きになったりします。

マウスカーソルが画像の右上にあるとき
f:id:kikutaro777:20141223224604j:plain

左下
f:id:kikutaro777:20141223224638j:plain

DataTableのExpansion

Backlogではマウスオーバーすると展開されて情報が出てくるものもよくありますよね。
例えばプロジェクト情報の行にマウスオーバーすると
f:id:kikutaro777:20141223224756j:plain

メニューが
f:id:kikutaro777:20141223224802j:plain

PrimeFacesで、これと同じもの、、、は今回見つからなかったのですが、DataTableのExpansionで少し近いものができるのかなと。

これだとカラムでこんなのがついて
f:id:kikutaro777:20141223225004j:plain

クリックすると展開される形で、マウスオーバーよりアクションは多いですが(^^;
f:id:kikutaro777:20141223225044j:plain

faceletsは次のような形で、普通のdataTableに対して、rowTogglerとrowExpansionを付けてあげるだけでできます。

<p:dataTable var="prj" value="#{backlogBean.listProject}">
    <f:facet name="header">
        プロジェクト
    </f:facet>
    <p:column>
        <h:outputText value="#{prj}" />
    </p:column>
    <p:column width="16">
        <p:rowToggler />
    </p:column>
    <p:rowExpansion>
        <h:commandLink value="課題の検索" />
        <h:commandLink value=" | " />
        <h:commandLink value="課題の追加" />
    </p:rowExpansion>
</p:dataTable>

最初から全部展開させておきたい場合はdataTableにexpandRow属性というのがあるので、これをtrueにすればできたりします。

Rating

Backlogでは各投稿に「いいね」チックに星マークがつけられます。
人によって利用頻度が違いますが、いいですよね。
f:id:kikutaro777:20141223230311j:plain

PrimeFacesだとRatingコンポーネントが、そのままの機能です。
f:id:kikutaro777:20141223230416j:plain

faceletsではratingコンポを置いて、value属性でIntegerの変数(星の数を表す)とバインドするだけです。

<p:rating value="#{ticket.rating}" />

その他の属性で星の数を変えたり、色々な設定が可能です。

DataScroller

課題のフィードは、TwitterやFacebookみたいに、ある一定が表示されていて、どんどん追加表示していくことができます。
「もっと見る」にマウスオーバーすると次の何件かの課題が追加表示される形です。
f:id:kikutaro777:20141223225555j:plain

PrimeFacesだとDataScrollerを使うのが良さそうです。
f:id:kikutaro777:20141223225744j:plain

ボタンを押すと
f:id:kikutaro777:20141223225822j:plain

ボタンでない形式もできて、その場合はTwitterと同じようにフィードの最下端がブラウザの一番下にあたったときに自動的に読み込まれる形式です。
PrimeFacesのshowcaseがそうなってますね。
http://www.primefaces.org/showcase/ui/data/datascroller/basic.xhtml

そのせいで、このshowcaseページは下にあるサンプルコードが読めないっていうあれになってるんですが(^^;

faceletsは次のような感じです。DataTableとかと同じで、POJOなインスタンスを処理できるので、ここではTicketという課題を表すクラスのリストを渡して表示しています。

<p:dataScroller var="ticket" value="#{backlogBean.listTicket}"
                chunkSize="10">
    <f:facet name="loader">
        <p:commandButton type="button" value="View More" />
    </f:facet>
    <h:graphicImage value="/resources/images/makimaki.jpeg" width="32" />
    <h:commandLink value="#{ticket.id}" />
    <p:rating value="#{ticket.rating}" />
    <h:outputText value="#{ticket.content}" />
</p:dataScroller>

GridCSS

最後ですが、Backlogではブラウザの横幅サイズを変えるとレスポンシブにUIが変わります。

f:id:kikutaro777:20141223230955j:plain

横を縮めていくと
f:id:kikutaro777:20141223231008j:plain

PrimeFacesではGridCSSをつかって同じことができます。前に少し書きましたが、この仕組みです。

通常の画面を縮めていき
f:id:kikutaro777:20141223232152j:plain

こうなる
f:id:kikutaro777:20141223232213j:plain

ThemeSwitcher

最後に、これはBacklogと少し違いますが、PrimeFacesでは色々なテーマが用意されており、ThemeSwitcherコンポにて切り替えることができます。

今までのはRedmondというテーマだったのですが、

オレンジベースで少し明るめなui-lightnessや
f:id:kikutaro777:20141223232637j:plain

Flickrチックなもの
f:id:kikutaro777:20141223232702j:plain

カエル的な…
f:id:kikutaro777:20141223232724j:plain

jQuery UIのTheme使ったことある方はお馴染みかもしれませんが(^^;

まとめ

作ったサンプルコードはGitHubに置きました。
kikutaro/JsfBacklogSample · GitHub

今回の例では、自分で書いたCSS、JavaScriptはゼロです(^^;
これは全て、PrimeFacesのコンポーネントが内包しているためです。

それが良いわけでは全然ないのですが、私のように書けない人間がエンプラでモダンさを求められた場合、今こんな風にやっていますという所でした。

ちなみにPrimeFacesは相当な数のコンポーネントが揃っているのですが、まだまだ今でも追加していて驚きます(^^;

JSFはコンポーネントベースなので、どういうコンポがあるか抑えていれば、プロトタイピングもサクサクできるので、今は要件定義でも積極的に使うようにして、はやめに動きの認識合わせをお客さんとすることに利用しています。

JSFはJava EE 8でのJSF2.3に向けて、様々な拡張も継続しているようです。

日本OracleのJavaエバンジェリストである寺田さんから教えて頂いた情報↓

既にブログ書かれている方も(はやい!)

2015年はJavaScriptなどWeb系の勉強やウォッチに力を入れていきたいなと思う今日この頃です。

JavaFXのサードパーティ「JFXtras」を触ってみる! #javafx

この記事は「JavaFX Advent Calendar 2013」の22日目の記事となります。

昨日はもじゃ変さん(@razon)による「JavaFX 8 on Scala - SHI-Zone」でした。
明日は@tikeminさんです!宜しくお願いします。

JFXtrasとは?

JavaFXでは標準で様々な画面コンポーネントが揃っていますが、企業やコミュニティのオープンソースによるサードパーティコンポーネントも色々あるようです。情報として最新状態か不明ですが、Oracleさんのページに「JavaFX Third Party Tools and Utilities」があって、画面コントロール系としては

などが挙げられていました。今回この中から、JFXtrasを少しだけ触ってみました。
http://jfxtras.org/

なぜJSXtrasに興味を持ったかというと…

  1. ShelfViewを使ってみたかった
  2. 関わっているメンバーがすごそう

の2つでした(^^;

後者は、パッと見てわかったのはStephen ChinさんとJim Weaverさんだけなのですが、今年JJUGの勉強会やJavaOneに行っていなかったら、こうした方々の名前すら気にも止めなかったと思います…(^^;

で、いざ使ってみたら経緯がわからないのですが、ShelfViewはなくなっているようで…ちょっと残念でした。

JFXtrasについては、日本でも少し前ですがブログ書かれてる方がいらっしゃって、そちらでプロジェクトの解説等が翻訳された形になっていますので、参考にして頂くほうが良いかと思います。

JFXtras 2プロジェクトとは?

サンプルを触ってみる

jfxtras-ensembleというサンプル集のようなものがあって、GitHubからダウンロードして手元でビルド・実行してみたら、こんな感じでした。

f:id:kikutaro777:20131222053205j:plain

が、自分の設定が悪いのか触るとエラーに…(^^;

あと、Java 8を入れていれば「FXTras 8.0 Samples」を見れるよ、と書いてあったので試してみました。こちらは問題なく動かせました。

f:id:kikutaro777:20131222102950j:plain

上記はタイムスケジュールとか作るようなサンプルですね。あと放射状の(Radial)メニューとか

f:id:kikutaro777:20131222103359j:plain

ちょっと触るだけでも面白いので、JDK8を入れてる方は是非触ってみてください。
以下サイト真ん中あたりの「Try It!」からjar落として、JDK8で以下実行するだけです。
http://jfxtras.org/

java -jar jfxtras-labs-samples-8.0-r1-SNAPSHOT-shadow.jar

実際に使ってみる

で、もともとネタにしようとしていたShelfViewなるものがないので、どうしよう…と思ったのですが、とりあえず動かしてみることに。

サイトみるとUse It!のところでMavenのセントラルリポジトリにjfxtras-labsがあるとのことでしたが、バージョンが古い2.2-r5までは置いてあるのですが、2.2-r6-SNAPSHOTと8.0-r1-SNAPSHOTは候補に出てきませんでした。一応セントラルの検索ページみてみたのですが、やはりなさそうな。。

f:id:kikutaro777:20131222105002j:plain

とりあえずjarは落とせるので「jfxtras-labs-8.0-8.0-r1-20130906.112928-11.jar」を適当なフォルダに落として、Mavenを使わない流れでNetBeansプロジェクトを作りました。
で、手動でjarを参照設定します。

f:id:kikutaro777:20131222105217j:plain

f:id:kikutaro777:20131222105240j:plain

FXMLファイルを開いてコード補完みると

f:id:kikutaro777:20131222105329j:plain

と出て、一瞬「あれ、コンポーネントみえないのかな…」と思いますが、右下コメントにあるように「Ctrl+Space」を押すと、JFXtras labで定義されているコンポーネントがみえるようになりました。

AgendaとかBatteryとか(^^)見慣れないコンポーネントがぞろぞろ。

f:id:kikutaro777:20131222105617j:plain

とりあえず、何かおいてみます。わかりやすそうなClockを選択。コード補完も普通に効きます。

f:id:kikutaro777:20131222111658j:plain

実行すると

f:id:kikutaro777:20131222111725j:plain

時計ですねw

他にもTrafficLightというコンポーネントがあって、属性をみたらgreenOnとかredOnとかyellowOnとか…(^^)大体想像つきますね。

さらにgreenBlinking、redBlinking、yellowBlinkingとあるので、まさかー、と思ってgreenに両方trueを指定してみました。

属性もちゃんとみえますね。
f:id:kikutaro777:20131222111634j:plain

f:id:kikutaro777:20131222111955g:plain

実行すると以下のような画面に(^^)

カスタムコンポーネントで自分でもこういう部品が作れるの?と思うと何かちょっとワクワクしますね。

残念ながら上記FXMLをSceneBuilderで開くと

f:id:kikutaro777:20131222112228j:plain

とエラーになってしまいました。クラスパス設定でうまくできるのかも?、ですが、単純にJar指定しただけではダメだったので今回はちょっと諦めます。

堀北真希さん with JFXtras

最後はやっぱり堀北さんで何か作りたい(※この理由は最後に補足)、ということで、Windowというコンポーネントを使って遊んでみました。

FXMLでWindowをAnchorPaneのchildren内に定義します。id名を付けておいて後でプログラムから触りやすいようにしておきます。

<children>
    <jfxtras.labs.scene.control.window.Window fx:id="beautifulWindow" title="きれいな堀北真希さん" prefWidth="400" prefHeight="300" />
</children>

Controllerのプログラムで

@FXML
private Window beautifulWindow;

@Override
public void initialize(URL url, ResourceBundle rb) {
    //綺麗な堀北さんの写真を指定
    Path imagePath = Paths.get("D:\\photo\\horikita\\beautiful.jpg");
    ImageView image = new ImageView(imagePath.toUri().toString());
    
    //タイトルバーの右側に閉じるボタンつける   
    beautifulWindow.getRightIcons().add(new CloseIcon(beautifulWindow));

    //Window内はBorderPaneにしてCenterへ写真配置
    BorderPane windowPane = new BorderPane();
    beautifulWindow.getContentPane().getChildren().add(windowPane);
    windowPane.setCenter(image);
}

こんな感じでWindow内に写真を置いたりします。同じようなWindowをいくつか用意して、ついでにClockコンポーネントをつけて実行すると。
美人時計ならぬ、マイ堀北さん時計…とか(^^; Windowコンポは自由に移動できるので、配置も自由に変えられます。

f:id:kikutaro777:20131222114804j:plain

Windowコンポでは閉じるボタンを左にするか右にするか(綺麗な堀北さんは右に、舞台宣伝のは左につけてます)等、細かく設定できるので便利そうです。

また、タイトルバーのボタンでRotateIconをつけると、Windowがグルっと回転したりw

f:id:kikutaro777:20131222115147j:plain

まだまだJavaFX標準機能の理解を深めないといけない自分ですが、こんな感じでちょっと脱線して面白いライブラリをみつけたりして遊ぶのもいい感じです(^^)

補足

ということで、今年の夏から始めたJavaFX、仕事で利用しているわけではなく遊びでやっているので中々上達しませんが…楽しいです(^^)
堀北真希さんを絡めた理由は少し前にJavaFX勉強会でLTさせて頂いた以下の資料を参照下さい。

Embedded GlassFishで困った時にやってたこと

この記事は「GlassFish Advent Calendar 2013」の19日目の記事となります。

昨日はHASUNUMA Kenjiさん(@btnrouge)による「管理コンソールは本当にJSF 2.xで構築されているのか?」でした。

明日もHASUNUMA Kenjiさん(@btnrouge)です(^^;お疲れ様です。

Embedded GlassFish

Embedded GlassFishとは何ぞや?ということについては、既に@btnrougeさんが4日目の記事で「GlassFish Embedded Serverのご紹介」を書かれていますので、そちらを参照して頂くのが良いと思います。

また、以前に自分が書いた「オフライン機能をEmbedded GlassFishで実現できるか?」の中でも日本語で参考になるサイトを紹介してるので、その辺りも含めて興味ある方は参照頂ければと思います。

思ったように動かないとき

@btnrougeさんが「GlassFish Embedded Serverのご紹介」で書いているように、構成管理がしっかりしていればほとんどエラーになることはないのではないかなと思います。

ただ、自分が最近とある技術調査をしたとき(内容としては、Java EE6で構築したシステムをオフラインで動かすために、warをEmbedded GlassFishでデプロイして動かすようなもの)、細かい所でショボイミスしたり、思ったように動かなくてハマったりしました。そのときに行っていたことを整理してみます。

CommandResultを確認する

Embedded GlassFishでは管理コンソールがみえないので、asadminコマンドを実行するためのCommandRunnerクラスが用意されています。

glassfish.getCommandRunner().run(
    "create-jdbc-connection-pool",
    "--driverclassname=com.microsoft.sqlserver.jdbc.SQLServerDataSource",
    "--datasourceclassname=com.microsoft.sqlserver.jdbc.SQLServerDataSource",
    "--restype=javax.sql.DataSource",
    "--property",
    "portNumber=1433:databaseName=HogeHoge:serverName=XX.XX.XX.XXX",
    "hogehogePool"
);

上記はJDBCのコネクションプールを生成するコマンドを実行したものですが、こんな風に結構長くなったりして、しょぼいスペルミスしたりとかもあったり…(^^;

サンプルではあまり戻り値が気にされてないことが多いのですが、runの戻り値がCommandResultクラスとなっていて

CommandResult result = glassfish.getCommandRunner().run(
    "create-jdbc-connection-pool",
    "--driverclassname=com.microsoft.sqlserver.jdbc.SQLServerDataSource",
    "--datasourceclassname=com.microsoft.sqlserver.jdbc.SQLServerDataSource",
    "--restype=javax.sql.DataSource",
    "--property",
    "portNumber=1433:databaseName=HogeHoge:serverName=XX.XX.XX.XXX",
    "hogehogePool"
);

//結果を標準出力してみる
System.out.println(result.getOutput());
System.out.println(result.getFailureCause());
System.out.println(result.getExitStatus());

上記が成功すると

PlainTextActionReporterSUCCESSJDBC connection pool hogehogePool created successfully.
null
SUCCESS

みたいな出力となります。

最後にコールしたgetExitStatus()の戻り値はExitStatusクラスで

  • CommandResult.ExitStatus.SUCCESS
  • CommandResult.ExitStatus.WARNING
  • CommandResult.ExitStatus.FAILURE

等の値判定で細かく分岐することもできます。

試しに「create-jdbc-connection-pool」のコマンド名を間違えてみます。「create-jdbc-connection-poola」みたいな(^^;l

そうすると

Exception while executing command.
java.lang.NullPointerException
FAILURE

と失敗が明確にわかります。

propertyの指定で誤ったシンタックスを入れたりすると

PlainTextActionReporterFAILUREjava.lang.IllegalArgumentException: Invalid property syntax, missing property value: aDescription: create-jdbc-connection-pool commandInvalid property syntax, missing property value: a
Usage: //長いので省略
java.lang.IllegalArgumentException: Invalid property syntax, missing property value: a
FAILURE

みたいな感じです。

詳細なログを出す

上記の設定でasadmin関連の処理は無事に成功して、Embedded GlassFishが起動できて、最後にデプロイ!すると上手くいかない、なんてケースもありました。

デプロイの実行内容で詳細な内容をみたい場合は、以下のようなログ記述を入れると簡単に確認できます。

Logger.getLogger("").getHandlers()[0].setLevel(Level.SEVERE);
Logger.getLogger("javax.enterprise.system.tools.deployment").setLevel(Level.SEVERE);
Logger.getLogger("javax.enterprise.system").setLevel(Level.SEVERE);

元ネタは以下ですが、Embedded GlassFishのドキュメントにも書いてありました。

Changing Log Levels in Embedded GlassFish

ログをファイルに書き出したい

先の設定で詳細なログが標準出力されますが、相当な量になるのでみえません(^^;
やっぱファイルでみたい、という場合には、動いているJavaのlogging.propertiesを一時的に変えるのが手っ取り早かったり。
(インストールされたJREJDKの\lib\logging.properties)

handlers= java.util.logging.ConsoleHandler,java.util.logging.FileHandler

最後にハマったパターン

自分が試したシステムでは、最後の最後に「アプリケーションは起動時に正しく初期化されず、ファクトリが見つかりませんでした: javax.faces.context.FacesContextFactory」というエラーが出て、何が悪いのかわからずハマってました。

以下のStackOverflowの返信の中にEmbedded GlassFishで同じIssueを持っている人がいました。

Exception: could not find Factory: javax.faces.context.FacesContextFactory

上記からリンクもされてますが、以下参考情報。

Using JSF 1.2 with Facelets on Google App Engine for Java

とりあえずweb.xml

<listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>

を入れることで動くようになったのですが、イマイチすっきりしない感じも。

でも、とりあえず、Embedded GlassFishApache Derbyを組み合わせることで、一度クライアント・サーバ構成で作ったJava EE6のWebアプリケーションをオフラインでも簡単に使える状態が作れました(^^)

にほんブログ村 IT技術ブログへ
にほんブログ村 にほんブログ村 IT技術ブログ Javaへ
にほんブログ村