SQLの窓

2017年05月14日


Android Studio : OkHttp v3.8.0 で WEBアプリに POST 送信を行う

関連する記事

OkHttp v3.8.0 jar( と okio 1.13.0.jar ) を Eclipse のプロジェクトに追加して一般的な POST 送信を行う

Eclipse の一般的な Java からの送信を AsynTask を使用して Android Studio から送信しました。送信する文字列は、ArrayList にセットして、AsyncTask<ArrayList<String>,Void,String> として定義して引き渡しています。
package com.example.lightbox.posttest;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.util.ArrayList;

import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button) MainActivity.this.findViewById(R.id.button);
        button.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {

        if ( v.getId() == R.id.button) {
            Log.i("lightbox", "クリックされました");
            CallPost();

        }

    }

    private void CallPost() {

        ArrayList<String> data = new ArrayList<String>();
        data.add("winofsql@gmail.com");
        data.add("OkHttp で送信テスト(Android Studio)");
        data.add("日本語\r\n表示");

        AsyncTask<ArrayList<String>,Void,String> async;
        // 非同期実行用オブジェクト
        async = new AsyncTask<ArrayList<String>, Void, String>() {
            @Override
            protected String doInBackground(ArrayList<String>... params) {

                ArrayList<String> data = params[0];

                // HTTP 処理用オプジェクト
                OkHttpClient client = new OkHttpClient();

                // POST 用 FormBody の内容の作成
                FormBody.Builder formbodyBuilder = new FormBody.Builder();
                formbodyBuilder.add("to", data.get(0));
                formbodyBuilder.add("subject", data.get(1));
                formbodyBuilder.add("body", data.get(2));

                // 送信用ユニットの作成
                FormBody formbody = formbodyBuilder.build();

                // 送信用のデータを作成
                Request.Builder requestBuilder = new Request.Builder();
                String url = "https://ドメイン/lightbox/mail/send.php";
                requestBuilder.url(url);
                requestBuilder.post(formbody);
                Request request = requestBuilder.build();

                // 受信用のオブジェクトの準備
                Call call = client.newCall(request);
                String result = "";

                // 送信と受信
                try {

                    Response response = call.execute();
                    result = response.body().string();

                } catch (Exception e) {
                    e.printStackTrace();
                }

                return result;
            }

            @Override
            protected void onPostExecute(String s) {
                Log.i("lightbox", s);
                // 画面に対してのアクセスはここから行います


            }
        };

        // 実行
        async.execute(data);

    }

}


Module の build.gradle
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.example.lightbox.posttest"
        minSdkVersion 23
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile 'com.squareup.okhttp3:okhttp:3.8.0'
}

※ AndroidManifest.xml には、<uses-permission android:name="android.permission.INTERNET" /> を追加。


posted by lightbox at 2017-05-14 20:07 | Comment(0) | Android Studio 2017 | このブログの読者になる | 更新情報をチェックする

OkHttp v3.8.0 jar( と okio 1.13.0.jar ) を Eclipse のプロジェクトに追加して一般的な POST 送信を行う

Android Studio では、Gradle に compile 'com.squareup.okhttp3:okhttp:3.8.0' を追加すれば済むと思いますが、Eclipse のプロジェクトでは、普通に lib フォルダを追加して、そこに二つを置いて右クリックから追加しました。



※ 右クリックから参照の追加をしないで、外部 jar の追加で処理すると、jar の場所が相対位置にならないので注意


OkHttp のダウンロード

OkHttp
An HTTP & HTTP/2 client for Android and Java applications


( 大きいのが OkHttp で下の小さいリンクが 依存ライブラリの okio です )

Javadoc

呼び出す WEB アプリ

結果が解りやすいので、メール送信です。

▼ リンク先にサンプルコードがあります
mb_send_mail を使用したメール送信テンプレート

POST メソッドで受け取った時のみ送信するようになっています。

Java のコード
import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class Main {

	public static void main(String[] args) {

		// HTTP 処理用オプジェクト
		OkHttpClient client = new OkHttpClient();		

		// POST 用 FormBody の内容の作成
		FormBody.Builder formbodyBuilder = new FormBody.Builder();
		formbodyBuilder.add("to", "xxxxxx@gmail.com");
		formbodyBuilder.add("body", "日本語\r\n表示");
		formbodyBuilder.add("subject", "OkHttp で送信テスト");

		// 送信用ユニットの作成
		FormBody formbody = formbodyBuilder.build();

		// 送信用のデータを作成
		Request.Builder requestBuilder = new Request.Builder();
		String url = "http://localhost/lightbox/send_post_test.php";
		requestBuilder.url(url);
		requestBuilder.post(formbody);
		Request request = requestBuilder.build();

		// 受信用のオブジェクトの準備
		Call call = client.newCall(request);
		String result = "";

		// 送信と受信
		try {
			
			Response response = call.execute();
			result = response.body().string();
			
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 受信結果の表示
		System.out.println(result);

	}

}

OkHttp では、メソッドの戻り値をオブジェクト自体にする事によって、チェーンするコードが書けるようになっていますが、イマいち直感的では無いので、それぞれのオプジェクト毎の記述で行っています。

▼ 以下は、ローカルに送った内容をトレースで記録したものです
POST /lightbox/send_post_test.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 150
Host: localhost
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.8.0

to=xxxxxx%40gmail.com&body=%E6%97%A5%E6%9C%AC%E8%AA%9E%0D%0A%E8%A1%A8%E7%A4%BA&subject=OkHttp%20%E3%81%A7%E9%80%81%E4%BF%A1%E3%83%86%E3%82%B9%E3%83%88


関連する記事

Android Studio : OkHttp v3.8.0 で WEBアプリに POST 送信を行う


タグ:post OkHttp
posted by lightbox at 2017-05-14 18:44 | Comment(0) | java : 通信関連 | このブログの読者になる | 更新情報をチェックする

2017年05月09日


Laravel を試す為に Windows に Composer をインストール

Composer をインストールする

ちゃんと、『プログラムと機能』に登録されるのをインストール後に確認して下さい。



ダウンロード

ダウンロードは、Dependency Manager for PHP からダウンロードボタンをクリックして Composer-Setup.exe よりダウンロードします。



インストール事前チェック

インストーラを実行前に、php の場所を確認して、php.ini の extension=php_openssl.dll を有効にしておいてください。





インストール後チェック

インストール終了すると、システム用パス環境変数の最後にインストール場所が追加されているので確認して下さい。(後々の都合上、php のパスも登録されるので、既に登録している場合はどちらかを削除するといいです)

ユーザのほうにも登録されますが、vendor\bin というフォルダは最初は存在しません。しかし、Conposer でインストールした Laravel がここにインストールされる予定(最新版しかここには登録できないようなので、Laravel のインストールは毎回 Conposer を使うしかありません)です。

※ pathx コマンドはこちらを参照して下さい



C:\ProgramData\ComposerSetup\bin にインストールされ、composer.bat と composer.phar と composer という3つのファイルが保存され、composer.bat が windows から呼び出されます。

最終確認

コマンドプロンプトを開いて、composer と入力して以下のようになれば OK です



関連する記事

Windows で Laravel を試す際、PHP の Windows バージョンが 5.6.30 なので、Larvel 5.2 をインストールします




タグ:PHP Laravel Conposer
posted by lightbox at 2017-05-09 21:50 | Comment(0) | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

2017年05月03日


MastodonOAuthPHP の HttpRequest.php の解説

MastodonOAuthPHP の HttpRequest.php は、Mastodon 用というか、API 呼び出しに特化しているので、そのまま使うには少し改造が必要です。ですが、GET 呼び出しはとりあえずそのまま使えるので、仕様としての概要をだいたいは知る事ができます。

get_and_save.php
<?php
session_cache_limiter('nocache');
session_start();

header( "Content-Type: text/html; charset=utf-8" );

// **********************************************
// クラス定義の読み込み
// **********************************************
require_once("HttpRequest.php");

// **********************************************
// 【クラスの参照】
// HttpRequest の別名を MastodonHttp として使用
// **********************************************
use \theCodingCompany\HttpRequest as MastodonHttp;

$path = "0502/std.html";

// **********************************************
// ペース URL を設定をしたインスタンスの取得
// **********************************************
$http = MastodonHttp::Instance("http://localhost");

// **********************************************
// static メソッドの実行
// **********************************************
$result = $http::Get($path);



file_put_contents('get_and_save.txt', $result );

?>
保存しました


クラスの参照

まず、HttpRequest クラスは名前空間が theCodingCompany で定義されているので、require_once で読み込んだ後、use \theCodingCompany\HttpRequest as MastodonHttp; で、MastodonHttp という名前で使えるようにします。

※ 別名を定義する必要は無いのですが、use \theCodingCompany\HttpRequest は参照するのに必要です。

コンストラクタが protected

使い勝手の理由だと思いますが、new でインスタンスを作らずに instance メソッドを実装してインスタンスを作成するようになっています。内部メソッドは全て static なので、インスタンス化しなくても呼べるはずですが、API 用の $base_url と $base_path を保存した上で インスタンス化して使用しています。

※ インスタンス化されたクラスオブジェクトから static なメソッドにはアクセスできます

static 仕様にした本当の理由は解りませんが、get_called_class を使用して呼び出し元からの インスタンス作成で必ず再利用できるようになっているようです。( instance メソッド を何度読んでも一度しか作成されないので、結果的には static メソッドのクラスを使うのと同じようになっています )

コンストラクタと instance メソッド
    // コンストラクタ
    protected function __construct($base_url = "", $base_path = "/") {            
        self::$base_path = $base_path;
        self::$base_url = $base_url;
    }
    
    // インスタンス作成用メソッド
    public static function Instance($base_url = "", $base_path = "/"){
        $cls = get_called_class();
        if(!isset(self::$instance[$cls])){
            self::$instance[$cls] = new HttpRequest($base_url, $base_path);
        }
        return self::$instance[$cls];
    }


結果的に $http::Get($path); は、$http がインスタンスで、インスタンスから static メソッドを呼び出しています。

Post メソッドは API に特化
    public static function Post($path = "", $parameters = array(), $headers = array()){
        //Sen the request and return response
        $post_data = json_encode($parameters);
        return self::http_request(
            "POST", 
            self::$base_url.self::$base_path.$path, 
            $headers,
            $post_data
        );
    }

データ部分が JSON フォーマットに固定されています。このままでは一般用では使用できないのですが、private メソッドの http_request が結果的に一般仕様なので、これを public に変更すると使えるはずです。

http_request を public にして使用 

public で、URL は直接指定なので、インスタンス作成する必要もありません。
<?php
session_cache_limiter('nocache');
session_start();

header( "Content-Type: text/html; charset=utf-8" );

// **********************************************
// クラス定義の読み込み
// **********************************************
require_once("HttpRequest.php");

// **********************************************
// 【クラスの参照】
// HttpRequest の別名を MastodonHttp として使用
// **********************************************
use \theCodingCompany\HttpRequest as MastodonHttp;

// **********************************************
// POST
// **********************************************
MastodonHttp::http_request("POST","http://localhost/0502/post_and_save.php", array(), array( "text" => "投稿データ" ) );

?>
投稿しました



posted by lightbox at 2017-05-03 20:58 | Comment(0) | PHP + 通信 | このブログの読者になる | 更新情報をチェックする

2017年05月02日


PHP で Mastodon にアプリを登録して投稿する手順

MastodonOAuthPHP をダウンロードして使用します。通信部分で、file_get_contents が使われているので、他方面でも参考になるでしょう。

必要なファイルは以下の三つ
1) HttpRequest.php (通信)
2) oAuth.php
3) Mastodon.php (API)
 ※ Mastodon API overview

ただ、ちょっと古い php のバージョンを使っている場合はエラーとなるので、Mastodon.php の 81 行目を変更する必要があります。( 5.4 以前では言語構造である empty の 引数に関数の戻り値を指定できないので、いったん変数にセットして使う)

※ ソースコードは全て UTF8N で保存

PHP 5.4 以前での変更箇所
    /**
     * Post a new status to your {visibility} timeline
     * @param type $text
     * @param type $visibility
     */
    public function postStatus($text = "", $visibility = "public", $in_reply_to_id = null){
        $credentials = $this->getCredentials();
        if(!empty($credentials)){
            
            $headers = $this->getHeaders();
            
            //Create our object
            $http = HttpRequest::Instance($this->getApiURL());
            $status = $http::Post(
                "api/v1/statuses",
                array(
                    "status"        => $text,
                    "visibility"    => $visibility,
                    "in_reply_to_id" => $in_reply_to_id
                ),
                $headers
            );
            return $status;
        }
        return false;
    }


PHP でリダイレクトする URL の設定

oAuth.php の中で3箇所あります。最初の値は、redirect_uris なので、複数の URL を指定できるようですが、ここでは一つの localhost の テスト用の redirect.php を指定しています。
    private $app_config = array(
        "client_name"   => "MastoTweet",
        "redirect_uris" => "http://localhost/0502/redirect.php",
        "scopes"        => "read write",
        "website"       => "https://www.thecodingcompany.se"
    );

    public function getAuthUrl(){
        if(is_array($this->credentials) && isset($this->credentials["client_id"])){
            
            //Return the Authorization URL
            return "https://{$this->mastodon_api_url}/oauth/authorize/?".http_build_query(array(
                    "response_type"    => "code",
                    "redirect_uri"     => "http://localhost/0502/redirect.php",
                    "scope"            => "read write",
                    "client_id"        => $this->credentials["client_id"]
                ));
        }        
        return false;        
    }

    public function getAccessToken($auth_code = ""){
        
        if(is_array($this->credentials) && isset($this->credentials["client_id"])){
            
            //Request access token in exchange for our Authorization token
            $http = HttpRequest::Instance("https://{$this->mastodon_api_url}");
            $token_info = $http::Post(
                "oauth/token",
                array(
                    "grant_type"    => "authorization_code",
                    "redirect_uri"  => "http://localhost/0502/redirect.php",
                    "client_id"     => $this->credentials["client_id"],
                    "client_secret" => $this->credentials["client_secret"],
                    "code"          => $auth_code
                ),
                $this->headers
            );
            
            //Save our token info
            return $this->_handle_bearer($token_info);
        }
        return false;
    }



最初の処理 : アプリの登録

登録と言っても、実行する毎に client_id と client_secret が取得されます。実行は一度きりでいいですが、後でアクセストークンを取得するので、いったんファイルに保存します

require_once は、autoload.php のみでできるように example.php に書かれていますが、逆に初見では解りづらいのでカレントに置いて全て require_once しています。

mstdn.jp は、登録したいインスタンスのドメインです。

create_app.php
<?php

require_once("HttpRequest.php");
require_once("oAuth.php");
require_once("Mastodon.php");

$mastodon = new \theCodingCompany\Mastodon("mstdn.jp");

$token_info = $mastodon->createApp("appname", "サイトURL");
// appname : 認証済みアプリに表示される id
// サイトURL : 上記のリンク先となる URL

print "<pre>";
print_r( $token_info );
print "</pre>";

file_put_contents("token_info.txt", json_encode( $token_info, JSON_PRETTY_PRINT ) );

?>


アクセストークンの取得

いわゆる認証のいつもの流れですが、アクセストークンを取得する為の code を取得する URL を取得して、その URL に header 関数でリダイレクトします。

get_token.php
<?php

require_once("HttpRequest.php");
require_once("oAuth.php");
require_once("Mastodon.php");

$mastodon = new \theCodingCompany\Mastodon("mstdn.jp");

// client_id と client_secret のセット
$mastodon->setCredentials( json_decode( file_get_contents('token_info.txt'), true ) );

// アクセストークン取得の為のトークンを取得する URL
$auth_url = $mastodon->getAuthUrl();

// その URL をブラウザで表示
header("Location: $auth_url");

?>


そうすると、ログインしていなければ以下の画面になります



そして、ログインすると承認画面です。



承認したら、oAuth.php で指定した場所に飛ばされるので、以下のソースコードで受け取ります。

redirect.php
<?php
header( "Content-Type: text/html; Charset=utf-8" );

require_once("HttpRequest.php");
require_once("oAuth.php");
require_once("Mastodon.php");

$mastodon = new \theCodingCompany\Mastodon("mstdn.jp");
// client_id と client_secret のセット
$mastodon->setCredentials( json_decode( file_get_contents('token_info.txt'), true ) );

$access_token = $mastodon->getAccessToken($_GET['code']);
file_put_contents("token_info.txt", json_encode( $mastodon->getCredentials(), JSON_PRETTY_PRINT ) );
?>

AccessToken を取得して保存しました


これで準備は完了です。あとは FORM 作って投稿です。

mstdn_post.php
<?php
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {

	require_once("HttpRequest.php");
	require_once("oAuth.php");
	require_once("Mastodon.php");

	$mastodon = new \theCodingCompany\Mastodon("mstdn.jp");
	// client_id と client_secret と AccessToken のセット
	$mastodon->setCredentials( json_decode( file_get_contents('token_info.txt'), true ) );

	$mastodon->postStatus($_POST[text]);

}

?>
<!DOCTYPE html>
<html>
<head>
<meta content="width=device-width initial-scale=1.0 minimum-scale=1.0 maximum-scale=1.0 user-scalable=no" name="viewport">
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
</head>
<body>
<form method="post">
	<div>
		<textarea name="text" style='width:400px;height:200px;'></textarea>
	</div>
	<input name="send" type="submit" value="send">
</form>

</body></html>




タグ:MASTODON PHP API
posted by lightbox at 2017-05-02 17:44 | Comment(0) | API | このブログの読者になる | 更新情報をチェックする
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
PHP正規表現チェッカー
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり