親バカエンジニアのナレッジ帳

webのエンジニアをやっており、日頃の開発で詰まったことや書き残しておきたいことを載せています。育児のイロハという育児サイト(https://ikujip.jp)の開発も行っているため、その開発で使用されている技術についても掲載しています。

AWS(EC2)でセキュリティグループの設定方法

AWS(EC2)のセキュリティグループ

AWS(EC2)ではセキュリティグループというものを設定しますが、その名の通りセキュリティに関しての設定になります。
グループって何?って感じですが、設定したセキュリティは使い周りができるのです。
例えばWEBサーバではセキュリティグループAをDBサーバではセキュリティグループBを...
というように、役割ごとにグルーピングしてセキュリティルールを設定できたりするので、「グループ」となっています。

使う場面としては、ポート開放やIP制限をかけたりする時などになります。
CentOSではiptablesなどでファイアウォールの設定ができたりしますが、AWS(EC2)ではセキュリティグループの編集で設定が可能です。

ポート開放をしていないと以下ようなことも起こりうるので要注意ですね。


設定方法

色々ぼかしてわかりずらいかもですが、EC2のインスタンス一覧画面でインスタンスを選択するとどのセキュリティグループを使用しているのか表示されます。

f:id:tomotomo1129:20180712150641p:plain

EC2を作成した時に自分でセキュリティグループを作成していなくても、自動でセキュリティグループが作成され、デフォルトではポート22(SSH)のみ開放されている状態です。

セキュリティグループのリンクになっている箇所をクリックすると編集ページに遷移するので、下のメニューから「インバウンド」->「編集」と進めば自分でルールを追加することができます。

f:id:tomotomo1129:20180712150700p:plain

よく使うものとして、「SSH 22」の他に、「HTTP 80」、「HTTPS 443」、「MYSQL 3306」、「SMTP 25」あたりは追加しておいても良いと思います。
HTTPSMYSQLだけはなぜかちゃんと選択してもタイプ名が「カスタム TCP ルール」になってしまいますが、ちゃんと動作するので大丈夫です。

f:id:tomotomo1129:20180712150715p:plain

「ソース」に関しては、特に接続元を制限する必要がない場合は「0.0.0.0/0」と入れておきましょう。
後々IP制限をしたい場合に変更が可能です。

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門 (CodeZine BOOKS)

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門 (CodeZine BOOKS)

AWS(EC2)でのサーバ構築とキーペア(鍵)を使ったSSH接続

AWS(EC2)でのサーバ構築

AWSでのEC2サーバ構築は非常に簡単にできます。
スペックは高くないですが、1年間の無料枠もあるのでLinuxの操作に慣れたいという方などは勉強がてら触ってみてはいかがでしょうか。

Linuxの操作をするためにはSSH接続をする必要がありますが、AWSでは通常SSH接続をするためにはキーペア(鍵)による鍵認証が必要になります。
ここではAWSの簡単構築と、キーペア(鍵)を使ったSSH接続について記載したいと思います。

※今回は、AWSのアカウントを保持している、または、登録したことが前提で、サーバは簡易的な設定(もちろんwebで使う点では問題ありません)で1台のみ設定するものとします。
また、構築するサーバはCentOS6ベースのAmazon Linuxになります。
CentOS7ベースのAmazon Linux2を構築したい場合も今回のSSH接続までであればほとんど同一手順で進めることができるのですが、途中サーバのタイプを選択する手順でAmazon Linux2を選択するようにしてください。

EC2作成・起動

AWSのアカウントにログインしている状態からスタートします。
まず最初にリージョンが目的の場所になっていることを確認してください。
今回は日本国内向けサービスなので、アジアパシフィック(東京)になっていることを確認します。

f:id:tomotomo1129:20180712133203p:plain:w150

次に、ヘッダーメニューで「サービス」->「EC2」と進みます。

f:id:tomotomo1129:20180712133214p:plain

EC2のメニューページに遷移されますので、サイドメニューの「インスタンス」を選択します。

f:id:tomotomo1129:20180712133228p:plain:w150

次に「インスタンスの作成」をクリックします。

f:id:tomotomo1129:20180712133244p:plain

すると、「ステップ 1: Amazon マシンイメージ (AMI)」の画面でマシンイメージの選択画面に移ります。

AMI は、インスタンスの作成に必要なソフトウェア構成 (OS、アプリケーションサーバー、アプリケーション) を含むテンプレートです。

と記載があるように、どのような構成のサーバを作成するのかを選択する画面なので、ここでの選択はサーバ構築で大きな影響が出ます。
よくよく注意して選択してください。

先述しました通り、今回はCentOS6ベースで構築したいのでAmazon Linuxを選択します。
名前が長くてわかりづらいですが、「Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type」というものになります。
※CentOS7ベースで構築したい場合は1つ上にあるAmazon Linux2を選択してください。

f:id:tomotomo1129:20180712133255p:plain

次にインスタンスタイプの選択になりますが、ここでのタイプはサーバのスペックに関係があります。
以下をご覧いただければ分かると思いますが、それぞれタイプごとにvCPUやメモリの数値が異なってきます。
今回私の方ではt2.smallを選択したいと思います。

無料利用枠で使いたい場合はt2.microを選択してください。

選択したら「確認と作成」を押下します。

f:id:tomotomo1129:20180712133327p:plain

すると一気に「ステップ 7: インスタンス作成の確認」に飛びます。

※このあたりある程度詳しい方は、SSHの接続ができるようにセキュリティグループでポートの22を開放しなくても大丈夫なの?
と疑問に思われるかもしれませんが、インスタンス作成と同時に新しいセキュリティグループが作成され、デフォルトでポートの22だけ開放されているのでこのまま進んで問題ありません。

ちなみに、インスタンスタイプの選択画面で、「次の手順: インスタンスの詳細の設定」をクリックすれば

ステップ 3: インスタンスの詳細の設定
ステップ 4: ストレージの追加
ステップ 5: タグの追加
ステップ 6: セキュリティグループの設定

も設定可能ですが、今回は細かい設定は省略するので、ここでは上記の設定をする必要はありません。

f:id:tomotomo1129:20180712133347p:plain

ここで「作成」をクリックするとキーペア(鍵)に関するモーダルが出現します。

f:id:tomotomo1129:20180712133402p:plain

キーペア名は適当に入力し(今回はaws-keyとしています)、キーペアのダウンロードをクリックしてください。
キーペアをダウンロードすると「インスタンスの作成」がクリックできるようになります。

注意書きの通り、ここでダウンロードしたファイルを失くしてしまうと二度とダウンロードできなくなります。
また、このようなキーファイルは厳重に保管し、絶対に外部に漏れないようにしてください。

インスタンスを作成を押下すれば以下の画面になり、インスタンスが作成されます。

f:id:tomotomo1129:20180712133420p:plain

キーペア(鍵)を使ったSSH接続

上記手順によってインスタンスは起動している状態になるので、あとはSSH接続です。

先ほどダウンロードした鍵を~/.sshに移動させ、権限を付与しましょう。
「~/Downloads/aws-key.pem」の箇所はそれぞれの環境によって

cp ~/Downloads/aws-key.pem ~/.ssh/aws-key.pem
sudo chmod 700 ~/.ssh/aws-key.pem

また、「サービス」->「EC2」->「インスタンス」と進めば起動させたインスタンスの情報が見れます。
作成したインスタンスを選択すればパブリックDNSが表示されるのでコピーしておきましょう。

f:id:tomotomo1129:20180712133436p:plain

あとは以下のSSHコマンドでOKです。

ssh -i ~/.ssh/aws-key.pem ec2-user@ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com

※「aws-key.pem」、「XXX-XXX-XXX-XXX」の箇所は環境によって異なるので、それぞれのキーペア名、パブリックDNSを入力してください。

以下のような画面が出ればSSHでのログインは成功です。

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2018.03-release-notes/
2 package(s) needed for security, out of 2 available
Run "sudo yum update" to apply all updates.


Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA)

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門 (CodeZine BOOKS)

Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門 (CodeZine BOOKS)

Vue.jsのdataプロパティで配列の変更はspliceで置き換えろ!

dataプロパティで配列の定義

ti-tomo-knowledge.hatenablog.com

のページで、Vue.jsではdataプロパティの変更がリアクティブに変化すること、また、それを単なる変数ではなくオブジェクトでも実現させるための方法について説明しましたが、このページではdataプロパティで配列を定義した場合にリアクティブに動作させる方法を説明します。

オブジェクトに続いて、配列でも変更の仕方に注意が必要になるのです。

変更する場合はspliceで置き換え

オブジェクトの変更で使用していた$setと同様、配列でもspliceという使い慣れない関数を使うことになります。
例えばdataプロパティで以下のような定義をした場合、

export default {
  data () {
    return {
      testArray: ['test1-Value', 'test2-Value', 'test3-Value']
    }
  }
}

配列の3番目(インデックスのキーが2)の値をvalueの値のみ「test5-Value」と変更したい場合、いつもの流れだと以下のようにしたくありませんか?

this.testArray[2] = 'test5-Value'

残念ながらこの変更方法では、Vue.jsではリアクティブに動作しないです。
変数の値自体は当然変更できるのですが、リアクティブではなくなり、テンプレートには変化が起きません。
つまり、配列の変更により、テンプレート側でなんらかの動作の変化が起きるようにテンプレートが書かれている場合、このような形で配列を変更してもテンプレートには何ら変化は起きないのです。

オブジェクトの変更同様に元々Javascriptや他の言語に慣れている人ほど、かなりハマりそうですね。
Vue.jsでdataプロパティで定義した配列を変更する場合は、以下のようにspliceを使いましょう。
引数が3つあってわかりづらいかもですが、以下で配列の3番目(インデックスのキーが2)を変更できるのです。

this.testArray.splice(2, 1, 'test5-Value')

配列の3番目(インデックスのキーが2)から数えて1つ目を置き換えという意味です。
使い慣れない関数だと思いますが、これで変更するようにすればリアクティブに変更されます。

削除する場合もsplice

Javascriptでは配列を削除する場合に、削除するキーによってはshift()やpop()を使ったりできますが、Vue.jsでは一律spliceを使いましょう。
例えば先ほどの配列で、配列の3番目(インデックスのキーが2)を削除したい場合、配列の末尾なので以下のようにpop()を使いたくなるでしょう。

this.testArray.pop()

でも、これではリアクティブに変更されないのです。
置き換えだけではなく、削除の場合にもspliceを使えるので、以下のようにしてください。

this.testArray.splice(2, 1)

配列の3番目(インデックスのキーが2)から数えて1つ目を削除するという意味です。


以下のようにすれば、配列の3番目(インデックスのキーが2)から数えて2つ目までを削除するという意味で、まとめて2つの項目を削除できます。

this.testArray.splice(2, 2)

末尾に追加する場合は従来通りpushを使え

dataプロパティの配列に新しい要素を追加する場合は、従来のJavascript同様にpush()を使えば大丈夫です。
以下のような配列が定義されている場合に「test3-Value」を追加したいとします。

export default {
  data () {
    return {
      testArray: ['test1-Value', 'test2-Value']
    }
  }
}

この場合は以下のようにしたくなるのものですが、これではリアクティブに変化しません。

this.testArray[2] = 'test3-Value'


以下のようにpushで追加すればリアクティブに動作します。

this.testArray.push('test3-Value')

多次元配列はループなどで同様に変更可能

以下のように、多次元配列の定義をしている場合も同様にspliceを使えば解決です。

export default {
  data () {
    return {
      testArray = [
        ['test1', 'test2'],
        ['test3', 'test4']
      ]
    }
  }
}

それぞれの配列の2番目(インデックスのキーが1)の値を変更する場合

this.testArray.forEach(array => {
  array.splice(1, 1, 'test10')
})

こんな感じで配列でもリアクティブな動作が可能となります。
慣れるまでは面倒ですが、慣れてしまえば問題ありません。


速習Vue.js 速習シリーズ

速習Vue.js 速習シリーズ

Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))

Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))

React,Angular,Vue.js,React Nativeを使って学ぶ はじめてのフロントエンド開発

React,Angular,Vue.js,React Nativeを使って学ぶ はじめてのフロントエンド開発

Vue.jsのdataプロパティでオブジェクトの変更は$setで置き換えろ!

dataプロパティでオブジェクトの定義

Vue.jsでインスタンスを生成した際、dataオブジェクトに変数を定義した場合のリアクティブな動作についてはご存知だと思いますが、テンプレート内でdataオブジェクトに定義した変数を使用していた場合、変数の中身が変更されるとリアクティブに変更されます。

リアクティブについて詳細に述べるのは別な機会にするとして、簡単に言えば変数が変更されると、それに応じてテンプレート内で使用されている箇所も同時に変更され、変更後の値に応じた振る舞いをします。
単なる文字列(String)や数値(Integer)、真偽値(Boolean)の場合だけではなく、配列(Array)やオブジェクト(Object)の場合も同様です。

「dataプロパティに定義されているオブジェクトの変更 → テンプレートでの振る舞いの変更」と繋がるはずですが、オブジェクトと配列の場合は変更の仕方に注意が必要です。
ここではdataプロパティで定義されたオブジェクトの値を変更する方法について述べます。

変更する場合は$setで置き換え

例えばdataプロパティで以下のような定義をした場合、

export default {
  data () {
    return {
      testObject: {'name': 'test1-Name': 'value': 'test1-Value'}
    }
  }
}

valueの値のみ「test2-Value」と変更したい場合、いつもの流れだと以下のようにしたくありませんか?

this.testObject.value = 'test2-Value'

残念ながらこの変更方法はVue.jsではやらない方が良いです。
変数の値自体は当然変更できるのですが、リアクティブではなくなるのです。
つまり、オブジェクトの変更により、テンプレート側でなんらかの動作の変化が起きるようにプログラムされている場合、オブジェクトを変更してもテンプレートには何ら変化は起きないのです。

元々Javascriptを長く使っていた人ほど、Vueを使い始めた頃はかなりハマるのではないでしょうか。
Vue.jsでdataプロパティで定義したオブジェクトを変更する場合は以下のように$setを使いましょう。

this.$set(this.testObject, 'value', 'test2-Value')

使い慣れない関数だと思いますが、これで変更するようにすればリアクティブに変更されます。

配列中のオブジェクトはループなどで同様に変更可能

以下のように、配列の中でオブジェクトの定義をしている場合も同様に$setを使えば解決です。

export default {
  data () {
    return {
      testObject = [
        {'name': 'test1-Name': 'value': 'test1-Value'},
        {'name': 'test2-Name': 'value': 'test2-Value'}
      ]
    }
  }
}

配列の場合は、配列中のどのキーのオブジェクトを変更すれば良いのか指定する必要があるので、そのような場合はループを使えば変更が可能です。

例1) 配列の2番目(インデックスのキーが1)の場合にvalueを変更する場合

this.testObject.forEach((object, index) => {
  if (index === 1) {
    this.$set(this.testObject[index], 'value', 'test2-Value')
  }
})

例2) nameが「test2-Name」の場合にvalueを変更する場合

this.testObject.forEach((object, index) => {
  if (object.name === 'test2-Name') {
    this.$set(this.testObject[index], 'value', 'test2-Value')
  }
})

こんな感じでオブジェクトでもリアクティブな動作が可能となります。

今回はオブジェクトのリアクティブな動作について記載しましたが、配列についても以下に記していますのでぜひとも参考にしてください。

ti-tomo-knowledge.hatenablog.com

基礎から学ぶ Vue.js

基礎から学ぶ Vue.js

速習Vue.js 速習シリーズ

速習Vue.js 速習シリーズ

Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))

Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))

ThymeleafでJavascriptエラー(SAXParseException)

Thymeleafでのorg.xml.sax.SAXParseException例外

Thymeleafは構文チェックが厳しく、Javascriptなどをそのまま文中に貼り付けると、以下のようなエラーが発生してしまいページが開けないことがあります。

org.xml.sax.SAXParseException: エンティティ"l"への参照は';'デリミタで終了する必要があります。

"l"はあくまで一例であって、Javascriptの内容によって変数名は変わってきます。
この場合ではなんとなくエンティティ"l"という箇所付近を調査しますよね。
でもこのメッセージだけで解決することは難しいです。

エラーが発生したJavascriptの中で、srcなどでURLを入力している箇所はありませんか?
もしあったら、その中で「&」という文字列がないか確認してください。
GETパラメータが複数ある場合などにきっと「&」があるはずです。

Thymeleafでは、「&」はそのままでは使えないのです。

解決方法としては2つあり、「&」をエスケープして使えるようにするか、エスケープしなくても使用できるようにコメントを挿入するかのいずれかになります。

解決方法1 「&」をエスケープ

エスケープする時は、「&」を「&」という文字に置き換えればOKです。

「&」→「&」

<script type="text/javascript" th:inline="javascript">
	(function()
	・
	src='https://www.test.com/test.js?id=1&amp;l=2
	・
	);
</script>

みたいな感じですね。

「&」が連続で複数存在している場合も同様です。
以下のように

「&&」→「&amp;&amp;」

とすれば問題ありません。

簡単と言えば簡単な解決策ですが、「&」がたくさんある場合は、どこをどう変えたのかややこしくなることがあります。

解決方法2 エスケープしなくても使用できるようにコメントを挿入する

Javascriptの前後にコメントを入れても解決できます。
具体的には構文の開始前に

/*<![CDATA[*/

を、構文の最後の後ろに

/*]]>*/

を入れれば大丈夫です。

こんな感じですね。

<script type="text/javascript" th:inline="javascript">
	/*<![CDATA[*/
	(function()
	・
	・
	・
	);
	/*]]>*/
</script>

こうするとThymeleafはJavascriptの構文チェックを無視してくれます。
個人的には解決方法2の方がおすすめですが、お好みの方をお使いください。

TomcatのインストールとCATALINA_OPTSの設定

Java Servlet を動かすために必要なコンテナとしてよく使用されているTomcatですが、Linux環境にインストールする方法としては大きく2つあります。
それぞれの違いはご存知ですか?
インストール方法によって、起動の仕組みが変わるため、CATALINA_OPTSの設定方法も変わってきます。
ここではその違いについて記したいと思いますので参考にしていただければ。

CATALINA_OPTSを設定する場面

Tomcatが起動するJavaVM(JVM)のメモリの割り当てを設定する場合に、CATALINA_OPTSを設定することになります。
メモリの割り当てが少ないと起動時、または、起動中にメモリリークなどが発生してプロセスが落ちてしまうので、割り当てのサイズを変更しておく必要性が出てくる場面があります。

CATALINA_OPTSに指定するパラメータは、とりあえず大体以下のあたりを設定しておけば大丈夫だと思います。
もちろん他にも細かくパラメータの設定はできますが、最初は以下を設定して改善されたか様子を見るのが良いでしょう。

-Xmx 最大ヒープサイズ(最大メモリ使用量)
-Xms 初期ヒープサイズ(初期メモリ使用量)
-Xss プロセスに割り当てられるスタックサイズ(228k以上必要になります)

Tomcatのインストール方法

wgetコマンドなどでソースコードをダウンロードしてからコンパイルする方法

詳細なインストール方法は別途記したいと思いますが、最初にコンパイルされる時はTomcatはデーモン化されておらず、startup.shやcatalina.shなどシェルで起動させることになります。
CATALINA_OPTSの設定に関しては、Tomcatの起動時にシェルファイルに記載されている設定値を読み込ませることになります。

記入するファイルとしてはcatalina.shやsetenv.shになりますが、環境変数はsetenv.shに書きましょう。
catalina.shの中に以下の記述がある通り、もしsetenv.shが存在していれば、勝手に読み込まれて設定値が反映されます。

if [ -r "$CATALINA_BASE/bin/setenv.sh" ]; then
  . "$CATALINA_BASE/bin/setenv.sh"
elif [ -r "$CATALINA_HOME/bin/setenv.sh" ]; then
  . "$CATALINA_HOME/bin/setenv.sh"
fi

上記の記述からもわかる通り、ファイルの場所としてはcatalina.shと同じディレクトリ上に置くことになります。
デフォルトではsetenv.shは存在しないため、自分で作成することになります。
※以下はtomcatのバージョンが8.5.13の時のパターンです。

cd /opt/apache-tomcat-8.5.13/bin
vim setenv.sh

だいぶ省略はしていますが、例としてはこんな感じです。
※設定値は環境と要件に合わせて設定してください。

CATALINA_OPTS="-server -Xmx1024m -Xms1024m -Xss512k"
export CATALINA_OPTS

設定が反映されているか確認したい場合、プロセスを確認してください。

ps aux | grep tomcat

以下はプロセスの例です。

tomcat   23302  1.7 30.4 4193556 1862964 ?     Sl    2017 7778:07 /usr/java/jdk1.8.0_121/bin/java -Djava.util.logging.config.file=/opt/apache-tomcat-8.5.13/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -server -Xmx1024m -Xms1024m -Xss512k -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Djava.endorsed.dirs=/opt/apache-tomcat-8.5.13/endorsed -classpath /opt/apache-tomcat-8.5.13/bin/bootstrap.jar:/opt/apache-tomcat-8.5.13/bin/tomcat-juli.jar -Dcatalina.base=/opt/apache-tomcat-8.5.13 -Dcatalina.home=/opt/apache-tomcat-8.5.13 -Djava.io.tmpdir=/opt/apache-tomcat-8.5.13/temp org.apache.catalina.startup.Bootstrap start

この中に「/usr/lib/jvm/jre/bin/java -server -Xmx1024m -Xms1024m -Xss512k」という記述がありますよね。
これによって設定値が反映されていることが確認できました。

yumでインストールする方法

ここも詳細なインストール方法は別途記載しますが、yumでインストールした場合はTomcatはデーモン化されているため、サービス(プロセス)を起動すればOKです。
ただ、ソースをダウンロードした場合と異なり、yumでインストールした場合はcatalina.shファイルは作られません。
よって、ここでsetenv.shファイルを作成しても読み込まれないため、環境変数などが設定されているtomcat8.confファイルに記入してください。

vim /etc/tomcat8/tomcat8.conf

ファイルの一番下に以下のように記入してください。
※ここも設定値は環境と要件に合わせて設定してください。

CATALINA_OPTS="-server -Xmx1024m -Xms1024m -Xss512k"

あとはtomcatを再起動すれば反映されます。

設定が反映されているか確認したい場合、プロセスを確認してください。

ps aux | grep tomcat
tomcat   28652 61.9 33.0 2223808 336440 ?      Sl   13:36   0:42 /usr/lib/jvm/jre/bin/java -server -Xmx1024m -Xms1024m -Xss512k -classpath :/usr/share/tomcat8/bin/bootstrap.jar:/usr/share/tomcat8/bin/tomcat-juli.jar:/usr/share/java/commons-daemon.jar -Dcatalina.base=/usr/share/tomcat8 -Dcatalina.home=/usr/share/tomcat8 -Djava.endorsed.dirs= -Djava.io.tmpdir=/var/cache/tomcat8/temp -Djava.util.logging.config.file=/usr/share/tomcat8/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager org.apache.catalina.startup.Bootstrap start

この中に「/usr/lib/jvm/jre/bin/java -server -Xmx1024m -Xms1024m -Xss512k」という記述がありますよね。
これによって設定値が反映されていることが確認できました。

Java+MySQL+Tomcatで始めるWebアプリケーション構築入門

Java+MySQL+Tomcatで始めるWebアプリケーション構築入門

スッキリわかる Java入門 実践編 第2版 (スッキリシリーズ)

スッキリわかる Java入門 実践編 第2版 (スッキリシリーズ)

AMPページではてなブックマークのシェアボタンを動的に設置

AMPページではシェアボタンを置きたくなることが多い

もはやwebページでは必ずと言ってもいいくらいシェアボタンを設置しますよね。
影響力のあるユーザに拡散してもらえれば一気にPV数を増やすことができます。

特にAMP対応のページを作る場合、SEOを意識したコンテンツになるため、シェアボタンによりがんがん拡散してもらいたいですよね。

AMPページではSNSのシェアボタンを簡単に設置できる。

AMPを使わないページでも比較的設置は簡単なSNSのシェアボタンですが、AMPページではもっと簡単に設定ができます。
「amp-social-share」タグを使うことで簡単にシェアボタンを設置できるのです。

syncer.jp

のページが対応方法などが非常にわかりやすいですが、

Email、Facebook、LinkedIn、PinterestGoogle+TumblrTwitter、Whatsapp

は公式に対応しているため、何の苦労もなくtypeやURLを入れ込むだけで設置できます。

はてなブックマークのシェアボタンも非公式ではあるがAMPに対応している

上記のSNSに加えて、はてなブックマークのシェアボタンもAMPに対応しているようです。
なかなかブックマークされずらくなったはてブですが、新着エントリーに掲載された時のPV数の増加は未だに爆発力があります。
webサイトを作る場合にとりあえず設置しておきたいと思う人も多いですよね。

はてなブックマークも「amp-social-share」を使えばAMPページで設置可能なのですが、シェアするURL(エンドポイントのURL)を含めなければいけないのでそこがちょっと厄介です。
コードとしては以下のようになります。

<amp-social-share
	type="hatena_bookmark"
	layout="container"
	data-share-endpoint="http://b.hatena.ne.jp/entry/(httpまたはhttpsから始まるURLを入れる)">
B!
</amp-social-share>

(httpまたはhttpsから始まるURLを入れる)の箇所にシェアするURL(エンドポイントのURL)を入れるわけですが、静的ページであれば以下の例のように直接打ち込めば済む話なので何の問題もありません。

<amp-social-share
	type="hatena_bookmark"
	layout="container"
	data-share-endpoint="http://b.hatena.ne.jp/entry/http://example.com">
B!
</amp-social-share>

ところが、自分でCMSを作成するなど、動的にURLを設定したい場合に困ります。

以下のようにURLの箇所に変数を入れ込めばいいのでは?と第一感は思いますよね。

<amp-social-share
	type="hatena_bookmark"
	layout="container"
	data-share-endpoint="http://b.hatena.ne.jp/entry/$URLが代入されている変数">
B!
</amp-social-share>

しかし、この方法では上手くいきません。

AMPページでのはてなブックマークボタンの実装方法

前置きが長くなりましたが、動的にURLの値を設定したい場合の実装方法を説明します。
今回はサーバサイドはSpring BootでThymeleafのテンプレートを使用して説明しますが、他のフレームワークを使用した場合でも実装方法は変わらないはずです。

結論としては、サーバサイド側(Spring Bootの方)で、URLの変数だけではなく、URLを含めたタグを変数に入れてしまい、それをテンプレート側(Thymeleafの方)で展開すれば良いのです。

まずサーバサイド側(Spring Bootの方)です。

// わかりやすくURL全体を固定で入れていますが、実際は最後の「1」の部分だけが動的に変わるパターンが多いと思います。
String url = "https://ikujip.jp/column/1";

model.addAttribute("hatena", "<amp-social-share type='hatena_bookmark' layout='container' data-share-endpoint='http://b.hatena.ne.jp/entry/" + url + "'/'>B!</amp-social-share>");

Spring Bootをご存知ない方も多いと思うので簡単に補足しますと、「hatena」という変数にカンマの後ろのダブルコーテーションで囲まれたタグを値として入れているようなものです。

あとはThymeleafでhatenaの変数を展開すれば問題ありません。

<div th:utext="${hatena}"></div>

ここもThymeleafをご存知ない方のための補足ですが、th:utextで変数を展開すれば、変数にタグが含まれている場合でも自動的にエスケープされるため、タグが反映されることになります。

この実装を行なったページが以下になりますが、
https://ikujip.jp/column/1

ページごとに最後の数字が変わっていく構成です。

要素の検証ではてなブックマークのボタンを見てもらえれば、以下のようにURLが入力されていることがわかると思います。

<amp-social-share type="hatena_bookmark" layout="container" data-share-endpoint="http://b.hatena.ne.jp/entry/https://ikujip.jp/column/1/" class="i-amphtml-element i-amphtml-layout-container amp-social-share-hatena_bookmark i-amphtml-layout" role="button" tabindex="0">B!</amp-social-share>

テンプレートの変数を使えない時点で諦めてしまう人もいるかと思いますが、タグごと突っ込んでしまえば万事解決です!
ちょっと変数が長くなって不恰好ですがw

AMPで色々やっている人はぜひお試しください。

WordPress AMP対応 モダンWeb制作 レッスンブック

WordPress AMP対応 モダンWeb制作 レッスンブック