LoginSignup
0
0

More than 3 years have passed since last update.

[ Android Studio ][ HTTP ] サーバクライアント通信2(未完)

Posted at

引き続き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();
    }
}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0