順次、選択、そして繰り返し

プログラミングのことやITのこと、たまに演劇のことも書きます。

APIGatewayからAWSLambdaを叩く(POST送信)

『サーバーレスアーキテクチャ』という言葉にひかれて、
APIGatewayからAWSLambdaを叩いてみた。
そして、色々詰まったのでメモとして残しておく。


まずはAPIGatewayの設定。

メソッドリクエストの設定。
f:id:sndstudy:20170118005347p:plain

リクエスト本文のコンテンツタイプに
application/x-www-form-urlencoded を設定する。
これを設定することFormの値をPOSTメソッドでも送信することができる。

統合リクエストの設定。
f:id:sndstudy:20170118005833p:plain
f:id:sndstudy:20170118005856p:plain

本文マッピングテンプレートのコンテンツタイプは
メソッドリクエストと合わせる。
また、ここでリクエストボディに詰められた
Formの値を取り出すためにマッピングテンプレートを設定する。

マッピングテンプレートはVTLで記述する。
Velocityの文法 - Javaについて

{
    "headers" : {
        #foreach( $key in $input.params().header.keySet() )
            "$key" : "$input.params().header.get($key)"#if( $foreach.hasNext ),#end
        #end
    },
    "queryParameters" : {
        #set( $tmpstr = $input.body )
        #foreach( $keyandvaluestr in $tmpstr.split( '&' ) )
        #set( $keyandvaluearray = $keyandvaluestr.split( '=' ) )
            "$keyandvaluearray[0]" : "$keyandvaluearray[1]"#if( $foreach.hasNext ),#end
        #end
    },
    "stage" : "$context.stage",
    "sourceIp" : "$context.identity.sourceIp",
    "userAgent" : "$context.identity.userAgent"
}

特にこの部分でFormで送信したkeyとvalueを取り出している。

    "queryParameters" : {
        #set( $tmpstr = $input.body )
        #foreach( $keyandvaluestr in $tmpstr.split( '&' ) )
        #set( $keyandvaluearray = $keyandvaluestr.split( '=' ) )
            "$keyandvaluearray[0]" : "$keyandvaluearray[1]"#if( $foreach.hasNext ),#end
        #end

統合レスポンスの設定。
今回はFormで2つの値を送信し、足し算を行った結果を
htmlで表示するためコンテンツタイプを
text/htmlに設定する。

f:id:sndstudy:20170118010532p:plain

本文テンプレートは以下のように、計算結果を表示するように記述。

<html>
    <head>
        <title>title</title>    
    </head>
    <body>
        <span>$input.path('ans')</span>
    </body>
    
</html>


メソッドレスポンスでは、
統合レスポンスと同様にtext/htmlを設定する。
f:id:sndstudy:20170118010941p:plain

次はLambdaの作成。
今回はNode.jsで作成。

f:id:sndstudy:20170118011146p:plain

exports.handler = (event, context, callback) => {
    
    //値を取得する
    var num1 = parseInt(event.queryParameters.param1);
    var num2 = parseInt(event.queryParameters.param2);
    var answer = num1 + num2;
    
    //レスポンス
    context.done(null, {"ans": answer});
    
};

最後はFormを送信するhtmlを作成。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>LambdaTest</title>

</head>
<body>
    
    <form action="create api url" method="post">
        
        値1:<input type="text" name="param1"><br>
        値2:<input type="text" name="param2">
        
        <input type="submit" name="test">
    </form>

</body>
</html>

実行結果はこんな感じ。
f:id:sndstudy:20170118011543p:plain
f:id:sndstudy:20170118011701p:plain

特に詰まったのは統合リクエストのマッピングテンプレートだった。
VLTは初めてだったので、処理を書くのに時間がかかった。

あと、今回APIを作成したおかげでGETとPOSTのリクエストの中身を
細かく知ることができてよかった。(POSTはリクエストボディがあるなど)


■参考サイト
API Gateway + Lambda にFormからPOSTする時のマッピングテンプレートを作成しました | Developers.IO
[Web] HTTPリクエストの中身を学んでみた。GETやPOSTの違いなど - YoheiM .NET
HTTP入門
Amazon API Gatewayをブラウザから呼んでみた | Developers.IO
パーセントエンコーディング - Wikipedia
application/x-www-form-urlencoded ‐ 通信用語の基礎知識
node.jsのcontext.succeedで気をつけること | hacknote
docs.aws.amazon.com

GoogleMapsAPI リクエスト メモ

var directionsService;
var directionsDisplay = [];
/*緯度*/
var longitude = 35.7102849;

/*経度*/
var latitude = 139.77714030000004;

var map;

var allCount = 1;

var i = 0;

function initMap() {
    var mapdiv = document.getElementById('map');
    
    directionsService = new google.maps.DirectionsService();

    //オプション設定
    var myOptions = {
        zoom: 17,
        center: new google.maps.LatLng(longitude, latitude),
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        scaleControl: true,
    };

    //マップを描画
    map = new google.maps.Map(mapdiv, myOptions);

    //マップ上に線を描く
    drawLine();

}

function drawLine() {
    
    var divisor = 100000;
    
    if(i == 500){
        return;
    }

    var originLatLng;
    // 経由地点を設定 
    var wayPoints = [];

    if (allCount != 1) {
        originLatLng = new google.maps.LatLng(longitude + allCount / divisor, latitude + allCount / divisor);
    } else {
        originLatLng = new google.maps.LatLng(longitude, latitude);
    }

    //waypoints作成
    for (var count = 1; count <= 20; count++) {

        wayPoints.push({
            location: new google.maps.LatLng(longitude + allCount / divisor, latitude + allCount / divisor)
        });

        allCount++;

    }

    var request = {
        origin: originLatLng, //入力地点の緯度、経度
        destination: new google.maps.LatLng(longitude + allCount / divisor, latitude + allCount / divisor), //到着地点の緯度、経度
        travelMode: google.maps.DirectionsTravelMode.WALKING, //ルートの種類
        waypoints: wayPoints
    }

    /* 描画 */
    directionsService.route(request, function (result, status) {
        directionsDisplay.push(new google.maps.DirectionsRenderer());
        directionsDisplay[directionsDisplay.length - 1].setDirections(result); //取得した情報をset
        directionsDisplay[directionsDisplay.length - 1].setMap(map); //マップに描画
    });
    
    i++;
    
    $("#count").empty();
    $("#count").append(i);
    
    setTimeout(function(){ 
        drawLine();
    }, 1000);
    


}

JavaScript bindメモ

aタグに対するbindのメモ

JavaScript

$(function () {
    $("#jump").bind('click', function (event) {
        alert("hoge");
    });
});

HTML

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>JavaScript ClickTest</title>
    <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
    <script type="text/javascript" src="click.js"></script>
</head>

<body>

    <a href="https://www.google.co.jp" id="jump">
        <img src="duke.jpg">
    </a>

</body>

</html>

Mavenメモ(主にpom.xml)

Maven2のpom.xmlの構成 - tanamonの日記

Maven – POM Reference

MavenプロジェクトをTomcatで動かす方法 - Qiita

Maven 2 で Tomcat 7 にデプロイする - エンジニアきまぐれTips

kakakikikekeのブログ: eclipseでmavenプロジェクトとTomcat7を連携する方法(デプロイ)

環境構築2「動的Webプロジェクト in Eclipse + Maven 編」 - grachroのブログ

Selenium について(メモ)

簡単・便利、ブラウザの自動操作!~Selenium WebDriver~ : アシアルブログ

Selenium WebDriverでWebアプリのテストが変わる(前編):iPhone/Android含むブラウザ自動テストの最終兵器Selenium WebDriverとは (2/2) - @IT

Java+SeleniumなWebアプリケーションの自動テストプロジェクト構築 - Qiita

windows7+eclipse+Selenium WebDriverその0007(mavenプロジェクトとして環境構築をやり直してみる) - MOTOMICHI WORKS BLOG

自動テストはじめませんか?#1 | Developers.IO

Seleniumを使用して、テストの自動化に挑む。基本編 | 株式会社Seekcloud 長野県 上田市 ホームページ制作・Webサイト システム開発::長野県上田市

Selenium WebDriverのインストール~動かしてみる - hifive

カウントアップマクロ

個人的に今欲しいマクロを作成してみた。

'変数宣言
Dim szGetText As String
Dim szSetText As String
Dim iCnt As String


'*************************************
'コピーした文字列の末尾を取得して
'カウントアップする
'*************************************
Sub GetText()

On Error GoTo GetTextError
    
    Selection.Copy

    With New DataObject
        .GetFromClipboard       '変数のデータをDataObjectに格納する
        szGetText = .GetText    'クリップボードから取得
        iCnt = Val(Right(szGetText, 3))
        iCnt = iCnt + 1
        '改行コード(vbLf)を考慮
        szSetText = Left(szGetText, Len(szGetText) - 3) 
    End With
    
    Exit Sub
    
GetTextError:

MsgBox ("エラー")

End Sub

'*************************************
'GetText()でカウントアップした
'文字列を貼り付ける
'*************************************
Sub SetText()

    With New DataObject
        .SetText szSetText & Format(iCnt, "0")  '数値から文字へ
        'DataObjectのデータをクリップボードに格納する
        .PutInClipboard                         
    End With
    
    ActiveSheet.Paste

End Sub


例えば次のデータがあるとする
f:id:sndstudy:20160831222104p:plain

そのデータをコピーして
f:id:sndstudy:20160831222122p:plain

別のセルに貼り付ければ、末尾の数字がカウントアップする
f:id:sndstudy:20160831222202p:plain

やっぱエビデンスの番号紐づけぐらいしか用途ないな……。

■参考サイト
クリップボードとデータのやりとりをする:Excel VBA|即効テクニック|Excel VBAを学ぶならmoug

Office TANAKA - Excel VBA Tips[クリップボードを操作する(1)]

Microsoft Forms 2.0 Object Libraryへの参照設定を行うには? :VBE(Visual Basic Editor)

Excel VBA 入門講座

VBA 文字列の改行

VBA 数値を変換

Javaでちょっと気になったこと

新人3ヵ月目の時、よく理解していなかったが故にやってしまったこと。

例えばユーザ情報をListに入れるときに

package test.java;

import java.util.ArrayList;
import java.util.List;

public class ListTest {

	public static void main(String[] args) {

		List<UserBean> list = new ArrayList<UserBean>();

		UserBean uBean = new UserBean();

		/* 1人目 */
		uBean.setNo("1");
		uBean.setName("YoneSan");
		uBean.setMsg("MSG1");

		/* リストに追加 */
		list.add(uBean);

		/* 2人目 */
		uBean.setNo("2");
		uBean.setName("OzekiStyle");
		uBean.setMsg("MSG2");

		/* リストに追加 */
		list.add(uBean);

		/* 3人目 */
		uBean.setNo("3");
		uBean.setName("NagasawaKun");
		uBean.setMsg("MSG3");

		/* リストに追加 */
		list.add(uBean);

		for(UserBean ub : list){

			System.out.println(ub.getNo());
			System.out.println(ub.getName());
			System.out.println(ub.getMsg());

		}
	}

}

想定していた出力は

1
YoneSan
MSG1
2
OzekiStyle
MSG2
3
NagasawaKun
MSG3

こんな感じだけど、実際に実行すると。

3
NagasawaKun
MSG3
3
NagasawaKun
MSG3
3
NagasawaKun
MSG3

一番最後に設定した値が出力される。

そりゃあインスタンスが1つ(newが1回)しか生成
されていないのにそのインスタンスに対して値を変更したら
すでにリストに格納されているものも変わるよなって話。

試しにハッシュコードを調べてみる。

package test.java;

import java.util.ArrayList;
import java.util.List;

public class ListTest {

	public static void main(String[] args) {

		List<UserBean> list = new ArrayList<UserBean>();

		UserBean uBean = new UserBean();
		System.out.println(uBean);

		/* 1人目 */
		uBean.setNo("1");
		uBean.setName("YoneSan");
		uBean.setMsg("MSG1");

		/* リストに追加 */
		list.add(uBean);

		System.out.println(uBean);

		/* 2人目 */
		uBean.setNo("2");
		uBean.setName("OzekiStyle");
		uBean.setMsg("MSG2");

		/* リストに追加 */
		list.add(uBean);

		System.out.println(uBean);

		/* 3人目 */
		uBean.setNo("3");
		uBean.setName("NagasawaKun");
		uBean.setMsg("MSG3");

		/* リストに追加 */
		list.add(uBean);

		for(UserBean ub : list){

			System.out.println(ub.getNo());
			System.out.println(ub.getName());
			System.out.println(ub.getMsg());

		}
	}

}

出力結果↓
test.java.UserBean@659e0bfd
test.java.UserBean@659e0bfd
test.java.UserBean@659e0bfd
3
NagasawaKun
MSG3
3
NagasawaKun
MSG3
3
NagasawaKun
MSG3

@以降がハッシュコードを指してる。

ハッシュコードはオブジェクトの内部アドレスを整数値にしたもの
みたいなので、すべて同じところを指していることが分かる。

参考↓
Object (Java Platform SE 7)

なので値を設定する前にインスタンスを生成すればOK。

package test.java;

import java.util.ArrayList;
import java.util.List;

public class ListTest {

	public static void main(String[] args) {

		List<UserBean> list = new ArrayList<UserBean>();

		UserBean uBean = new UserBean();
		System.out.println(uBean);

		/* 1人目 */
		uBean.setNo("1");
		uBean.setName("YoneSan");
		uBean.setMsg("MSG1");

		/* リストに追加 */
		list.add(uBean);

		uBean = new UserBean();
		System.out.println(uBean);

		/* 2人目 */
		uBean.setNo("2");
		uBean.setName("OzekiStyle");
		uBean.setMsg("MSG2");

		/* リストに追加 */
		list.add(uBean);

		uBean = new UserBean();
		System.out.println(uBean);

		/* 3人目 */
		uBean.setNo("3");
		uBean.setName("NagasawaKun");
		uBean.setMsg("MSG3");

		/* リストに追加 */
		list.add(uBean);

		for(UserBean ub : list){

			System.out.println(ub.getNo());
			System.out.println(ub.getName());
			System.out.println(ub.getMsg());

		}
	}

}

出力結果↓
test.java.UserBean@659e0bfd
test.java.UserBean@2a139a55
test.java.UserBean@15db9742
1
YoneSan
MSG1
2
OzekiStyle
MSG2
3
NagasawaKun
MSG3

ハッシュコードも別々で想定した出力になっている。
これでインスタンスの理解が少し深まったかも。