yamashiro0110の日記

yamashiro0110の日記です。おもにIT技術のメモを綴っていきます(^o^)

SpringBoot入門


SpringBoot入門してみた

Spring Boot + Thymeleaf


環境

Mac OS X

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.10.4
BuildVersion:   14E46

Java

$ java -version
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)

以下のページを参考にしましたm(__)m

qiita.com qiita.com

  • Spring Data JPAでの実装について

qiita.com

  • Thymeleafの日本語ドキュメント

http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf_ja.htmlwww.thymeleaf.org

  • Spring MVCについて

d.hatena.ne.jp

個人でこれだけまとめるとかすごすぎ・・・

  • Springをより詳しく知りたいときに読む

m12i.hatenablog.com http://terasolunaorg.github.io/guideline/5.0.1.RELEASE/ja/terasolunaorg.github.io

  • 公式ドキュメント(英語)

spring.io

  • アプリケーションの設定値

http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.htmldocs.spring.io

  • 書籍


試しに、簡単なアプリケーションを作成してみた。

github.com


メモ. その1

Spring Securityで、どうやって認証が行われるのかよくわからなかった。

認証の設定は、SecurityConfigでしている。

protected void configure(HttpSecurity http)にて、アクセス認証の設定をしている。

public void configure(WebSecurity web)では、セキュリティの設定対象外として設定している。

protected void configure(HttpSecurity http)内でも、 .antMatchers("/login/form").permitAll()で同じようなことをしているが、 違いがわかっていない。。。

static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapterが、一番謎だった。

ざっくりと動作を記述する。

ログイン画面(/login/form)からFormが送信されると、 リクエストパラメータであるmailの値がLoginUserDetailService#loadUserByUsername(String username)に渡される。

この時、usernameを元にリポジトリ(DB)から対象のデータ(レコード)を取得する。 取得結果が、nullならば存在しないユーザーIDなので例外をthrowする。

存在する場合は、org.springframework.security.core.userdetails.Userを継承した、LoginUserDetailインスタンスを返す。 LoginUserDetailコンストラクタには、引数として取得したAuthUserインスタンスを設定する。

LoginUserDetailコンストラクタ内では、org.springframework.security.core.userdetails.Userコンストラクタを呼び出している。 呼び出しているコンストラクタの引数は、User(String username, String password, Collection<? extends GrantedAuthority> authorities)となっている。 1, 2番目の引数は見ての通り、username, passwordになっている。

この値が、Formで送信された値と比較される。 パスワードは、SecurityConfig.AuthenticationConfiguration#init(AuthenticationManagerBuilder auth)内で 設定したpasswordEncoder(getPasswordEncoder())によって暗号化されて比較されるぽい。

Collection<? extends GrantedAuthority> authoritiesについては、 よくわかってないが認証したユーザーの権限を渡しているみたい。

わかったら追記。。。

LoginUserDetailについて

  • LoginUserDetailは、org.springframework.security.core.userdetails.Userを継承したクラス
  • org.springframework.security.core.userdetails.Userは、org.springframework.security.core.userdetails.UserDetailsの実装なので、拡張(継承)して使う
  • org.springframework.security.core.userdetails.UserDetailsは、認証ユーザーの情報を取得するためのAPIを定義したinterface

メモ. その2

CSRFについて。

Spring Securityを有効にすると、デフォルトでCSRF対策が有効になるが、 Thymeleaf側で、正しくform要素を定義しないといけない。

以下のように、<form> ~ </form>th:action属性を追加することで、 自動的に<input type="hidden" name="_csrf" value="e5521ea3-3cc5-4be4-84a5-7acd9ce10987" />のような トークンがリクエストパラメータとして追加される。

<form th:action="@{/xxx/xxx}" method="xxx">
    ~
</form>

正しく設定されてない場合は、403でエラーとなる。


メモ. その3

Thymeleafでの、バリデーションエラーの表示について。

見たほうがわかりやすい。

<form th:object="${user}" th:action="@{/user/input}" method="POST">
    ~ 省略 ~
    <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">error</p>
    ~ 省略 ~
</form>

上記について。

  • th:if="${#fields.hasErrors('name')}"

    • userオブジェクトのnameフィールドにエラーが存在するか
  • th:errors="*{name}"

    • nameフィールドのエラーを表示する

Thymeleafがオブジェクトのプロパティにアクセスする場合は、 getXxxisXxxxメソッドに対して、xxxという名前に変換してアクセスするので、 アクセスするプロパティにはGetterが必要。

ex) user.name <- user.getName()

なので、Getterメソッドだけ定義してフィールドを宣言しなくてもOK。

ex) sample.user.auth.domain.AuthUser#isCheckPassword

この辺の実装は↓

  • sample.user.controller.UserController#confirm
  • src/main/resources/templates/user/form.html

SpringBootを使ってみて

Springの面倒な設定がいらない。

Springのみの場合、xmlとかannotationでいろいろ設定しないといけない

最初、理解するためにSpringだけでやってみようとしたけど、設定で躓いて諦めた。。。

ライブラリを追加する場合でも、SpringBootがよしなにやってくれるのでかなり楽。

組み込みのWebサーバがある。

ビルドしたらjarが作られるので、配置先のサーバでjava -jar xxx.jarでAPサーバが立ち上がる(!) Gradleだと、gradle bootRunで一発(!)

Annotationつけるだけで、全部設定してくれる。

ある程度わかってくると楽になっていいけど、初めはつらいかも。。

How Google Worksを読んだ

How Google Works (ハウ・グーグル・ワークス)  ―私たちの働き方とマネジメント

How Google Works (ハウ・グーグル・ワークス) ―私たちの働き方とマネジメント

Googleがどのようにしてこれまでの成功を収めたのかについて書かれている本。

現在のインターネットによる変化が著しい時代(本の中では、"インターネットの世紀"と呼ばれてる)で成功するためには、 プロダクトの優位性が必要で、それがあればユーザーを獲得することができるし、あとから利益もついてくる。

プロダクトの優位性を得るには、既存の市場を参考にするのではなく これまでにない技術的アイデアによって実現されることが成功の鍵。

ex) Gmailだと、今までメールソフト使うのが常識だったけどブラウザで出来るようなったとかかな

ユーザーに焦点を絞るというのも、プロダクトの優位性を保ち続けるためのもので、ユーザーにとっての価値が最優先。

そのプロダクトを実現するには、専門性と実現力を備えたとても優秀な人材が必要で その人材のことが"スマートクリエイティブ"と呼ばれている。

スマートクリエイティブを獲得するために、 Googleは採用を経営者の一番重要な仕事だと考えていて、 中には"自分より優秀な人間を採用せよ"というルールがあるらしい。


ほかにもイノベーションや組織のマネジメントについても書かれており、 人材についてはGoogleみたいな企業しか出来ないこともあると思うけど(破格の報酬とか・・・)、 Googleが実践してきた手法を学べる良い本だと思いました。

PlayFramework2.3(scala)でDBアクセスをするときのめも


Play + ScalaでDBアクセスのめも


環境

  • Play2.3

  • Scala 2.10.2

  • MySQL 5.6

    • 今回利用したテーブルとデータは、事前に手動で作成ずみ

DDLは↓

本来はEvolutionを利用して作るものだけど、今回は直接作成した・・・

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `mail` varchar(255) NOT NULL,
  `password` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `mail_UNIQUE` (`mail`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8

設定

SQLアクセスをするために、anormを使う

build.sbtの設定

必要なライブラリを追加

jdbc, anorm, "mysql" % "mysql-connector-java" % "5.1.34"

libraryDependencies ++= Seq(
  jdbc,
  anorm,
  cache,
  ws,
  "mysql" % "mysql-connector-java" % "5.1.34"
)

application.confの設定

DB接続設定の追加 それぞれ以下の変数は自分の環境に適宜変更する

HOSTNAME, SCHEMANAME, USERNAME, PASSWORD

db.default.driver=com.mysql.jdbc.Driver
db.default.url="jdbc:mysql://_HOSTNAME_/_SCHEMANAME_"
db.default.user="_USERNAME_"
db.default.password="_PASSWORD_"

実装

Scalaの場合、Javaと違ってモデルを扱うためのライブラリがないみたい

Slickというライブラリが時期バージョンでデフォルトになるとかならないとか・・・

初めはSlickを試していたけどうまく動いてくれなかったので断念して、 anormを利用してみたところ使い勝手が良かったのでanormを利用することにした

モデルは、Javaと同様にapp/models以下に作成していく

anormではモデルを作成するパッケージなどに特に縛りはなく、 コントローラにSQLを書いたりしても問題ないが、アレだと思うのでapp/models以下に作成していく

実際のソース

https://github.com/yamashiro0110/Play-ScalaSample/blob/master/app/models/User.scala


ハマった点.1: ~って何?

~については、以下のページに解説があった

http://libro.tuyano.com/index3?id=1069003&page=5 ここでの「~」という記号は、Anorm特有の機能で、値をリスト化する働きをします。例えば、A~B~Cとすると、((A, B), C)というようにまとめられます。こうしてまとめたものを元にMydataオブジェクトを生成するのが、その後のmap部分です。


ハマった点.2:object User.dataが何なのかよくわからない

dataについては、SQLの実行結果をオブジェクトにパースするためのものみたい

以下のコードだとSQL(SQL文).on(条件).as(パーサ.戻り値)となっている

  def findById(id: Long): Option[User] = {
    DB.withConnection { implicit c =>
      val sql = "SELECT * FROM user WHERE id = {id}"
      SQL(sql)
        .on("id" -> id)
        .as(User.data.singleOpt)
    }
  }

戻り値をOption[User]にしたのは、指定されたIDがテーブルに存在しない場合にエラーが発生したため

パーサ(data)からOption[User]を取得するためには、singleOptを呼び出せばいい

Userを取得したい場合は、singleでいける


Userモデルを呼び出している部分はapp/controllers/SampleControllerになっている

変数usrに、IDが1のUserを探して代入、存在しない場合はUser.notFoundを代入している

レスポンスはCall SampleController index!! ->という文字列にusr.nameを追加して返しているだけ

  def index = Action {
    val usr = User.findById(1).getOrElse(User.notFound)
    Ok("Call SampleController index!! -> " + usr.name)
  }

Play + JavaのEbeanがクソ便利だったので、 Play + Scalaにはなかったことを知ったとき(とSlickを断念したとき)はJavaに戻ろうかと考えたけど、 anormもなかなか使いやすかったので今後もPlay + Scalaを利用していきたいと思った

あと、今回のソースをGitHubに上げました^^;

github.com


参考にしたページm(__)m

ScalaDatabase

Model(モデル)を使ってデータベースアクセスする[Scala編](1/7):Herokuで始める 初心者のためのPlay Framework入門

Scala Optionメモ(Hishidama's Scala Option Memo)

stackoverflow.com

リーン・スタートアップを読んだ

印象にのこったところ

  • 顧客にとっての価値のあるもの以外はすべて無駄である
  • 起業とはマネジメントである
  • 仮設と検証による学びを繰り返して、製品を価値あるものに成長させる
  • ピボット(方向転換)
  • MVP(実用最小限の製品)
  • 小さなバッチサイズ

今まで起業については、「当たれば成功」「外れたら取り返しがつかないほどの失敗」といった 超ハイリスクなギャンブルのようなものだと思っていた。

この本を読むことで起業した場合に、 リーンスタートアップではどのように仕事を 進めるべきなのかが実例をもとに解説されているため、 起業はギャンブルであるという印象はなくなった。

ただ、起業して本当に成功するためには努力と情熱が必要だし、 ほかにもまだまだ知らなければならないことがあると感じた。

YahooBB With フレッツ光でインターネットに接続できなくなったときのめも

家のインターネット回線をauひかりから、YahooBB フレッツ光に乗り換えたのだけど オプション解約などするとネットにつながらなくなったので、そのときの対応をメモ・・・


つながらなくなった経緯

2015/03/26に自動音声案内にそって、すべてのオプション解約手続きをしました。 (てかサポートがまじで電話とらん、ネット上では8時間掛けっぱなしにしても取らなかった人もいるとか・・・)

以下のページに記載の番号 http://ybb.softbank.jp/support/inquiry/hikari/301i.html

月が変わって、4/1に・・・

朝、スマホFacebookやらInstagramのアプリを開くとネットワーク接続エラー・・・

ルータを再起動したりしてみるも、変わらず・・・


対応したこと

とりあえずルータにログイン(ルータはフレッツ光のもの)

自分のとこでは、http://192.168.1.1へアクセスするとBasic認証が行われたが、 メッセージにID,PWらしきものが記載されてたので、それでログインできた

"情報" > "障害ログ"とリンクをたどると、ルータのログがあった

以下ようなメッセージがあった

66. 2015/04/02 20:11:31 PPPの認証失敗[メインセッション]
67. 2015/04/02 20:11:31 PPP-LCPの確立[メインセッション]
68. 2015/04/02 20:11:31 PPPoE セッション開始成功[メインセッション]
69. 2015/04/02 20:11:31 PPPoE AC発見成功[メインセッション]

PPPの認証失敗だと・・・!? (PPP接続の認証情報とか見覚えがないし・・・)

家のPCでは、ネットがつながらないのでひたすらスマホでググってると PPPoE接続のID・パスワードの変更を行えるページにヒット(この間、約2日・・・)

https://ybb.softbank.jp/member/yf/index.php このページを表示するにも、契約時に発行されたYahooIDでのログインが必要

今回はPWがわからなかったので、PWだけ変更

変更が完了したら再度ルータの設定画面へ行き、PPPoE接続の設定を行う

基本設定 > 接続先設定(IPv4 PPPoE) > メインセッション

PPPoEのIDが'xxxxxxxxxxxx@sbb.ne.jp'のようになってたので、以下のように設定

接続先名:xxxxxxxxxxxx(IDがメールアドレスになってたのでアカウント部分を設定)
接続先ユーザー名:xxxxxxxxxxxx@sbb.ne.jp
接続パスワード:xxxxxxxx(先ほど設定したPW)

入力したら"設定"ボタンを押す

再度、"障害ログ"を見ると以下のログが・・・

  1. 2015/04/02 20:15:37 PPP-IPCPの確立[メインセッション]
  2. 2015/04/02 20:15:37 PPPの認証成功[メインセッション]
  3. 2015/04/02 20:15:37 PPP-LCPの確立[メインセッション]
  4. 2015/04/02 20:15:37 PPPoE セッション開始成功[メインセッション]
  5. 2015/04/02 20:15:37 PPPoE AC発見成功[メインセッション]

認証成功キタ━━━━(゚∀゚)━━━━!!

https://www.google.co.jp/にアクセスすると、表示された!

一件落着( ´ー`)フゥー...


まとめ

YahooBBのオプションである光BBユニットを解約すると(?) PPPoEの認証設定を変更しないといけないぽい・・・

ネットつながらないから、サポートに電話してるってのに 全然とらないってどういうことだってばよ・・・ (WEBで手続き出来ますとか言ってるし)

光BBユニット解約したら認証設定必要とか聞いてないし、 オプション解約時の影響とか手元の資料見ても全然わからんし・・・ (この辺は確認不足もあるかも)

おかげで、スマホの通信料を無駄遣いしてしまった・・・

いろいろと文句が多くなっていますが、 同じような現象で困っている人の助けになれば幸いです(-_-;)


Written with StackEdit.

PlayFrameworkインストールめも

f:id:yamashiro0110:20150320055919p:plain


Play2.3を対象にしてます

言語はJava


環境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.10.1
BuildVersion:   14B25
$ java -version
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

Activatorのインストール

ここからDL

今回は/Application以下に配置

以下のファイルにパスを通す

/Applications/activator-1.2.2-minimal/activator

プロジェクトを作成

プロジェクト用のディレクトリ作成&移動

mkdir /path/to/play && cd /path/to/play

プロジェクト作成

activator new

対話式で進んでいくので、質問に答えていけば問題なく作成されるはず 今回はplay-javaを選択


起動してみる

cd /path/to/play
activator run

初回実行だからか、ライブラリのDLが始まった 30分くらいかかった気がする・・・

ブラウザで以下のURLにアクセスしてみる

http://localhost:9000


参考

https://www.playframework.com/documentation/ja/2.3.x/Installing

CakePHPのインストールめも

f:id:yamashiro0110:20150119013230p:plain


CakePHPの環境構築のめも(ちょっとハマった・・・)

環境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.10.1
BuildVersion:   14B25
Server version: Apache/2.4.9 (Unix)
Server built:   Sep  9 2014 14:48:20
CakePHP 2.6.1

インストール

CakePHPのダウンロード

Gitでclone

$ cd /path/to/CakePHP
$ git clone git://github.com/cakephp/cakephp.git

Apacheの設定

ここでドキュメント通りにやってもうまく行かなかったためCakePHP用に以下の設定を行う

  • ポートを10080に設定
Listen 127.0.0.1:10080

<VirtualHost 127.0.0.1:10080>
    # CakePHPを'git clone'したディレクトリの'app/webroot'を指定
    DocumentRoot    /path/to/CakePHP/cakephp/app/webroot
    ServerName      127.0.0.1:10080
    ServerAdmin     webmaster@host.example.com

    <IfModule php5_module>
        AddType application/x-httpd-php .php
    </IfModule>

    <IfModule dir_module>
        DirectoryIndex index.php
    </IfModule>

    # CakePHPの公開用ディレクトリ'app/webroot'を'/'にマッピング
    Alias / /path/to/CakePHP/cakephp/app/webroot/

    <Directory "/path/to/CakePHP/cakephp/app/webroot/">
        AllowOverride None
        Options All
        Require all granted
    </Directory>
</VirtualHost>

2015/01/27 追記

DocumentRootには、Cakeのapp/webrootを指定すること

コントローラを作成したときに、そのコントローラのURLにアクセスできなかったため

上記、設定後にApache再起動

以下のURLにアクセス

http://localhost:10080/

公式のチュートリアルだと、以下のように記述されていたのですが これだとリダイレクトループが発生するためエラーが発生していました

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteRule    ^$ app/webroot/    [L]
    RewriteRule    (.*) app/webroot/$1 [L]
</IfModule>

参考

URLリライティング — CakePHP Cookbook 2.x ドキュメント