jsonpはなぜクロスドメイン制約に引っ掛からないのか
・json( JavaScript Object Notation )
JavaScriptの中でオブジェクト(人間が分かりやすいような形)を記述する書式。
例.
{
"name": "Sakurai",
"age": "34",
"address": "Tokyo",
"result": true
}
関数に引数としてJSONオブジェクトを指定し、クロスドメイン間でのデータを扱える形式。
関数名+取得データで異なるドメインに置いてあるスクリプトファイルを読み込むことが出来る。
APIから返されるコールバック関数と同じ名前( callbackFunc(jsonデータ) )で定義しておくと、
データを読み込んだときにその関数が実行される。
例.
callbackFunc(
{
"name": "Sakurai",
"age": "34",
"address": "Tokyo",
"result": true
}
)
でも、なんでjsonpだとクロスドメイン制約に引っ掛からないのか。
別のドメインからデータを取ってこれるんだったらセキュリティ的にヤバイんじゃないの?
と思って気になってしらべたところ、セキュリティに関して説明されてるページを見つけた(古いけど)。
第3回 JSONPでのクロスドメインアクセス:ここが危ない!Web2.0のセキュリティ|gihyo.jp … 技術評論社
JSONPで公開している場合は、そもそも機密情報を含まない。
はてなとかyahooとか、オープンなAPIを提供するために使われることが多いよう。
JSONP形式になってる=厳格なセキュリティ不要な広く公開されてるサービスってことですね。
というかむしろ、機密情報をJSONPで公開してたらまずいってことですね(゜゜)!
Botkitでslackのbotを作る(Windows環境)
slackでbotを作成したのでmemo
この手順を参考にして作成して、
トークンの渡し方はここを参考に行った。
SlackのBotkitをWindowsで実行する - Qiita
⇒ Windows環境だとbotkitに記載されている実行方法どおりに実行してもエラーになる。
botkitをforeverでデーモン化させる。
Botkitをforeverでデーモン化 - 0239
デーモン化させてあげないと、一度起動させてエラーが発生した場合に落ちてしまう。
デーモン化させてあれば自動で再起動してくれる。
これ実行して
sudo npm install -g forever
そのあとこれ実行
forever start bot.js
怒られた。
環境変数にトークンを明記しろと言われている。
なので、bot.jsにトークンを明記してあげる。
process.env.token=slack側で取得したトークン
以下は要らなくなるのでコメントアウトしとく。
/*
if (!process.env.token) {
console.log('Error: Specify token in environment');
process.exit(1);
}
/
これで無事動きました。
因みにhubotでも作ってみましたが、herokuに会員登録して(クレジットカードの情報登録しないといけない)うんたらかんたらやって~~・・ってのが面倒だったので
botkitのほうが楽だなと思いました。
slackをプログラミングの勉強に生かす
slack
Slack: Be less busy
slack、使い始めました。
ソースコードを貼るとインデントも崩れず、色分けもされるので便利。
チャンネルに登録しているメンバーと話題を共有できるのも便利。
チャット感覚でソースコードやファイルを添付しながら話せるのが良いです。
tomcatのインストールと起動
tomcatを入れて動かすところまで
※ [任意]は必須ではない
JRE:Java Runtime Environment
javaプログラム実行時に必要なライブラリ群。
実行に必要。
JDK:Java Development kit
コンパイラやソース・ライブラリの集まり。
開発に必要。
環境変数の設定
コントロールパネル>システムとセキュリティ>システム>左のほうに出てる「システムの詳細設定」をクリック。
システムのプロパティ画面が出てくるので>「詳細設定」タブ>「環境変数」ボタンをクリック
・JAVA_HOME=${jdkがインストールされた場所}
例:C:\Program Files\Java\jdk1.8.0_25
・PATH=%JAVA_HOME%\bin;%PATH%
※元々書かれているものは消さずに、最後に追加する。
C:\aaa;C:\arashi\member;・・・というふうに半角セミコロンで区切る
java -version でバージョン情報が表示されればOK
■Tomcatのインストール
環境変数の設定
・CATALINA_HOME=${tomcatをインストールした場所}
例:C:\apache-tomcat-7.0.59
・[任意]CATALINA_OPTS=-XX:MaxPermSize=256m -Xmx1024m -ea
(Tomcatに割り当てるメモリを増やす)
[任意] 管理ページを使えるユーザーの作成
tomcat_users.xmlに以下を追加
起動確認
・%CATALINA_HOME%\bin\startup.batでtomcat起動。
javaのアイコン付きのコマンドプロンプトが表示される。
・ブラウザ(FirefoxとかInternet Exprolerとか)で http://localhost:8080/ を開き、
Tomcatのスタートページ(へんなネコみたいのが書いてあるページ)が表示されればOK
【トラブルシューティング】
・startup.batを起動しても一瞬だけコマンドプロンプトの画面が出て消えてしまう
*****原因その1:パスの設定ミス
原因を特定するためログを出してみる。
>>1.コマンドプロンプトでstartup.batがある場所に移動
例:cd C:\apache-tomcat-7.0.59\bin
2.以下を入力
startup.bat > startup(ここは何でもOK).log
-左のファイルを起動して、右のファイルに実行結果を書き込むという処理。
startup.logを確認してみる。
私の場合、以下のようなログが出ていた。
Using CATALINA_BASE: "C:\apache-tomcat-7.0.42"
Using CATALINA_HOME: "C:\apache-tomcat-7.0.42"
Using CATALINA_TMPDIR: "C:\apache-tomcat-7.0.42\temp"
Using JRE_HOME: "C:\Program Files\Java\jdk1.8.0_25"・・・・★
Using CLASSPATH: "C:\apache-tomcat-7.0.42\bin\bootstrap.jar;C:\apache-tomcat-7.0.42\bin\tomcat-juli.jar"
★のところに注目すると、JRE_HOMEを使うと言ってるのにjdkの場所を参照してしまっていた。
⇒環境設定でJREの場所を設定。
新規追加で、変数名:JRE_HOME、変数値:C:\Program Files\Java\jre7(jreの場所)
上記ではjreのパス設定ミスだったが、他にもjdkやCATALINA_HOMEの設定ミスの場合も考えられる。
- 途中に半角スペースが入ってしまっていないか
- 複数パスを追加するときセミコロン(;)がぬけていないか
- ホームページとかブログの例をそのままそっくり移して、自分の環境と異なっている点でエラーになっていないか
等を確認してみる。
*****原因その2:ポートの競合
ポート番号・・・外部とデータを入出力するときに、通信先のプログラムを特定するための番号
Tomcatはデフォルトで8080というポート番号を使うようになっているが、
この番号が既に使用されている場合は起動に失敗する。
Oracleとか入れたりすると、8080を乗っ取って使っちゃうみたい。
⇒Tomcatで使うポート番号を変更する
%CATALINA_HOME%\confのserver.xmlを編集。
Stringクラスのtrim( )メソッドの中身を考える
trim()メソッド
この処理の中身を考える。
しかし、説明から意味不明。。。
がんばって帰りの電車で考えてみます
============================================================
3/20追記
APIのリンク
java.lang: String.java
============================================================
3/23追記
3/20追記分のAPIを元に、trimの中身を見てみた。
何をやっているかというと、1つめのwhile文内で
trim後の最初のインデックスを設定している。
次に、2つめのwhile文内で
trim後の最後のインデックスを設定している。
上記より、開始インデックスと終了インデックスが決まった。
これらを引数としてsubStringメソッドを呼びだす。
SubStringの中身は以下のようになっている(例外処理は省略)。
・開始インデックスが0かつ終了インデックスが文字数と同じ(スペースがないとき)
⇒this(このString文字列の参照)をそのまま返す
・それ以外のとき
⇒この文字列の部分文字列を表す新しい String オブジェクトを返す
newでコンストラクタを呼び出しています。
// Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
こうしてtrimされた新しい文字列が生成されます。
上で出てきたようなif文の書き方好きじゃない。
素人には難解なのです。
いくら簡単な判別だとしても、パッと見て分かるものにしてほしい。
ネストクラス
ネストクラスってなに???
クラスの中にさらにクラスをつくること。
こうすることで外に見えるクラスが無駄に多くなることを防ぎ、プログラマにとって分かりやすいプログラムとなる。
ネストクラスは外側のクラスのメンバの1つ。
非staticな内側クラスを「インナークラス」という。
ネストクラスのルール
共通
・外側のクラスと同じ名前を使用できない
・アクセス修飾子を使用できる
・abstract, final修飾子を使用できる
static
非staticメンバ、staticメンバどちらも持てる。
外側のクラスで定義したインスタンス変数にアクセスできない
非static
staticメンバを持てない。
外側のクラスで定義したインスタンス変数にアクセスできる。
こうして何個もネストできる
クラスファイルは「$」で区切られている。
サンプルコード
非スタティックなクラス(インナークラス)と、スタティックなクラス。
上記の呼び出しは以下のようにして行う。
アクセス
//ネストクラスへのアクセス
NestCls.Inner inner = new NestCls().new Inner();
inner.innerMtd();
実行結果
で、、、、ここから疑問点。
何日か前の記事にも書きましたが
なんで非staticクラスではstaticメンバを持てないんだ??
だとしたら外側の非staticクラスでstaticメンバ持てるのもおかしくない?
以下、私の思うstatic
・・・・と思ったけど、いちばんうえのほうで書いた
ネストクラスは外側のクラスのメンバの1つ。
これがカギになりそう。
メンバはクラスがインスタンス化されるたびに複数できる。
ここまでは分かった。なんか前よりもゴールに近づいた気がする。。。
enumの基礎
enumについて
特定の値のみをもつ型で、プログラマが任意に定義できる。
列挙型は、java.lang.Enumクラスを継承したfinalクラスとなる。
列挙した値はpublic static finalで定数化される。そのため、列挙する値の前後にダブルクォーテーションはつかない。
package enumTest;
// あらしめん列挙クラス
public enum EnumTest {
AIBA,
SAKURAI,
MATSUMOTO,
NINOMIYA,
OHNO
}
上記をコンパイルしてできたEnumTestクラス(ちょっと文字化けしてるけど・・・)
ハコセ 4 : enumTest/EnumTest java/lang/Enum AIBA LenumTest/EnumTest; SAKURAI MATSUMOTO NINOMIYA OHNO ENUM$VALUES [LenumTest/EnumTest;
"
$ LineNumberTable LocalVariableTable
this values ()[LenumTest/EnumTest;
, . - java/lang/System / 0 arraycopy *(Ljava/lang/Object;ILjava/lang/Object;II)V valueOf '(Ljava/lang/String;)LenumTest/EnumTest;
4 1 5 5(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
SourceFile
EnumTest.java Signature %Ljava/lang/Enum
赤文字をつけた2つのメソッドは自動的に追加されたもの。
・static 列挙型[ ] values()
列挙した値(定数)のすべてを配列で返す
・static 列挙型 valueOf ( String name)
引数で指定された名前を持つ値(定数)を返す
int型を引数にとるコンストラクタがないよー!って言ってる。。
以下のようにコンストラクタを作成する。
package enumTest;
// あらしめん列挙クラス
public enum EnumTest {
AIBA(1), SAKURAI(5), MATSUMOTO(3), NINOMIYA(2), OHNO(4);
private EnumTest(int a) {
}
}
EnumはComparableインターフェースを実装しており、各定数は配列した順番で管理されている。