【忘却のJavaScript#4】Vue.jsでガントチャートを表示してみる

やること

  • 前回使ったFullCalendarでDayGridとは別のタイプのカレンダーを表示させる
  • Timeline Viewというガントチャートが書けるライブラリを使ってみる

用意するもの

FullCalendarのインストール

> npm install --save @fullcalendar/resource-timeline

  • 以下のようなメッセージが出たら、インストール成功
・・・
+ @fullcalendar/resource-timeline@4.1.0
added 3 packages from 1 contributor and audited 43477 packages in 29.741s

Timeline.jsの作成

  • src\components配下にTimeline.vueを作成
  • 以下の通り、FullCalendarライブラリの読み込みと画面表示を実装

Timeline.vue:

<template>
  <!-- Timeline Viewを表示 -->
  <FullCalendar
    :schedulerLicenseKey="calendarCustomize.schedulerLicenseKey"
    :plugins="calendarCustomize.plugins"
    :defaultView="calendarCustomize.defaultView"
    :height="calendarCustomize.height"
    :resources="calendarCustomize.resources"
    :events="calendarCustomize.events"
    :slotDuration="calendarCustomize.slotDuration"
  />
</template>

<style lang="scss">
@import "~@fullcalendar/core/main.css";
@import "~@fullcalendar/timeline/main.css";
@import "~@fullcalendar/resource-timeline/main.css";
</style>

<script>
import FullCalendar from "@fullcalendar/vue";
import resourceTimelinePlugin from "@fullcalendar/resource-timeline";

export default {
  components: {
    FullCalendar // make the <FullCalendar> tag available
  },
  data() {
    return {
      calendarCustomize: {
        // ライセンス要求表示を非表示化
        schedulerLicenseKey: "GPL-My-Project-Is-Open-Source",
        // 使用するプラグイン
        plugins: [resourceTimelinePlugin],
        // 表示形式 (今回はTimeline View)
        defaultView: "resourceTimelineDay",
        // タイムラインの高さ (項目数に応じて自動調整)
        height: "auto",
        // 時間軸の表示幅 (今回は2時間ごと)
        slotDuration: { hours: 2 },
        // Resourcesのデモデータ
        resources:
          "https://fullcalendar.io/demo-resources.json?with-nesting&with-colors",
        // Resourcesごとのイベントのデモデータ
        events:
          "https://fullcalendar.io/demo-events.json?single-day&for-resource-timeline"
      }
    };
  }
};
</script>

router.jsの更新

カレンダーの表示

f:id:wingfair:20190516212149p:plain

【忘却のJavaScript #3】Vue.jsでカレンダーを表示してみる

やること

FullCalendarをVue.jsに取り込んで、カレンダーを表示させてみる

「FullCalendar」とは?

用意するもの

FullCalendarのインストール

  • コマンドプロンプトから以下のコマンドを実行し、ライブラリをインストールする
    • 今回は"daygrid"という卓上カレンダーによくあるタイプのカレンダーのライブラリを使ってみる
    • "core"と"vue"とはFullcalendarのメインコードとvue用のアダプタ
> npm install --save @fullcalendar/vue @fullcalendar/core @fullcalendar/daygrid

  • 以下のようなメッセージが出たら、インストール成功
    • エラーが出る場合は後述の「npm installにてエラーが出る場合」を参照してみください
・・・
+ @fullcalendar/core@4.1.0
+ @fullcalendar/daygrid@4.1.0
+ @fullcalendar/vue@4.1.1
added 150 packages from 218 contributors, removed 52 packages, updated 1474 packages and audited 42927 packages in 128.145s

Sassのインストール

  • コマンドプロンプトから以下のコマンドを実行し、ライブラリをインストールする
    • ないとcssをインポートして、ビルドする際に怒られるので入れておく
> npm install sass-loader
> npm install node-sass

  • 以下のようなメッセージが出たら、インストール成功
・・・
+ sass-loader@7.1.0
added 10 packages from 17 contributors, updated 14 packages and audited 42949 packages in 48.009s
・・・
+ node-sass@4.12.0
added 58 packages from 58 contributors in 43.488s

Calendar.jsの作成

  • src\components配下にCalendar.vueを作成
  • 以下の通り、FullCalendarライブラリの読み込みと画面表示を実装

Calendar.vue:

<template>
  <FullCalendar defaultView="dayGridMonth" :plugins="calendarPlugins" />
</template>

<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'

export default {
  components: {
    FullCalendar // make the <FullCalendar> tag available
  },
  data() {
    return {
      calendarPlugins: [ dayGridPlugin ]
    }
  }
};
</script>

router.jsの更新

  • src\router.jsにCalendar.vueへのリクエストパスを記述

router.vue:

import Vue from "vue";
import Router from "vue-router";

Vue.use(Router);

export default new Router({
  routes: [
    {
      path: "/calendar",
      name: "calendar",
      component: () => import("./components/Calendar")
    }
  ]
});

カレンダーの表示

f:id:wingfair:20190515235855p:plain
FullCalendarのDayGrid

npm installにてエラーが出る場合

"EPERM: operation not permitted"エラーが出る場合

エラー内容

以下のようなエラーが出てしまうことがある。
VSCodeでプロジェクトフォルダを開いていたせいか、ファイルを掴まれていて正常にインストールできていない模様。

npm ERR! Error: EPERM: operation not permitted, ・・・
対処

原因究明をしっかりやったわけではないので、あくまで私の場合はこうやったら解決できたという一例です。

  • VSCodeなどテキストエディタを開いている場合は一度閉じてから、npm installを再実行してみる
  • それでもエラーが出る場合は以下のコマンドでnpmのキャッシュを強制的にクリアしてから、npm installを再実行してみる
npm cache clean --force

  • それでもエラーが出る場合はOS再起動し、npm installを再実行してみる

"Maximum call stack size exceeded"エラーが出る場合

エラー内容

上記の"operation not permitted"を解消されても、以下のようなエラーが出てしまうことがある。
エラーメッセージ的には一度に実行できるシステムコールの回数を上限を超えている模様。

npm ERR! Maximum call stack size exceeded
対処

こちらも原因究明をしっかりやったわけではないので、あくまで私の場合はこうやったら解決したという一例です。

  • 以下のコマンドを実行後にnpm installを再実行
npm rebuild
npm install @vue/cli-service -D

  • vue/cli-service -Dを実行しているのは、cli-serviceが消えてしまっていたため
    • "npm cache clean --froce"の影響・・?

【忘却のJavaScript#2】Windows10でVue.js動かしてみる

Vue.jsをインストールして、動かしてみたいと思います。
今回はローカル環境をつくるところまでしかやりませんが、Web上にたくさん公開されている画面テンプレを利用すれば、かなり簡単にきれいな画面をつくることができる代物です。

「Vue.js」とは?

やりたいこと

yarnを使って、Windowsローカル環境にVue.jsをインストールし、サンプルページを表示させる

用意するもの

VSCodeインストール

  • 以下にアクセスし、「Download for Windows」を選択して、exeファイルをダウンロード
  • ダウンロード後、exeファイルを実行し、VSCodeをインストール
    • インストールウィザードでは全てデフォルト設定を選択
  • インストール完了後、起動してみて以下のような画面が立ち上げればOK

f:id:wingfair:20190513213959p:plain
VSCode起動後の画面

YARNインストール

  • 以下にアクセスし、「YARNをインストール」を押下
  • YARNの利用にはNode.jsが必要となるため、事前にインストールしておく
    • インストーラを使用する場合はまず Node.js をインストールしておく必要があります。」の"Node.js"をクリックするとダウンロード先に飛べる
    • 「10.15.3 LTS」を選択してmsiファイルをダウンロード
    • ダウンロード後、msiファイルを実行し、Node.jsをインストール
    • インストールウィザードでは全てデフォルト設定を選択
  • YARNのダウンロードページに戻り、[Windows]、[安定版1.16.0]を選択し、[インストーラをダウンロードする]を押下
  • ダウンロード後、msiファイルを実行し、YARNをインストール
  • インストールが完了したら、コマンドプロンプトから以下のコマンドを実行し、想定バージョンが表示されればOK
> yarn --version
1.16.0

Vue.jsインストール

> yarn global add @vue/cli

  • 以下のコマンドを実行し、想定バージョンがインストールされていることを確認する
> vue --version
3.7.0

プロジェクトの作成

> vue create sample-app

  • 上記、コマンド内でインタラクティブにプロジェクトの作成を行っていく
    • 状態管理やら静的解析やらテストやらプロジェクトで使うツールを選ぶのですが、詳細な説明は割愛・・
    • 今回はひとまず今後使いそうなものを以下の通り選択していく
      • Please pick a preset: ⇒ "Manually select features"
      • Check the features needed for your project:
        • (*) Babel
        • ( ) TypeScript
        • ( ) Progressive Web App (PWA) Support
        • (*) Router
        • (*) Vuex
        • ( ) CSS Pre-processors
        • (*) Linter / Formatter
        • (*) Unit Testing
        • (*) E2E Testing
        • (*) CSS Pre-processors
      • User history mode for router? ⇒ "n"
      • Pick a liner / formatter config: ⇒ "ESLint + Prettier"
      • Pick additional lint features: ⇒ "Lint on save"
      • Pick a unit testing solution: ⇒ "Jest"
      • Pick a E2E testing solution: ⇒ "Cypress (Chrome only)"
      • Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? ⇒ "In package.json"
      • Save this as a preset for future projects? ⇒ "y"
      • Save preset as: ⇒ "sample-app"
      • Pick the package manager to use when installing dependencies: ⇒ "Use Yarn"
    • 一通り選択してEnterを押下するとプロジェクト作成が開始される
      • 10分くらいかかる (Cypressが重い・・・)
  • プロジェクトをVSCodeから開いて確認してみる
    • VSCodeを起動し、[File]->[Open Folder...]を選択
    • ファイルエクスプローラから先ほど作成したプロジェクトのディレクトリを選択して開く
    • すると以下の画像のようにプロジェクトのディレクトリ階層が構築されていることを確認できる
      • 左側にプロジェクトのsrcやconfigが並んでいる
      • ちなみにHome.vueは後述しているWelcomeページの実態

f:id:wingfair:20190513224212p:plain
Vueプロジェクトの雛形

プロジェクトのビルドとアプリ起動

  • コマンドプロンプトから作成したプロジェクトディレクトリの第一階層に移動し、以下のコマンドを実行してビルド&起動を行う
    • 以下の通り、"DONE Compiled successfully"と"App running at"が表示されればOK
> yarn serve

DONE  Compiled successfully in 9367ms                                22:24:31

 App running at:
 - Local:   http://localhost:8080/
 - Network: http://192.168.10.9:8080/

 Note that the development build is not optimized.
 To create a production build, run yarn build.

  • 以下のURLにアクセスし、画像のように「Welcome to Your Vue.js App」のページが表示されれば成功

f:id:wingfair:20190513222755p:plain
Vueのウェルカムページ

以上。

JSON ServerでサクッとAPIモックサーバをつくってみる

直近でフロントエンドの開発に携わることになりました。
APIモックがあると何かと便利かと思い、ググったところJSON Serverなるものがあるということで試してみました。

JSON Server」とは?

JSON Server(ジェイソン サーバ)とは、JSONファイルを元にしてWebAPIサーバモックアップを作成できる簡易サーバです。
開発中のWebAPIテストなどに活用できます。

引用元: 「オープンソースのAPI連携/JSON Serverとは

やること

JSON Serverを構築し、GETリクエストでjsonデータを取得する

用意するもの

Node.jsインストール

リポジトリ追加

以下のコマンドを実行し、yumからNode.jsを落とせるようにリポジトリ追加する。

# curl -sL https://rpm.nodesource.com/setup_8.x | bash -

Node.jsインストール

以下のコマンドを実行し、Node.jsをインストールする。
(10分くらいかかる)

# yum install -y nodejs gcc-c++ make

JSON Serverインストール

以下のコマンドを実行し、JSON Serverをインストールする。
(10分くらいかかる)

# npm install -g json-server 

APIモック作成

作業用フォルダ作成

適当なパスに作業用フォルダを作成し、フォルダに移動する。
今回は/api-mockを切る。

# mkdir /api-mock
# cd /api-mock

JSON Serverが返すJSONデータの作成

今回は以下の通り人のリストを返すmemberlist.jsonをサンプルとして作成。

memberlist.json:

{
  "memberlist":[
   {
     "first_name":"太郎",
     "last_name":"田中",
     "jender":"男",
     "age":31
   },
   {
     "first_name":"花子",
     "last_name":"山田",
     "jender":"女",
     "age":27
   }
  ]
}

JSONファイルの中に書いた"memberlist"がリクエストパスとなる。

JSON Serverの起動

以下のコマンドを実行し、先ほど作成したJSONファイルをインプットにJSON Serverを起動する。
"--host"はJSON Server(192.168.10.4)のリクエストURLにIPアドレスを指定したい場合は使用。
"--host"がない場合はlocalhostを指定すればアクセス可能。

# json-server --host 192.168.10.4 memberlist.json


以下のように表示されれば、成功。
http://192.168.10.4:3000/memberlist"でGETリクエストを受け付けて、JSONを返す準備が整っている状態。

 \{^_^}/ hi!

  Loading memberlist.json
  Done

  Resources
  http://192.168.10.4:3000/memberlist

  Home
  http://192.168.10.4:3000

JSONファイルの更新を自動反映させたい場合は以下のように"--watch"を指定することで実現可能。

# json-server --watch memberlist.json

JSONデータの取得

リクエスト送信

Chromeを開き、以下のURLにアクセス
http://192.168.10.4:3000/memberlist

JSONデータ取得

以下の通り、無事に取得成功
これはお手軽で便利!

f:id:wingfair:20190508231738p:plain
GET結果

ローカル以外からJSON Serverにアクセスしたい場合

実はローカル以外の環境からこのAPIcurlで呼んでみたところ、エラーが発生した。

エラー内容

# curl http://192.168.10.4:3000/memberlist
curl: (7) Failed connect to 192.168.10.4:3000; 接続を拒否されました

原因

エラー文言でググったところ、以下の記事を発見。
普通にポートが開放されていなかっただけの模様。。

StackOverflow:
json-server cannot access via local IP

対策

以下のコマンドでfirewallのポート穴あけを実施

# firewall-cmd --zone=public --add-port=3000/tcp --permanent
# firewall-cmd --reload
# firewall-cmd --list-all

これでちゃんと繋がるはずです。

【忘却のJava#7】JSUG勉強会#4の参加レポート

勉強会に参加して、良い刺激を受けたので書き残したいと思います。
個人用の備忘で文章が拙劣なのは、あしからずでございます。

これまでインフラまわりの勉強会には参加してきましたが、アプリよりは初めてだったので少し緊張しました。笑
登壇者の方々は発表は苦手と言いつつ、一生懸命伝えようとしてくれた所が好印象でした。

開催概要

テーマ

JSUG勉強会 2019その4 初心者による初心者のSpring入門

日時

2019/04/25(金) 19:00~21:00

場所

六本木ヒルズ森タワー20F Pivotal Japan

セッション

4つのセッションが用意されていました。

  • JSUGの正しい参加方法 (柴田 洋平さん - JSUGスタッフ)
  • Spring Coreの解説 (田村 英雄さん - Guildhub)
  • Spring 歴約1年初心者の Test 奮闘記 (内藤千静さん - タグバンガーズ)
  • Spring Boot × Vue.jsでSPAを作る (宮坂 豪さん - アクロクエストテクノロジー)


以下はその所感とメモです。

JSUGの正しい参加方法

概要

JSUGの成り立ちや参加スタイルについて教えてくださいました。
登壇者を絶賛募集中とのことです。

所感

おそらくSpring界隈でテックメインでやっていくことはないので登壇という形でお役立てはできないかもしれませんが、これからも参加していきたいと思いました。

Spring Coreの解説

概要

DIコンテナがどのように機能しているのか、自身が理解するまでの流れをFactoryやBean定義ファイルをもとに説明してくださいました。

所感

技術者として簡単な技術を上手く使えるということも大事ですが、原則原理や成り立ちを知っているということもまた大事だと個人的には思うので、そのような説明が聞けたのは良かったです。
でも実は私はSpringBootのHelloWorldレベルしかやってなくてスプリングのスの字も分かってないので、肝心のDIコンテナやらFactoryやらBeanやらの中身はポカーンでした。
なので、ここに備忘として書いておいて、次回までには抑えておければと思ってます。

メモ

  • 以前はSpring(DIコンテナ)がどうやってServiceとRepositoryをインスタンス化しているか分からなかった。。
    • Controller -> Service -> Repository -> DBのような関係性でServiceがnewされる度にRepositoryが勝手に作られる蜜結合の状態を避けたい
    • ⇒インタフェースとFactoryを利用すればよい

  • Factoryクラスを毎回作るのは大変⇒設定ファイルからインスタンス化対象を読み取り、インスタンス化したい
    • クラスの置き換えには実装の変更が必要⇒設定ファイルから依存関係を読み取り、インスタンス化したクラスに注入したい
    • これらはReflectionを使えば実現できる!

  • setter injectionとかauto wiredとか
    • これらを理解する前にBean定義ファイルを勉強せよ

  • 現在はSpring Bootのアノテーション(@Service / @Autowired / @Repository)で簡単
    • XML Beam定義ファイルも不要

  • Bean定義ファイルを使っての開発はSpringの基礎なので、しっかり勉強しておくことがオススメ!
    • 金融案件なんかではまだ使っているところもある

Spring 歴約1年初心者の Test 奮闘記

概要

Springを使った開発におけるTestの自動化方法について説明してくださいました。

所感

Springもよく知らない、Testもよく知らない状態から実際に仕事で使えるところまで成長されたところが素晴らしいと思いました。
SpringやTestをあまり知らない人向けに説明してくれていたので分かりやすかったです。

メモ

  • 今までスクショ、エクセルのTestばかりやってた・・
    • JavaのTestディレクトリの存在も知らず
    • ⇒Unit TestをJUnitで書けば、何度でも楽にテストができる!

  • 依存している未完成のクラス多くてmockないとTestきついとき
    • Mockitoを使ってMockitoJUnitRunner.classを差し込めばいける

  • @Mock / @InjectMockを使ってTest対象のクラスをUnit Testする

  • SpringRunnerとは?
    • Bean同士の連携テストを行いたい、テスト上でDIコンテナを活用したいときに使用する機能
    • @RunWith(SpringRunner.class)をおまじないとして書く

  • @WebMvcTestで仮想Web層をたててレスポンスステータスのチェックTestとかできる

  • MockMvcResultMatchers.jsonPathでjsonのエラーメッセージのチェックも可能

  • データベースへのIntegration Test
    • DB接続は@DataJpaTestでTest
    • DBのTestにはデータがいるのでH2という内臓DBでデータをつくる

  • SpringRunnerを使用することでテストの幅が広がる (Web MVCいける)
    • SpringでのUnitTestは書きやすい(一年初心者の私でも書けた!)

Spring Boot × Vue.jsでSPAを作る

概要

まさにタイトルの通りですが、ご自身が作成されたSpring Boot + Vue.jsのアプリ構成や構築するまでの流れを解説していただきました。

所感

登壇者の方も言っていましたが、平成最後に聴いたプレゼンとなりました。
そう思うと感慨深いです。
仕事的にタイムリーな内容だったので楽しく聴かせていただきました。
いまどきはVueでSPAつくって処理はフロントエンドに寄せるんだよ、なんて話をどこかで聞いていはいましたが、まさにそのような構成になっていてだいぶイメージが湧きました。

メモ

  • SPAとは?
    • Single Page Application = 単一ページのみで構成されたWebサイト
    • 従来のクラサバのリクエストレスポンスとは違い、クライアントサイドのJSが動的に画面差分の更新を行う
    • (JSはAjax or WebSocketでAPIリクエストを送り、変更があったら更新)

  • 構成は?
    • クライアント <-> Vue.js <-> Spring Boot <-> Mybatis <-> MySQL

  • やったことの流れ
    • (1)Spring Bootプロジェクトの雛形作成
    • (2)Spring Bootに書くAPIの機能を実装
    • (3)Spring Security認証周りを整備
    • (4)Vue.jsで画面周りを実装
    • (5)Vue.jsのビルド媒体をSpring Boot内に配置
    • (6)Spring Bootだけでアプリ起動可能に

  • (1)Spring Bootプロジェクトの雛形作成
    • Spring Initializrで雛形を作成 
    • Webページからさくっと雛形を作れる

  • (2)Spring Bootに各APIの機能を実装
    • Spring BootはREST APIサーバという立ち位置
    • Controllerクラスに@RestControllerを付けた
    • 画面遷移、画面表示はサーバサイドに持たせない
    • サーバサイドでHTMLをつくらない、Thymeleafは使わない
    • APIサーバという立ち位置なので、クライアントとは疎結合な関係

  • (3)Spring Security認証周りを整備
    • Spring SecurityでAPI呼び出し時に認証トークンがないものは、受け付けない
    • ログイン用APIだけは、認証トークンなしでもアクセス可能にした (/loginだけ)

  • (4)Vue.jsで画面周りを実装
    • 画面表示/更新(vue)
    • 画面遷移(router) ⇒controller的なやつ
    • 画面操作に応じたRestAPIの呼び出し(actions) ⇒Ajaxリクエスト・レスポンス
    • 画面表示を司るデータの管理・更新 (state・mutations)
    • state⇒ユーザ情報とか画面上のデータ一覧情報とか
    • mutations⇒stateに一元的にアクセスし、アクセスログを管理  
  • (5)Vue.jsのビルド媒体をSpring Boot内に配置
    • SPAの資産の配信方法の選択肢はどんなものがあったか?
      • ①nginxやApacheで配信
      • ②Spring Bootで配信
    • 今回は②を採用 (利用者数が少ないのでSpring Bootだけでシンプルに)
    • クライアントのビルド成果物(html,css,js)の出力先をSpring Bootプロジェクトのsrc/main/resources/staticに設定
    • Gradleでビルド(npm run build)を実行するように設定
    • 静的ファイルも内包したjarファイルが完成

  • (6)Spring Bootだけでアプリ起動可能に
    • あとは java -jar xxx.jarで起動するだけ
    • Spring Securityとして静的ファイルへのアクセス許可が必要

  • はまりどころ
    • 問題: セッションが切れてもログアウトされない(SPAだと認証トークンの有効期限が切れても、画面遷移できてしまう)
    • 対策: 遷移前にトークンが有効かどうかチェックするためにサーバにリクエストを送るようにした

  • ユーザ情報はクライアントサイドでどう管理する?
    • stateで一元的に管理する

  • APIそものの管理はどうしてる?
    • 今回はSpring BootのControllerクラスに書いているだけ
    • クラスに書いているだけだとフロントとバックエンドで会話できないのでAPI仕様書は書いた

  • セッション管理はVue.jsの設定等でも実現できるのでは?
    • サーバ再起動時などサーバとクライアント側で整合性が取れなくなる場合もあると考え、同期がとれる方式にした

資料

まだ公開されていないようなので追って更新します。


以上。

【忘却のJava#6】IntelliJ IDEA + Spring BootでHello Worldしてみる

Webアプリをつくる必要が出てきたのでSpring Bootを試してみました。

やりたいこと

Spring Boot環境を構築し、WebブラウザからHello Worldを表示する

環境情報

  • 作業端末 (Windows10)
  • IntelliJ IDEA ver2019.1.1 (コミュニティ版)
  • Gradle 5.2.1 (Intellij IDEA同梱)
  • Open JDK 11
  • Spring Boot 2.1.4

流れ

  1. IntelliJ IDEAをWin10にインストール
  2. Spring InitializrにWebアクセスし、プロジェクトの雛形をつくる
  3. つくったプロジェクトをIntelliJ IDEAから開く
  4. IntelliJ IDEA上でjava(コントローラ)とhtmlを書き、プログラムを実行する
  5. ブラウザからWebアクセスする

IntelliJ IDEAのインストール

 - Community版の「Windows, JBR 11 (.exe)を選択

  • exeを実行し、インストールを開始する

 - 全部デフォルト設定で[next]で進めていき、[install]ボタンを押下する
 - 10分くらいかかる

  • プログラムを開き、以下の通り進める

 - Import IntelliJ IDEA Settings From..というページが開くので、[Do not import settings]を選択する
 - Privacy Policyに同意する
 - Data Sharingで[Don't send]を選択する
 - UI themeで好きなテーマを選択する
 - [Skip Remaining and Set Defaults]を選択すると以下のようなメニュー画面が開く

f:id:wingfair:20190424213704p:plain
IntelliJ IDEAメニュー

OpenJDKのダウンロードとPath設定

 - 今回は「11.0.2 Windows 64-bit」を選択する

  • ダウンロードができたらzipを解凍し、jdk-11.0.2フォルダを適当な場所に配置する

 - 今回は「C:\Program Files\Java\jdk-11.0.2」というかたちで配置する

  • システムの詳細設定から環境変数のPathを設定する

 - 今回は「Path」に「C:\Program Files\Java\jdk-11.0.2\bin」を追加する

Spring Initializrによる雛形プロジェクトのダウンロード

 - Project: Gradle Project (変更)
 - Language: Java (デフォルト)
 - Spring Boot: 2.1.4 (デフォルト)
 - Project Metadata:
  - Group: com.example (デフォルト)
  - Artifact: demo (デフォルト)
  - Name: demo (デフォルト)
  - Description: Demo project for Spring Boot (デフォルト)
  - Package Name: com.example.demo (デフォルト)
  - Packaging: Jar (デフォルト)
  - Java Version: 11 (デフォルト
 - Dependencies:DevTools / Lombok / Web / Thymeleaf / JDBC
  (後でbuild.gradleにて編集できるので、ひとまず必要になりそうなものを選ぶ)

画面上は下図のようになる。

f:id:wingfair:20190424213808p:plainf:id:wingfair:20190424213839p:plainf:id:wingfair:20190424213843p:plain
Spring Initializrの画面

  • [Generate Project]を押下し、zipファイルをダウンロードする
  • zipファイルを解凍し、ワークスペースに配置する

 - 今回は「C:\work\demo」に配置する

雛形プロジェクトを開き、Gradleビルドの実行

 - [Welcome to IntelliJ IDEA]メニューの[Open]を押下する
 - 「C:\work\demo」を選択し、[OK]を押下する

f:id:wingfair:20190424213950p:plain
demoをオープン

  • [Import Project from Gradle]の画面が表示されたら、[Gradle JVM]にて先ほど配置したJDKのパス「C:\Program Files\Java\jdk-11.0.2」を指定して[OK]を押下する

f:id:wingfair:20190424213953p:plain
Java指定

  • [Tips of the day]が表示されるので[Close]を押下する
  • アノテーション機能を有効化する

 - Crtl+Alt+SでSettings画面を開く
 - 下図の通り「Enable annotation processing」のチェックを入れ、[OK]を押下する

f:id:wingfair:20190424214011p:plain
アノテーション有効化

 - 左ペインの[build.gradle]をダブルクリックすると新しいバージョンのGradleを使用してビルドすることを推奨されるので、[OK, apply suggestion!]を押下する
 - 10分くらいかかる

f:id:wingfair:20190424214432p:plain
Gradleアップデート

コントローラとHTMLの追加

  • 「com.example.demo」配下に「HelloWorld」パッケージを追加し、その配下に「HelloWorldController.java」を作成する
  • 「resouces/templates」配下に「HelloWorld.html」を作成する
  • 「HelloWorldController.java」と「HelloWorld.html」はそれぞれ以下のように記述する

HelloWorldController.java

package com.example.demo.HelloWorld;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloWorldController {

    @GetMapping("/helloworld")
    public String HelloWorld() {
        return "HelloWorld";
    }

}

HelloWorld.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello World</title>
</head>
<body>
    <h1>Hello World!</h1>
</body>
</html>

IntellJ IDEA上ではこのようになります。

f:id:wingfair:20190424214558p:plain
IntelliJ IDEA上のコード

アノテーションによるコントローラの実装

「@Controller」と「@GetMapping」を書くだけで、コントローラを実装できます。
それぞれのアノテーションの意味は以下の通りです。

@Controller

これをクラスの前に書くだけで、Spring Bootがそのクラスをコントローラとして認識します。

@GetMapping

クライアントからのリクエストに対してGETメソッドをマッピングします。
「@GetMapping("/helloworld")」の"/helloworld"はリクエストURLを指します。
「return "HelloWorld"」の"HelloWorld"はView名を指します。
この View 名は クライアントに返却されるViewのファイル名(htmlファイル)に変換されます。

アプリケーション実行

ここまで来たらあとは実行するだけです。

  • Intellij IDEAにてDemoApplicationを選択し、[Run 'DemoApplication.main()']を押下する
  • 以下の通り、[Started DemoApplication...]と表示されれば起動成功

こんな風にSpringの文字が出ます。
(これは少し崩れてますが・・)

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.4.RELEASE)

2019-04-24 01:17:39.645  INFO 8464 --- [  restartedMain] com.example.demo.DemoApplication         : Starting DemoApplication on DESKTOP-ROVHDC9 with PID 8464 (C:\work\demo\out\production\classes started by wingg in C:\work\demo)
2019-04-24 01:17:39.645  INFO 8464 --- [  restartedMain] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2019-04-24 01:17:39.724  INFO 8464 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2019-04-24 01:17:39.724  INFO 8464 --- [  restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2019-04-24 01:17:41.626  INFO 8464 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-04-24 01:17:41.657  INFO 8464 --- [  restartedMain] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-04-24 01:17:41.657  INFO 8464 --- [  restartedMain] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.17]
2019-04-24 01:17:41.801  INFO 8464 --- [  restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-04-24 01:17:41.801  INFO 8464 --- [  restartedMain] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2077 ms
2019-04-24 01:17:42.082  INFO 8464 --- [  restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-04-24 01:17:42.379  INFO 8464 --- [  restartedMain] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2019-04-24 01:17:42.457  INFO 8464 --- [  restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-04-24 01:17:42.457  INFO 8464 --- [  restartedMain] com.example.demo.DemoApplication         : Started DemoApplication in 3.311 seconds (JVM running for 3.917)

ブラウザでの動作確認

f:id:wingfair:20190424211550p:plain
HelloWorld成功画面

実はこの前に1度エラーで実行に失敗してます

エラー事象

DemoApplicationを実行後、以下のエラーが発生し、起動に失敗しました。

2019-04-24 01:03:24.778 ERROR 8712 --- [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class


Action:

Consider the following:
	If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
	If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).

Class transformation time: 0.049822762s for 5710 classes or 8.725527495621715E-6s per class

Process finished with exit code 0

エラー内容の調査

エラー文言でググると以下の記事がヒット。
データソースの自動設定を無効化すると解消されるという内容です。

StackOverFlow
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. SPRING

原因

不明です。
というか今回やりたいことに対して本質的な問題ではないので、詳しくは調べていません。
何となくですが、Spring Bootとして基本的な挙動なのか、JDBCをDependenciesに追加しているせいなのかで、データストアに関する設定が事前にできていないとエラーになると思われます。

対策

上記の記事に書いてあるとおり以下のコードをDemoApplication.javaに追加しました。
追加後、改めて実行するとエラーが解消し、無事に起動成功しました。

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

【とはメモ#3】「Spring Boot」とは?

Spring Bootを使ってWebアプリを作ることになりそうなので、調べておくことにしました。

「Spring Boot」とは?

  • Javaを使ったWebアプリケーション開発を簡単にするためのフレームワーク
  • アプリケーションをつくるために必要なライブラリ群をまとめたSpring Frameworkをコア技術としている
  • Spring Frameworkベースのアプリケーションを素早く簡単に作成、実行、配布するためのサポート機能を提供する

具体的にどんなことができるのか?

  • ライブラリ群とコードの雛形が用意されており、一からコーディングする必要がない
  • アノテーション(注釈)を記述するだけでWebAPI等が実装でき、コード量を削減できる
  • Spring Frameworkでは必須だったXMLファイルによる複雑な設定(DB接続情報など)が不要になった
  • Tomcat、JettyなどWebコンテナをjarに内蔵することで、jar単体でWebアプリケーションが実行できる

まだ使ってないので、ピンと来ていないところもあります。
そもそも今回は書かなかったですが、Spring Frameworkの概念としてDIとかAOPとかBeanとか何じゃそれ状態なので勉強しないとですね。
実際使ってみたら、所感を書きたいと思います。