引き続きAndroidでのサーバクライアント通信について書いていく。
特にHTTPに絞って書いていきたい。
未完ではあるがサンプル等参考にして頂けたらと思う。
##HTTP
サーバ-クライアント間でデータの送受信を行うためのプロトコル。
クライアントがリクエストを送り、サーバがレスポンスを返す形式が基本。
リクエスト、レスポンスはヘッダとボディ部で構成されている。
通信メソッドには
・クライアントからサーバにデータ送信を求める(POST)
・クライアントがサーバからデータ取得を求める(GET)
などがある。
参考URL:http://e-words.jp/w/HTTP.html
現在、私はデータ取得を目的としているのでGETのサンプルを使って話していく。
##実装
サンプルを記事の下にupしているのでそちらを見て頂きたい。
流れは
クリックイベントでgetメソッドを呼び出し、通信できればサーバから値を取得し返す
といったものである。
サーバとの接続には基本的にtry catchを用いる。
try {
//接続処理
} catch {
//例外処理
} fially {
//切断処理
}
get()中の以下のコードでGETのHTTPメソッドを指定している。
httpConn.setRequestMethod("GET");
URLへの接続はget()中の以下のコードで行い、
URL url = new URL(endpoint); //endpointはURLを引数で渡したもの
httpConn = (HttpURLConnection) url.openConnection();
httpConn.connect();
finally句にある以下のコードで切断する。
httpConn.disconnect();
レスポンスのデータ読み取りに使うInputStreamなどのclose処理もfinally句で行う。
参考URL:https://qiita.com/riversun/items/5f78d47a3d95f857d34f
##接続エラー
サンプルを実行してみると
「Cleartext HTTP traffic not permitted」
というエラーが出た。
どうやらHTTP通信が許可されていないようなので、
https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted
こちらの記事を参考に解決を試みる。
そのために
①AndroidManifest.xmlに以下の2行目、5行目のコード
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" /> //2行目
<application
...
android:networkSecurityConfig="@xml/network_security_config" //5行目
...>
...
</application>
</manifest>
を追加する。
②res/xml/network_security_config.xmlを作成し、
以下のコードをnetwork_security_config.xmlに追加する。
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">Your URL(ex: 127.0.0.1)</domain>
</domain-config>
</network-security-config>
の2つを行う。
これで実行してみると許可はされたようだが、他のエラーが発生…
##NetworkOnMainThreadException
これは「Android3.0からメインスレッド(UIスレッド)からの通信が禁止された」
ことにより発生する。
つまりメインスレッド以外で通信しなければならない。
##まとめ
次回はNetworkOnMainThreadExceptionを解決する方法を調査したい。
以上。
##サンプル
package com.example;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
String string = "aaaaaaa";
Map<String,String> headers=new HashMap<String,String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText editTextResponse = findViewById(R.id.editTextResponse);
Button button = (Button)findViewById(R.id.buttonGet);
button.setOnClickListener((View view) -> {
try {
String resultStr = get("http://IP adress/searchman/servlet/hello", "UTF-8", null);
} catch (IOException e) {
e.printStackTrace();
}
});
}
public static String get(String endpoint, String encoding, Map<String, String> headers) throws IOException {
final int TIMEOUT_MILLIS = 0;
final StringBuffer sb = new StringBuffer("");
HttpURLConnection httpConn = null;
BufferedReader br = null;
InputStream is = null;
InputStreamReader isr = null;
try {
URL url = new URL(endpoint);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setConnectTimeout(TIMEOUT_MILLIS);
httpConn.setReadTimeout(TIMEOUT_MILLIS);
httpConn.setRequestMethod("GET");
httpConn.setUseCaches(false);
httpConn.setDoOutput(false);
httpConn.setDoInput(true);
if (headers != null) {
for (String key : headers.keySet()) {
httpConn.setRequestProperty(key, headers.get(key));
}
}
httpConn.connect();
final int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
is = httpConn.getInputStream();
isr = new InputStreamReader(is, encoding);
br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line);
}
} else {
// If responseCode is not HTTP_OK
}
} catch (IOException e) {
throw e;
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
}
}
if (isr != null) {
try {
isr.close();
} catch (IOException e) {
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
if (httpConn != null) {
httpConn.disconnect();
}
}
return sb.toString();
}
}