文系seの備忘録

Excelの改行でひたすらスペースを打っていた機械音痴の文系seが日々の備忘録を綴る。

jsonpはなぜクロスドメイン制約に引っ掛からないのか

まず、JSONPJSONPの違いから


json( JavaScript Object Notation )
JavaScriptの中でオブジェクト(人間が分かりやすいような形)を記述する書式。

例.

{
"name": "Sakurai",
"age": "34",
"address": "Tokyo",
"result": true
}


jsonpJSON with padding)

関数に引数として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で公開してたらまずいってことですね(゜゜)!


逆を言えば、信用できないサービスのJSONP形式のAPIは安易に利用しないほうが良さげ。

Botkitでslackのbotを作る(Windows環境)

slackでbotを作成したのでmemo



この手順を参考にして作成して、

BotkitでSlackのBotを作る方法


トークンの渡し方はここを参考に行った。
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);
}

/

これで無事動きました。

f:id:ron623:20160420165007p:plain


因みにhubotでも作ってみましたが、herokuに会員登録して(クレジットカードの情報登録しないといけない)うんたらかんたらやって~~・・ってのが面倒だったので
botkitのほうが楽だなと思いました。

slackをプログラミングの勉強に生かす

slack
Slack: Be less busy


slack、使い始めました。


ソースコードを貼るとインデントも崩れず、色分けもされるので便利。
f:id:ron623:20160420143221p:plain


チャンネルに登録しているメンバーと話題を共有できるのも便利。
f:id:ron623:20160420143220p:plain

チャット感覚でソースコードやファイルを添付しながら話せるのが良いです。
f:id:ron623:20160420144036p:plain

tomcatのインストールと起動

tomcatを入れて動かすところまで
※ [任意]は必須ではない

jdk,jreのインストール

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後の最初のインデックスを設定している。

f:id:ron623:20150323174719p:plain


次に、2つめのwhile文内で
trim後の最後のインデックスを設定している。
f:id:ron623:20150323174958p:plain


上記より、開始インデックスと終了インデックスが決まった。
これらを引数として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された新しい文字列が生成されます。
f:id:ron623:20150323175832p:plain




上で出てきたようなif文の書き方好きじゃない。
素人には難解なのです。
いくら簡単な判別だとしても、パッと見て分かるものにしてほしい。

ネストクラス

ネストクラスってなに???

クラスの中にさらにクラスをつくること。
こうすることで外に見えるクラスが無駄に多くなることを防ぎ、プログラマにとって分かりやすいプログラムとなる。

ネストクラスは外側のクラスのメンバの1つ。
非staticな内側クラスを「インナークラス」という。



ネストクラスのルール

共通
・外側のクラスと同じ名前を使用できない
・アクセス修飾子を使用できる
・abstract, final修飾子を使用できる


static
非staticメンバ、staticメンバどちらも持てる。
外側のクラスで定義したインスタンス変数にアクセスできない


非static
staticメンバを持てない。
外側のクラスで定義したインスタンス変数にアクセスできる。



こうして何個もネストできる

クラスファイルは「$」で区切られている。
f:id:ron623:20150314092118p:plain



サンプルコード

非スタティックなクラス(インナークラス)と、スタティックなクラス。

上記の呼び出しは以下のようにして行う。
アクセス

//ネストクラスへのアクセス
NestCls.Inner inner = new NestCls().new Inner();
inner.innerMtd();

実行結果
f:id:ron623:20150314100401p:plain




で、、、、ここから疑問点。
何日か前の記事にも書きましたが

なんで非staticクラスではstaticメンバを持てないんだ??

だとしたら外側の非staticクラスでstaticメンバ持てるのもおかしくない?


以下、私の思うstatic

f:id:ron623:20150314100701p:plain

f:id:ron623:20150314100755p:plain


・・・・と思ったけど、いちばんうえのほうで書いた

ネストクラスは外側のクラスのメンバの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; ()V Code
(Ljava/lang/String;I)V
"
$ 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;@1 @ @ @ @ @


赤文字をつけた2つのメソッドは自動的に追加されたもの。

・static 列挙型[ ] values()
   列挙した値(定数)のすべてを配列で返す

・static 列挙型 valueOf ( String name)
  引数で指定された名前を持つ値(定数)を返す



列挙型でのコンストラクタ、変数、メソッド定義

f:id:ron623:20150314091404p:plain

int型を引数にとるコンストラクタがないよー!って言ってる。。


以下のようにコンストラクタを作成する。

package enumTest;

// あらしめん列挙クラス
public enum EnumTest {

AIBA(1), SAKURAI(5), MATSUMOTO(3), NINOMIYA(2), OHNO(4);

private EnumTest(int a) {

}

}

EnumはComparableインターフェースを実装しており、各定数は配列した順番で管理されている。