トップページ > 記事閲覧
POST通信のやり方について
名前:焼肉 日時: 2021/02/21 21:14

いつもお世話になっております。 ・DXライブラリ Android版を使用した Androidアプリで Java のコードで HTTP通信を行う ttps://dxlib.xsrv.jp/lecture/Android/Android_Java_HTTP.html の項目を見てやってみたのですが、POST通信のやり方がわからず質問させて頂きました。 たとえば、クライアントでGET通信を Android_HTTP_Connect( "ttps://yaki-3d.work/test.php?num1=12", "GET" ) ; のように書けばサーバ側で <?php echo "受信されたファイルは「".$_GET["num1"]."」です。"; ?> ``` と書いてあるため出力結果が HTTPレスポンスコード データのサイズ:47byte データ:受信されたファイルは「12」です。 と表示されますが、POST通信をやろうと Android_HTTP_Connect( "ttps://yaki-3d.work/test_post.php", "POST" ) ; とC++で入力し、java側で ttps://dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=4835 でやったように // 非同期で HTTP 通信するためのクラス public class HTTP_ConnectTask extends Thread { public void run() { HttpURLConnection HTTPCon = null ; URL url = null ; try { // URLの作成 url = new URL( HTTP_URLString ) ; // 接続用HttpURLConnectionオブジェクト作成 HTTPCon = ( HttpURLConnection )url.openConnection() ; // メソッドタイプによって処理を分岐 switch( HTTP_MethodType ) { case 0: // GET HTTPCon.setRequestMethod( "GET" ) ; HTTPCon.setDoOutput( false ) ; break ; case 1: // POST HTTPCon.setRequestMethod( "POST" ) ; HTTPCon.setDoOutput( true ) ; break ; case 2: // PUT HTTPCon.setRequestMethod( "PUT" ) ; HTTPCon.setDoOutput( true ) ; break ; } HTTPCon.setDoInput( true ) ; if(HTTP_MethodType==1) { // レスポンスコードの取得 HTTP_ResponseCode = HTTPCon.getResponseCode(); //phpに渡すパラメータ String parameter = "num1=12"; //POST でパラメータをphpに渡す try { OutputStream outStream = HTTPCon.getOutputStream(); outStream.write(parameter.getBytes(StandardCharsets.UTF_8)); outStream.flush(); HTTP_ResponseCode = 999; HTTPCon.connect(); } catch (IOException e) { HTTP_ResponseCode = -5; } } // 接続 HTTPCon.connect() ; // レスポンスコードの取得 HTTP_ResponseCode = HTTPCon.getResponseCode(); // 通信結果のデータを格納する配列がまだ未初期化の場合はここで初期化 if( HTTP_DataBuffer_Initialize == false ) { HTTP_DataBuffer_Initialize = true; HTTP_DataBuffer = new byte[ HTTP_DataBufferBytes ] ; } // 有効なデータのサイズを0にセット HTTP_DataBufferEnableBytes = 0 ; // 通信結果のデータを取得 InputStream in = HTTPCon.getInputStream() ; int ReadSize = in.read( HTTP_DataBuffer ) ; while( ReadSize > 0 ) { HTTP_DataBufferEnableBytes += ReadSize ; ReadSize = in.read( HTTP_DataBuffer, HTTP_DataBufferEnableBytes, HTTP_DataBufferBytes - HTTP_DataBufferEnableBytes ) ; } in.close() ; } catch ( MalformedURLException e ) { // MalformedURL例外が発生したらレスポンスコードを代入する変数に -3 を代入 HTTP_ResponseCode = -3 ; // 例外のメッセージを取得する HTTP_ExceptionMessage = e.toString() ; } catch ( IOException e ) { // IO例外が発生したらレスポンスコードを代入する変数に -2 を代入 HTTP_ResponseCode = -2 ; // 例外のメッセージを取得する HTTP_ExceptionMessage = e.toString() ; } // HTTP通信が完了したので 1 を代入する HTTP_Connect_Finish = 1 ; } } ・サーバプログラム『test_post.php』 <?php echo "受信されたファイルは「".$_POST["num1"]."」です。"; ?> 出力結果が HTTPレスポンスコード データのサイズ:45byte データ:受信されたファイルは「」です。 となってしまいます。 どうすれば正しくPOST通信でデータを受け取ることが出来るでしょうか?
メンテ

Page: 1 |

Re: POST通信のやり方について ( No.1 )
名前:焼肉 日時:2021/02/21 21:48

サーバ側のプログラム『test_post.php』を <?php echo "受信されたファイルは「".$_POST["num1"]."」です。"; echo var_dump($_POST); ?> に変えた所、 HTTPレスポンスコード データのサイズ:58byte データ:受信されたファイルは「」です。array(0){ } と出力されました。配列の要素数が0となっているので、どうも配列の送信自体に失敗しているようです。 ※追記 プロジェクトファイルをアップしました。 C:\Users\Public フォルダに解凍してください。 ttps://yaki-3d.work/HttpTest.zip
メンテ
Re: POST通信のやり方について ( No.2 )
名前:焼肉 日時:2021/02/21 21:55

POST通信のテストサイトで行うと以下のように正常に結果が出ました。 ttps://so-zou.jp/web-app/network/post/ URL ttps://yaki-3d.work/test_post.php 入力 num1=hoge 出力結果 受信されたファイルは「hoge」です。array(1) { ["num1"]=> string(4) "hoge" }
メンテ
Re: POST通信のやり方について ( No.3 )
名前:管理人 日時:2021/02/22 00:54

Java には詳しくないので検索してみたのですが、こちらのウェブサイトの HttpURLConnection で POST通信を行うサンプルとは少し使い方が異なるようです( getBytes に渡す引数など ) <Wai 今更ながらの、HttpURLConnection POST編> https://www.yscjp.com/java_introduction/urlconnection/post.html HttpURLConnection の扱いに関しては『DXライブラリならでは』の部分は特にありませんので、 よろしければこちらのウェブサイトのサンプルや、その他 HttpURLConnection getOutputStream などのキーワードで検索した結果のサンプルをご覧になってみてください m(_ _)m
メンテ
Re: POST通信のやり方について ( No.4 )
名前:焼肉(解決済み) 日時:2021/02/22 22:37

管理人様ありがとうございます。 お陰で出来ました。 シグネチャがint型だと『I』だけなのにString型が『Ljava/lang/String;』とセミコロンを入れる必要があるため時間がかかってしまいました。 参考になったサイトです。 ttp://setohide.blogspot.com/2014/01/jni.html 以下ソースです。 //native-lib.cpp #include "DxLib.h" #include <string.h> // データ取得用バッファ 8MB( 足りない場合は増やしてください ) BYTE HTTP_DataBuffer[ 8 * 1024 * 1024 ] ; // HTTP通信を行う // URL : 接続するパス // Method : "GET", "POST", "PUT" の何れか // 戻り値 : 0:成功 -1:エラー int Android_HTTP_Connect( const char *URL, const char *Method, const char *Post ); int Android_HTTP_Connect( const char *URL, const char *Method) { return Android_HTTP_Connect(URL, Method, ""); } int Android_HTTP_Connect( const char *URL, const char *Method, const char *Post ) { JNIEnv *env ; const ANativeActivity *NativeActivity ; jstring jstring_URL ; jstring jstring_Post; int MethodType = 0 ; // アプリの NativeActivity を取得しておく NativeActivity = GetNativeActivity() ; // JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 ) if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK ) { return -1 ; } // URL から jstring を作成 jstring_URL = env->NewStringUTF( URL ) ; jstring_Post = env->NewStringUTF( Post ) ; // メソッド名からメソッドタイプの数値をセット if( strcmpDx( "GET", Method ) == 0 ) { MethodType = 0 ; } else if( strcmpDx( "POST", Method ) == 0 ) { MethodType = 1 ; } else if( strcmpDx( "PUT", Method ) == 0 ) { MethodType = 2 ; } // Java のクラス MainActivity を取得 jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ; // Java のクラス MainActivity のメンバー関数 HTTP_Connect の ID を取得 jmethodID jmethodID_HTTP_Connect = env->GetMethodID( jclass_MainActivity, "HTTP_Connect", "(Ljava/lang/String;ILjava/lang/String;)V" ) ; // Java のクラス MainActivity のメンバー関数 HTTP_Connect の呼び出し env->CallVoidMethod( NativeActivity->clazz, jmethodID_HTTP_Connect, jstring_URL, MethodType ,jstring_Post) ; // Java の参照を削除 env->DeleteLocalRef( jclass_MainActivity ) ; env->DeleteLocalRef( jstring_URL ) ; // JavaVM とソフト実行用スレッドの関連付け終了 NativeActivity->vm->DetachCurrentThread() ; // 正常終了 return 0 ; } // HTTP通信の結果を取得する // 戻り値 : 通信の結果( 0:まだ通信中 1以上:HTTPレスポンスコード -2:IO例外発生 -3:MalformedURL例外発生 ) int Android_HTTP_GetResponseCode( void ) { JNIEnv *env ; const ANativeActivity *NativeActivity ; int Result = -1 ; // アプリの NativeActivity を取得しておく NativeActivity = GetNativeActivity() ; // JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 ) if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK ) { return -1 ; } // Java のクラス MainActivity を取得 jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ; // Java のクラス MainActivity のメンバー変数の ID を取得 jfieldID jfieldID_HTTP_ResponseCode = env->GetStaticFieldID( jclass_MainActivity, "HTTP_ResponseCode", "I" ) ; jfieldID jfieldID_HTTP_Connect_Finish = env->GetStaticFieldID( jclass_MainActivity, "HTTP_Connect_Finish", "I" ) ; // Java のクラス MainActivity のメンバー変数の値を取得 jint jint_HTTP_ResponseCode = env->GetStaticIntField( jclass_MainActivity, jfieldID_HTTP_ResponseCode ) ; jint jint_HTTP_Connect_Finish = env->GetStaticIntField( jclass_MainActivity, jfieldID_HTTP_Connect_Finish ) ; // まだ通信処理が終わっていなかったら 0 を返す if( jint_HTTP_Connect_Finish == 0 ) { Result = 0 ; } else { // 終わっていたらレスポンスコードを返す Result = jint_HTTP_ResponseCode ; } // JavaVM とソフト実行用スレッドの関連付け終了 NativeActivity->vm->DetachCurrentThread() ; // 戻り値を返す return Result ; } // HTTP通信の例外メッセージを所得する // 戻り値 : 例外のメッセージ文字列のポインタ char *Android_HTTP_GetExceptionMessage( void ) { JNIEnv *env ; const ANativeActivity *NativeActivity ; static char HTTP_ExceptionMessage[ 64 * 1024 ] ; // アプリの NativeActivity を取得しておく NativeActivity = GetNativeActivity() ; // JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 ) if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK ) { return NULL ; } // Java のクラス MainActivity を取得 jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ; // Java のクラス MainActivity のメンバー変数の ID を取得 jfieldID jfieldID_HTTP_ExceptionMessage = env->GetStaticFieldID( jclass_MainActivity, "HTTP_ExceptionMessage", "Ljava/lang/String;" ) ; // Java のクラス MainActivity のメンバー変数の値を取得 jstring jstring_HTTP_ExceptionMessage = ( jstring )env->GetStaticObjectField( jclass_MainActivity, jfieldID_HTTP_ExceptionMessage ) ; // jstring の文字列をグローバル変数にコピー const char *utf8_HTTP_ExceptionMessage = env->GetStringUTFChars( jstring_HTTP_ExceptionMessage, NULL ) ; if( utf8_HTTP_ExceptionMessage != NULL ) { strcpyDx( HTTP_ExceptionMessage, utf8_HTTP_ExceptionMessage ) ; } else { HTTP_ExceptionMessage[ 0 ] = '\0' ; } env->ReleaseStringUTFChars( jstring_HTTP_ExceptionMessage, utf8_HTTP_ExceptionMessage ) ; // JavaVM とソフト実行用スレッドの関連付け終了 NativeActivity->vm->DetachCurrentThread() ; // メッセージ文字列を返す return HTTP_ExceptionMessage ; } // HTTP通信の結果得られたデータのバッファを取得する // BufferBytes : バッファに格納されているデータのサイズを保存する変数のアドレス // 戻り値 : データのバッファの先頭アドレス void *Android_HTTP_GetBuffer( size_t *BufferBytes ) { JNIEnv *env ; const ANativeActivity *NativeActivity ; void *Result = NULL ; // アプリの NativeActivity を取得しておく NativeActivity = GetNativeActivity() ; // JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 ) if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK ) { return NULL ; } // Java のクラス MainActivity を取得 jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ; // Java のクラス MainActivity のメンバー変数の ID を取得 jfieldID jfieldID_HTTP_DataBuffer = env->GetStaticFieldID( jclass_MainActivity, "HTTP_DataBuffer", "[B" ) ; jfieldID jfieldID_HTTP_DataBufferEnableBytes = env->GetStaticFieldID( jclass_MainActivity, "HTTP_DataBufferEnableBytes", "I" ) ; // Java のクラス MainActivity のメンバー変数の内容を取得 jint jint_HTTP_DataBufferEnableBytes = env->GetStaticIntField( jclass_MainActivity, jfieldID_HTTP_DataBufferEnableBytes ) ; // 有効なデータが 1byte でもあれば、バッファの内容を取得する if( jint_HTTP_DataBufferEnableBytes > 0 ) { // Java のクラス MainActivity のメンバー変数 HTTP_DataBuffer の内容を取得 jbyteArray jbyteArray_HTTP_DataBuffer = ( jbyteArray )env->GetStaticObjectField( jclass_MainActivity, jfieldID_HTTP_DataBuffer ) ; jbyte *jbyte_Elements = env->GetByteArrayElements( jbyteArray_HTTP_DataBuffer, NULL ) ; memcpy( HTTP_DataBuffer, jbyte_Elements, jint_HTTP_DataBufferEnableBytes ) ; env->ReleaseByteArrayElements( jbyteArray_HTTP_DataBuffer, jbyte_Elements, 0 ) ; env->DeleteLocalRef( jbyteArray_HTTP_DataBuffer ) ; Result = HTTP_DataBuffer ; } // バッファの有効なデータのサイズを保存 *BufferBytes = jint_HTTP_DataBufferEnableBytes ; // JavaVM とソフト実行用スレッドの関連付け終了 NativeActivity->vm->DetachCurrentThread() ; // バッファのアドレスを返す return Result ; } int android_main( void ) { // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // HTTP通信開始 //Android_HTTP_Connect( "ttps://yaki-3d.work/test.php?num1=12", "GET" ) ; Android_HTTP_Connect( "ttps://yaki-3d.work/test_post.php", "POST" , "num1=12") ; // メインループ while( ProcessMessage() == 0 ) { // 画面のクリア ClearDrawScreen() ; // HTTP通信の結果によって処理を分岐 int ResponseCode = Android_HTTP_GetResponseCode() ; switch( ResponseCode ) { case 0 : // 通信が終了していない場合は『通信中』を表示する DrawString( 0, 0, "通信中", GetColor( 255,255,255 ) ) ; break ; case -2 : // IO例外が発生した場合はメッセージを表示する DrawFormatString( 0, 0, GetColor( 255,255,255 ), "IO例外発生 : %s", Android_HTTP_GetExceptionMessage() ) ; break ; case -3 : // MalformedURL例外が発生した場合はメッセージを表示する DrawFormatString( 0, 0, GetColor( 255,255,255 ), "MalformedURL例外発生 : %s", Android_HTTP_GetExceptionMessage() ) ; break ; default : // それ以外の場合は HTTPレスポンスコード // データのサイズとアドレスを取得 size_t DataBytes ; void *Buffer = Android_HTTP_GetBuffer( &DataBytes ) ; DrawFormatString( 0, 16 * 0, GetColor( 255,255,255 ), "HTTPレスポンスコード : %d", ResponseCode ) ; DrawFormatString( 0, 16 * 1, GetColor( 255,255,255 ), "データのサイズ : %d bytes", ( int )DataBytes ) ; DrawFormatString( 0, 16 * 2, GetColor( 255,255,255 ), "データ : %s", Buffer != NULL ? ( char * )Buffer : "None" ) ; break ; } // 裏画面の内容を表画面に反映 ScreenFlip() ; } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; } //MainActivity.java package work.yaki3d.httptest; import android.app.NativeActivity; import java.io.Closeable; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.URL; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.io.InputStream; import java.io.IOException; import java.lang.Thread; import java.nio.charset.StandardCharsets; public class MainActivity extends NativeActivity { // 接続 URL 受け渡し用変数 static String HTTP_URLString ; // 接続 POST 受け渡し用変数 static String HTTP_POSTString ; // メソッドタイプ受け渡し用変数 static int HTTP_MethodType ; // 通信処理の終了確認用変数 static int HTTP_Connect_Finish ; // HTTPレスポンスコードを代入する変数 static int HTTP_ResponseCode ; // 例外発生時のメッセージを代入する変数 static String HTTP_ExceptionMessage ; // 通信結果のデータを格納するバッファ関連の変数 static boolean HTTP_DataBuffer_Initialize = false ; static byte[] HTTP_DataBuffer ; static int HTTP_DataBufferBytes = 8 * 1024 * 1024 ; // 通信結果を代入するバッファのサイズは 8MB( 足りない場合は増やしてください ) static int HTTP_DataBufferEnableBytes ; private static void safetyClose(Closeable c) { if (null == c) { return; } try { c.close(); } catch (Exception e) { //log.debug("", e); } } // 非同期で HTTP 通信するためのクラス public class HTTP_ConnectTask extends Thread { public void run() { HttpURLConnection HTTPCon = null ; URL url = null ; try { // URLの作成 url = new URL( HTTP_URLString ) ; // 接続用HttpURLConnectionオブジェクト作成 HTTPCon = ( HttpURLConnection )url.openConnection() ; // メソッドタイプによって処理を分岐 switch( HTTP_MethodType ) { case 0: // GET HTTPCon.setRequestMethod( "GET" ) ; HTTPCon.setDoOutput( false ) ; break ; case 1: // POST HTTPCon.setRequestMethod( "POST" ) ; HTTPCon.setDoOutput( true ) ; break ; case 2: // PUT HTTPCon.setRequestMethod( "PUT" ) ; HTTPCon.setDoOutput( true ) ; break ; } HTTPCon.setDoInput( true ) ; OutputStream outputStream = null; try{ outputStream = HTTPCon.getOutputStream(); //outputStream.write("num1=12".getBytes(StandardCharsets.UTF_8)); outputStream.write(HTTP_POSTString.getBytes(StandardCharsets.UTF_8)); }finally { safetyClose(outputStream); } // 接続 HTTPCon.connect() ; // レスポンスコードの取得 HTTP_ResponseCode = HTTPCon.getResponseCode(); // 通信結果のデータを格納する配列がまだ未初期化の場合はここで初期化 if( HTTP_DataBuffer_Initialize == false ) { HTTP_DataBuffer_Initialize = true; HTTP_DataBuffer = new byte[ HTTP_DataBufferBytes ] ; } // 有効なデータのサイズを0にセット HTTP_DataBufferEnableBytes = 0 ; // 通信結果のデータを取得 InputStream in = HTTPCon.getInputStream() ; int ReadSize = in.read( HTTP_DataBuffer ) ; while( ReadSize > 0 ) { HTTP_DataBufferEnableBytes += ReadSize ; ReadSize = in.read( HTTP_DataBuffer, HTTP_DataBufferEnableBytes, HTTP_DataBufferBytes - HTTP_DataBufferEnableBytes ) ; } in.close() ; } catch ( MalformedURLException e ) { // MalformedURL例外が発生したらレスポンスコードを代入する変数に -3 を代入 HTTP_ResponseCode = -3 ; // 例外のメッセージを取得する HTTP_ExceptionMessage = e.toString() ; } catch ( IOException e ) { // IO例外が発生したらレスポンスコードを代入する変数に -2 を代入 HTTP_ResponseCode = -2 ; // 例外のメッセージを取得する HTTP_ExceptionMessage = e.toString() ; } // HTTP通信が完了したので 1 を代入する HTTP_Connect_Finish = 1 ; } } // HTTP通信を行う Java の関数 public void HTTP_Connect( String URLString, int Method ,String PostString) { // HTTP通信の完了を確認するための変数を初期化 HTTP_Connect_Finish = 0 ; // 有効な取得データのサイズを初期化 HTTP_DataBufferEnableBytes = 0 ; // レスポンスコードを初期化 HTTP_ResponseCode = -1 ; // 非同期処理を行うクラスが参照できるようにグローバル変数に引数を代入 HTTP_URLString = URLString ; HTTP_MethodType = Method ; HTTP_POSTString = PostString; // HTTP通信を非同期で行う為のクラスを作成・実行 HTTP_ConnectTask HTTPTask = new HTTP_ConnectTask() ; HTTPTask.start() ; } } 出力結果 受信されたファイルは「12」です。array(1) { ["num1"]=> string(2) "12" }
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存