Sails.jsでコントローラを作成する。
動作環境
・Windows7 Ultimate Service Pack 1
・Node.js 0.10.28
・Sail.js 0.9.16
参考にしたのはこのサイト。
Sails.jsでコントローラを作成する。
動作環境
・Windows7 Ultimate Service Pack 1
・Node.js 0.10.28
・Sail.js 0.9.16
参考にしたのはこのサイト。
Sails.jsでログをファイルに出力する方法を記載する。
Sails.jsのログでは、ログはコンソールに出力するだけで、ファイルには出力されない。
ファイルに出力するために、ここではlog4jsを使用する。
動作環境
・Windows7 Ultimate Service Pack 1
・Node.js 0.10.28
・Sail.js 0.9.16
・log4js 0.6.14
Node.jsのフレームワークSails.jsを、Eclipseで実行する方法を記載する。
動作環境
・Windows7 Ultimate Service Pack 1
・Eclipse 4.3 Kepler Pleiades All in One
Node.jsのフレームワークExpressを、Eclipseで実行する方法を記載する。
動作環境
・Windows7 Ultimate Service Pack 1
・Eclipse 4.3 Kepler Pleiades All in One
WindowsにNode.jsをインストールし、Eclipseで実行する方法を記載する。
動作環境
・Windows7 Ultimate Service Pack 1
・Eclipse 4.3 Kepler Pleiades All in One
インストールするものは以下。
Node.jsを公式サイトからダウンロードする。
サイト中央の「INSTALL」から自環境に適したインストーラをダウンロードする。本稿執筆時、Node.jpの最新バージョンは「0.10.28」であった。
ダウンロードしたインストーラを起動し、インストールを実施する。ソフトウェアの使用許諾契約やインストール先選択の画面が表示されるが、画面の指示に従って先へ進んでいく。
「Completed the Node.js Setup Wizard」と記載された画面が表示されれば、インストールは完了。
Eclipseは公式サイトからダウンロードすると言語が英語なので、日本語化されたPleiadesからダウンロードする。
Eclipse 日本語化 | MergeDoc Project
ここでは、Eclipse 4.3 Kepler Pleiades All in Oneをダウンロードした。
ダウンロードしたファイルは圧縮ファイルなので解凍する。解凍後のフォルダを格納する場所はどこでもよい。解凍後、「pleiades\eclipse\eclipse.exe」を実行すると、Eclipseが起動する。
EclipseでNode.jsを動作させるために、Nodeclipseプラグインをインストールする。
Eclipseのメニュー「ヘルプ」→「新規ソフトウェアのインストール」からソフトウェアのインストール画面を開く。
作業対象の欄に下記のURLを入力する。
http://dl.bintray.com/nodeclipse/nodeclipse/
表示された項目全てをチェックし、「次へ」ボタンを押して進む。
インストール詳細、ライセンスのレビュー画面が表示されるので、指示に従ってインストールを実施する。
セキュリティ警告の画面では「OK」を押す。
インストール完了後、Eclipseを再起動すると、Nodeclipseを使用できる状態となる。
インストールが完了すると、Node.js用のプロジェクトを作成できるようになる。
Eclipseのメニュー「ファイル」→「新規」→「プロジェクト」から新規プロジェクト画面を開く。
「Nodeclipse」の項目の中の「Node.js Project」を選択し、「次へ」ボタンを押して進む。
「New Node.js Project」画面では、プロジェクト名を入力する。
ここでは、「SampleNodeJS」とした。
「Template to use」の項目では、「Hello World」を選択する。
「完了」ボタンを押すと、プロジェクトの作成が完了する。
自動生成されたファイルのうち、「hello-world.js」にWebサーバを起動するコードが書かれている。
localhostの1337ポートでサーバを起動し、「Hello World」と表示するようになっている。
var http = require('http');
http.createServer(function handler(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');実際に実行してみる。
メニュー「実行」→「実行」→「Node Application」を実行すると、コンソールに「Server running at http://127.0.0.1:1337/」と表示される。
これで、サーバが起動した。
ブラウザを開き、サーバにアクセスする。ソースコード通りだと、
にアクセスすればよいが、
http://localhost:1337/でも同じ。
ブラウザ上には、「Hello World」とだけ表示される。
Node.jsの実行に成功。
CakePHPでマルチパートでないHTTP-Postリクエストを受信する方法を記載する。
動作環境Webで実装方法を検索してみたところ、ピュアPHPではすぐに見つかったのだが、CakePHPではなかなか見つけることができなかった。
Webで検索するキーワードが悪かったのかもしれない。
HTTPクライアントはAndroidでHttpURLConnectionを使用した。
サンプルコードはこちら。
androidからAsyncTaskLoaderでHTTP-Post通信をする
ピュアPHPでPostリクエストのデータを取得する場合は、file_get_contentsメソッドを使用する。
引数に「php://input」を指定する。
リクエストデータは戻り値で取得できる。
<?php
// 受信データ格納
$data = file_get_contents("php://input");
// レスポンス
echo "POST DATA RECEIVED. data[".$data."]"
?>
CakePHPでPOSTデータを取得する場合、
CakeRequest::data[‘key’]
などでデータを取得するが、マルチパートでないPOSTデータの場合、取得できない。
上記の「key」を「php://input」としても取得できない。
といっても、CakePHPのどこかで「php://input」からPOSTデータを取得している箇所があるはずなので、CakePHPのコードを「php://input」で検索してみる。
すると、CakeRequest::_readInputメソッドで「php://input」を使用していた。
_readInputメソッドはprotectedなので、さらに_readInputメソッドを使用している箇所を検索してみる。
_readInputメソッドを使用している箇所は2カ所あったが、CakeRequest::inputメソッドがpublicだったので、ここからPOSTデータを取得できそう。
というわけで、CakeRequest::inputメソッドを使用する。
inputメソッドは引数にデコード用コールバックを指定できるが、省略可能引数となっているため、今回は省略する。
リクエストデータは戻り値で取得できる。
下記のサンプルでは、取得したリクエストデータを、そのままレスポンスデータとして送信している。
<?php
class PostSamplesController extends AppController {
public function index() {
if($this->request->is('post')) { // Post通信
// 受信データ格納
$input_data = $this->request->input();
// レスポンス
$this->response->body($input_data);
return $this->response;
}
}
}
?>
androidでは、HTTP通信をするための方法として、下記のふたつがある。
ここでは、HttpClientを使用する方法を紹介する。
HttpURLConnectionとHttpClientの違いについては、下記のサイトが参考になった。
Y.A.M の 雑記帳: Android Apache HTTP Client と HttpURLConnection どっちを使うべき?
HttpURLConnectionを使用する方法は下記を参照。
androidからAsyncTaskLoaderでHTTP-Post通信をする
Http通信処理を実現するためには、Androidアプリで下記の3つの部品を実装する。
Androidアプリのマニフェストファイルにインターネット接続のパーミッションを追加すること。
また、サーバ側でも何らかの応答を返す処理を実装する必要がある。
アプリケーション実行時に呼び出されるアクティビティ。
ここで通信データを生成し、バックグラウンド処理に渡す。
package net.kuttya.httppostsample2;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
public class MainActivity extends FragmentActivity implements LoaderCallbacks{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// サーバにデータ送信(初期化)
TransData sendData = new TransData();
Bundle args = new Bundle();
sendData.data = "test";
args.putSerializable("data", sendData);
getSupportLoaderManager().initLoader(0, args, this);
}
public LoaderonCreateLoader(int id, Bundle args) {
if( null != args ) {
TransData sendData = (TransData) args.getSerializable("data");
return new HttpAccesser(this, sendData);
}
return null;
}
public void onLoadFinished(Loaderloader, TransData recvData) {
// AsyncTaskLoaderの処理が終了したら呼び出される
if(null == recvData) {
return;
}
else {
}
}
public void onLoaderReset(Loaderarg0) {
// AsyncTaskLoaderが破棄されるときに呼び出される
}
}
実際に使用する通信データはメッセージ種別など様々な情報が含まれていると思うが、ここでは簡略化して文字列のみを送受信することにする。
package net.kuttya.httppostsample2;
import java.io.Serializable;
public class TransData implements Serializable {
private static final long serialVersionUID = 1L;
public String data;
}
ここでHTTP-Post通信を実行する。
package net.kuttya.httppostsample2;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
public class HttpAccesser extends AsyncTaskLoader{
private final static String SERVER_URL = "http://www.sample.com/index.php";
private final static String ENCODE = "UTF-8";
private TransData mSendData = null; // 送信データ
private DefaultHttpClient mHttpClient = null; // HTTPクライアント
private HttpPost mPost = null; // POST通信
public HttpAccesser(Context context, TransData sendData) {
super(context);
this.mSendData = sendData;
}
public TransData loadInBackground() {
// ここに非同期処理で実施したい処理を記載する
TransData recvData = null;
recvData = send(mSendData);
return recvData;
}
public void onCanceled(Boolean data) {
// キャンセル処理
}
protected void onStartLoading() {
// 開始処理
forceLoad();
}
public TransData send(TransData sendData) {
boolean ret = false;
TransData recvData = null;
Listparams = new ArrayList ();
HttpResponse response = null;
HttpEntity resEntity = null;
int resStatus = 0;
// 接続初期化
ret = initConnection();
if(false == ret) {
return null;
}
try {
// 送信データ生成
params.add(new BasicNameValuePair("data", sendData.data));
// UTF-8にエンコードする
mPost.setEntity(new UrlEncodedFormEntity(params, ENCODE));
// 送信
response = mHttpClient.execute(mPost);
// リクエスト結果を取得
resStatus = response.getStatusLine().getStatusCode();
if(200 == resStatus) {
// リクエスト成功
resEntity = response.getEntity();
recvData = new TransData();
recvData.data = EntityUtils.toString(resEntity, ENCODE);
}
} catch(Exception e) {
e.printStackTrace();
recvData = null;
} finally {
try {
if(mHttpClient != null) {
mHttpClient.getConnectionManager().shutdown();
}
} catch(Exception e) {
recvData = null;
}
}
return recvData;
}
private boolean initConnection() {
mHttpClient = new DefaultHttpClient();
mPost = new HttpPost(SERVER_URL);
return true;
}
}
下記のパーミッションを追加する。