「Android/HttpRequest通信/HttpURLConnection」の版間の差分
(ページの作成:「 ==サンプル== 同期処理のみ(AsyncTaskなどで実行すること) String strGetUrl = "https://api.github.com/feeds"; HttpURLConnection urlConn = null; Inpu...」) |
(→Causee: java.security.cert.CertificateException: Chain validation failedエラーが出るとき) |
||
| (同じ利用者による、間の42版が非表示) | |||
| 行1: | 行1: | ||
| + | ==準備== | ||
| + | AndroidManifest.xml | ||
| + | <uses-permission android:name="android.permission.INTERNET" /> | ||
==サンプル== | ==サンプル== | ||
同期処理のみ(AsyncTaskなどで実行すること) | 同期処理のみ(AsyncTaskなどで実行すること) | ||
| − | + | ||
| − | + | get | |
| − | + | <pre> | |
| − | + | CustomHttpURLConnection http = new CustomHttpURLConnection(); | |
| − | + | HashMap<String, String> params = new HashMap<String, String>(); | |
| − | + | params.put("errorlog", stackTrace); | |
| − | + | http.setParams(params); | |
| − | + | http.execGet("https://api.github.com/feeds"); | |
| − | // | + | </pre> |
| − | + | post | |
| − | + | <pre> | |
| − | + | CustomHttpURLConnection http = new CustomHttpURLConnection(); | |
| − | + | HashMap<String, String> params = new HashMap<String, String>(); | |
| − | + | params.put("errorlog", stackTrace); | |
| − | + | http.setParams(params); | |
| − | + | http.execPost("https://api.github.com/feeds"); | |
| − | + | </pre> | |
| − | + | ||
| − | + | CustomHttpURLConnection.java | |
| − | + | <pre> | |
| − | + | import java.io.BufferedReader; | |
| − | + | import java.io.IOException; | |
| − | + | import java.io.InputStream; | |
| − | + | import java.io.InputStreamReader; | |
| − | + | import java.io.OutputStream; | |
| − | + | import java.io.PrintWriter; | |
| − | + | import java.net.HttpURLConnection; | |
| − | + | import java.net.SocketTimeoutException; | |
| − | + | import java.net.URL; | |
| − | + | import java.util.HashMap; | |
| − | + | import java.util.Set; | |
| − | + | import android.net.Uri; | |
| − | + | import android.util.Log; | |
| − | + | ||
| − | + | class CustomHttpURLConnection | |
| − | + | { | |
| + | HttpURLConnection urlConn = null; | ||
| + | HashMap<String,String> mParams = new HashMap<String,String>(); | ||
| + | String body = ""; | ||
| + | public void setParams(HashMap<String,String> params) { | ||
| + | mParams = params; | ||
| + | } | ||
| + | public void execGet(String strUrl) { | ||
| + | // System.setProperty("http.agent", "Dalvik/2.1.0 (Linux; U; Android 9; H8216 Build/PDP-PKQ1.180708.001-10229)"); // System.getProperty("http.agent"); | ||
| + | Log.i("HttpURLConnection", "ua=" + System.getProperty("http.agent")); | ||
| + | InputStream in = null; | ||
| + | BufferedReader reader = null; | ||
| + | try { | ||
| + | if (mParams.size() > 0) { | ||
| + | Uri.Builder builder = new Uri.Builder(); | ||
| + | Set keys = mParams.keySet(); | ||
| + | for (Object key : keys) { | ||
| + | builder.appendQueryParameter((String) key, mParams.get((String) key)); | ||
| + | } | ||
| + | String join = builder.build().getEncodedQuery(); | ||
| + | Log.i("HttpURLConnection", "join=" + join); | ||
| + | strUrl = strUrl + "?" + join; | ||
| + | } | ||
| + | Log.i("HttpURLConnection", "url=" + strUrl); | ||
| + | URL url = new URL(strUrl); | ||
| + | urlConn = (HttpURLConnection) url.openConnection(); | ||
| + | urlConn.addRequestProperty("Content-Type", "application/json; charset=UTF-8"); | ||
| + | urlConn.setRequestMethod("GET"); | ||
| + | urlConn.setConnectTimeout(10000); // 10s | ||
| + | urlConn.setReadTimeout(1000); // 1s | ||
| + | urlConn.connect(); | ||
| + | int status = urlConn.getResponseCode(); | ||
| + | Log.i("HttpURLConnection", "status_code=" + status); | ||
| + | if (status == HttpURLConnection.HTTP_OK) { | ||
| + | in = urlConn.getInputStream(); | ||
| + | reader = new BufferedReader(new InputStreamReader(in)); | ||
| + | StringBuilder output = new StringBuilder(); | ||
| + | String line; | ||
| + | while ((line = reader.readLine()) != null) { | ||
| + | output.append(line); | ||
| + | } | ||
| + | Log.i("HttpURLConnection", "res=" + output.toString()); | ||
| + | body = output.toString(); | ||
| + | } | ||
| + | } catch (SocketTimeoutException e) { | ||
| + | e.printStackTrace(); | ||
| + | } catch (IOException e) { | ||
| + | e.printStackTrace(); | ||
| + | } finally { | ||
| + | try { | ||
| + | if (reader != null) { | ||
| + | reader.close(); | ||
| + | } | ||
| + | if (urlConn != null) { | ||
| + | urlConn.disconnect(); | ||
| + | } | ||
| + | } catch (IOException e) { | ||
| + | e.printStackTrace(); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | public void execPost(String strUrl) { | ||
| + | // System.setProperty("http.agent", "Dalvik/2.1.0 (Linux; U; Android 9; H8216 Build/PDP-PKQ1.180708.001-10229)"); // System.getProperty("http.agent"); | ||
| + | Log.i("HttpURLConnection", "ua=" + System.getProperty("http.agent")); | ||
| + | HttpURLConnection urlConn = null; | ||
| + | InputStream in = null; | ||
| + | BufferedReader reader = null; | ||
| + | try { | ||
| + | URL url = new URL(strUrl); | ||
| + | urlConn = (HttpURLConnection) url.openConnection(); | ||
| + | urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); | ||
| + | urlConn.setRequestMethod("POST"); | ||
| + | urlConn.setConnectTimeout(10000); // 10s | ||
| + | urlConn.setReadTimeout(1000); // 1s | ||
| + | urlConn.setInstanceFollowRedirects(false); | ||
| + | urlConn.setRequestProperty("Accept-Language", "jp"); | ||
| + | urlConn.setDoOutput(true); | ||
| + | OutputStream outputStream = urlConn.getOutputStream(); | ||
| + | Log.i("HttpURLConnection", "mParams.size()=" + mParams.size()); | ||
| + | if (mParams.size() > 0) { | ||
| + | Uri.Builder builder = new Uri.Builder(); | ||
| + | Set keys = mParams.keySet(); | ||
| + | for (Object key : keys) { | ||
| + | builder.appendQueryParameter((String) key, mParams.get((String) key)); | ||
| + | } | ||
| + | String join = builder.build().getEncodedQuery(); | ||
| + | Log.i("HttpURLConnection", "join=" + join); | ||
| + | PrintWriter ps = new PrintWriter(outputStream); | ||
| + | ps.print(join); | ||
| + | ps.close(); | ||
| + | } | ||
| + | outputStream.close(); | ||
| + | int status = urlConn.getResponseCode(); | ||
| + | String resmessage = urlConn.getResponseMessage(); | ||
| + | Log.i("HttpURLConnection", "status_code=" + status); | ||
| + | Log.i("HttpURLConnection", "message=" + resmessage); | ||
| + | if (status == HttpURLConnection.HTTP_OK) { | ||
| + | in = urlConn.getInputStream(); | ||
| + | reader = new BufferedReader(new InputStreamReader(in)); | ||
| + | StringBuilder output = new StringBuilder(); | ||
| + | String line; | ||
| + | while ((line = reader.readLine()) != null) { | ||
| + | output.append(line); | ||
| + | } | ||
| + | Log.i("HttpURLConnection", "res=" + output.toString()); | ||
| + | body = output.toString(); | ||
| + | } | ||
| + | } catch (SocketTimeoutException e) { | ||
| + | e.printStackTrace(); | ||
| + | } catch (IOException e) { | ||
| + | e.printStackTrace(); | ||
| + | } finally { | ||
| + | try { | ||
| + | if (reader != null) { | ||
| + | reader.close(); | ||
| + | } | ||
| + | if (urlConn != null) { | ||
| + | urlConn.disconnect(); | ||
| + | } | ||
| + | } catch (IOException e) { | ||
| + | e.printStackTrace(); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | public String getBody() { | ||
| + | return body; | ||
| + | } | ||
| + | } | ||
| + | </pre> | ||
| + | |||
| + | post時の参考:https://araramistudio.jimdo.com/2018/03/15/android%E3%81%A7http%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E6%8E%A5%E7%B6%9A/ | ||
| + | |||
| + | urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); はjsonでなくpost時はこんな感じにしないとならない。 | ||
| + | |||
| + | uaはサーバに接続して変更設定されていることを確認済み。 | ||
| + | |||
| + | ドメイン接続許可しないエラーが出るときはこちらを確認 | ||
| + | |||
| + | [[android/開発環境/Android8]] [ショートカット] | ||
==参考== | ==参考== | ||
| 行43: | 行184: | ||
http://d.hatena.ne.jp/Kazuhira/20131026/1382796711 | http://d.hatena.ne.jp/Kazuhira/20131026/1382796711 | ||
| + | |||
| + | ==uaを設定しない場合とwebviewからもてっくる場合== | ||
| + | HttpURLConnectionのuaデフォ(System.getProperty("http.agent");) | ||
| + | Dalvik/2.1.0 (Linux; U; Android 9; Pixel 2 XL Build/PPR2.181005.003) | ||
| + | webviewのua [[android/webview/useragent]] [ショートカット] | ||
| + | Mozilla/5.0 (Linux; Android 9; Pixel 2 XL Build/PPR2.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36 | ||
| + | |||
| + | ==retry処理== | ||
| + | 本来のget処理をexecGetCore()に入れる | ||
| + | <pre> | ||
| + | public boolean execGet() throws Exception { | ||
| + | Exception tmpException = null; | ||
| + | for (int retry = 0; retry <= mRetry; retry++) { | ||
| + | try { | ||
| + | boolean ret = execGetCore(); | ||
| + | if (ret) { | ||
| + | return ret; | ||
| + | } | ||
| + | } catch (Exception e) { | ||
| + | tmpException = e; | ||
| + | } | ||
| + | } | ||
| + | if (Exception != null) { | ||
| + | throw tmpException; | ||
| + | } | ||
| + | return false; | ||
| + | } | ||
| + | </pre> | ||
| + | |||
| + | ==AsyncTask経由== | ||
| + | <pre> | ||
| + | import android.app.Activity; | ||
| + | import android.content.Context; | ||
| + | import android.content.DialogInterface; | ||
| + | import android.content.DialogInterface.OnCancelListener; | ||
| + | import android.os.AsyncTask; | ||
| + | import android.util.Log; | ||
| + | import java.io.UnsupportedEncodingException; | ||
| + | import java.net.URLEncoder; | ||
| + | /* | ||
| + | HttpAsyncTask task = new HttpAsyncTask(); | ||
| + | task.setParam1("hoge"); | ||
| + | task.execute(); | ||
| + | */ | ||
| + | public class HttpAsyncTask extends AsyncTask<String, Integer, Long> | ||
| + | implements OnCancelListener { | ||
| + | private final String TAG = "MyAsyncTask"; | ||
| + | private Context mContext; | ||
| + | private Activity mActivity; | ||
| + | private String param1; | ||
| + | public HttpAsyncTask(Context context) { | ||
| + | this.mContext = context; | ||
| + | } | ||
| + | public void setActivity(Activity activity) { | ||
| + | mActivity = activity; | ||
| + | } | ||
| + | public void setParam1(String str) { | ||
| + | this.param1 = str; | ||
| + | } | ||
| + | @Override | ||
| + | protected void onPreExecute() { | ||
| + | Log.d(TAG, "onPreExecute"); | ||
| + | } | ||
| + | @Override | ||
| + | protected Long doInBackground(String... urls) { | ||
| + | CustomHttpURLConnection http = new CustomHttpURLConnection(); | ||
| + | try { | ||
| + | String encode = URLEncoder.encode(param1, "UTF-8"); | ||
| + | String url = "ttps://hoge.example.com/hoge?param1=" + encode; | ||
| + | http.execGet(url); | ||
| + | Log.d(TAG, url); | ||
| + | } catch (UnsupportedEncodingException e) { | ||
| + | e.printStackTrace(); | ||
| + | } | ||
| + | return 123L; | ||
| + | } | ||
| + | @Override | ||
| + | protected void onProgressUpdate(Integer... values) { | ||
| + | Log.d(TAG, "onProgressUpdate=" + values[0]); | ||
| + | } | ||
| + | @Override | ||
| + | protected void onCancelled() { | ||
| + | Log.d(TAG, "onCancelled"); | ||
| + | } | ||
| + | @Override | ||
| + | protected void onPostExecute(Long result) { | ||
| + | Log.d(TAG, "onPostExecute=" + result); | ||
| + | } | ||
| + | public void onCancel(DialogInterface dialog) { | ||
| + | Log.d(TAG, "Dialog onCancell... calling cancel(true)"); | ||
| + | this.cancel(true); | ||
| + | } | ||
| + | } | ||
| + | </pre> | ||
| + | |||
| + | -MainActivity.java | ||
| + | <pre> | ||
| + | HttpAsyncTask task = new HttpAsyncTask(); | ||
| + | task.setParam1("hoge"); | ||
| + | task.execute(); | ||
| + | try { | ||
| + | task.get(); // awaitのように待機待ちする場合はget()で待機待できる | ||
| + | } catch (ExecutionException e) { | ||
| + | e.printStackTrace(); | ||
| + | } catch (InterruptedException e) { | ||
| + | e.printStackTrace(); | ||
| + | } | ||
| + | </pre> | ||
| + | |||
| + | ==ThreadRunnable経由== | ||
| + | -MainActivity.java | ||
| + | <pre> | ||
| + | HandlerThread thread = new HandlerThread("other"); | ||
| + | thread.start(); | ||
| + | final Handler handler = new Handler(thread.getLooper()); | ||
| + | new Thread(new Runnable() { | ||
| + | @Override | ||
| + | public void run() { | ||
| + | if (handler != null) { | ||
| + | handler.post(new Runnable() { | ||
| + | @Override | ||
| + | public void run() { | ||
| + | CustomHttpURLConnection http = new CustomHttpURLConnection(); | ||
| + | try { | ||
| + | String encode = URLEncoder.encode(param1, "UTF-8"); | ||
| + | String url = "ttps://example.com/hoge?param1=" + encode; | ||
| + | http.execGet(url); | ||
| + | Log.i("test", http.getBody()); | ||
| + | Log.d("test", url); | ||
| + | } catch (UnsupportedEncodingException e) { | ||
| + | e.printStackTrace(); | ||
| + | } | ||
| + | } | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | }).start(); | ||
| + | </pre> | ||
| + | |||
| + | ===android.os.NetworkOnMainThreadExceptionエラーが出る場合=== | ||
| + | UIThreadでネットワークにアクセスするとそうなるので、 | ||
| + | <pre> | ||
| + | HandlerThread thread = new HandlerThread("other"); | ||
| + | thread.start(); | ||
| + | final Handler handler = new Handler(thread.getLooper()); | ||
| + | </pre> | ||
| + | が | ||
| + | Handler handler = new Handler(Looper.getMainLooper()); | ||
| + | になってないか確認する。 | ||
| + | |||
| + | ==戻り値を受けたい場合== | ||
| + | Listenerを使うとか、CountDownLatchを使うとか。 | ||
| + | |||
| + | CountDownLatchの参考 | ||
| + | |||
| + | https://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/CountDownLatch.html | ||
| + | |||
| + | https://qiita.com/maromaro3721/items/c9e16068d13e8ca217f5 | ||
| + | |||
| + | ==Causee: java.security.cert.CertificateException: Chain validation failedエラーが出るとき== | ||
| + | 自己署名証明書を通すように。 | ||
| + | 参考:https://www.it-swarm.dev/ja/android/okhttp%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%82%92%E4%BF%A1%E9%A0%BC%E3%81%99%E3%82%8B/1048177852/ | ||
| + | |||
| + | 以下add分を追加すればよい。 | ||
| + | <pre> | ||
| + | URL url = new URL(url); | ||
| + | urlConn = (HttpsURLConnection) url.openConnection(); | ||
| + | urlConn.setRequestMethod("GET"); | ||
| + | // add start | ||
| + | TrustManager[] trustAllCerts = new TrustManager[] { | ||
| + | new X509TrustManager() { | ||
| + | @Override | ||
| + | public X509Certificate[] getAcceptedIssuers() { | ||
| + | return new X509Certificate[] {}; | ||
| + | } | ||
| + | |||
| + | @Override | ||
| + | public void checkClientTrusted(X509Certificate[] chain, String authType) | ||
| + | throws CertificateException { | ||
| + | } | ||
| + | |||
| + | @Override | ||
| + | public void checkServerTrusted(X509Certificate[] chain, String authType) | ||
| + | throws CertificateException { | ||
| + | } | ||
| + | } | ||
| + | }; | ||
| + | SSLContext ctx = SSLContext.getInstance("TLS"); | ||
| + | ctx.init(null, trustAllCerts, new SecureRandom()); | ||
| + | SSLSocketFactory factory = ctx.getSocketFactory(); | ||
| + | urlConn.setSSLSocketFactory(factory); | ||
| + | // add end | ||
| + | urlConn.connect(); | ||
| + | </pre> | ||
| + | |||
| + | ===openStreamで起こる場合=== | ||
| + | 以下のように、urlのopenStrem()を削除してHttpsURLConnectionのgetInputStream()を追加して、上記項目のように、TLSの記述をHttpsURLConnectionへ追加する。 | ||
| + | <pre> | ||
| + | URL url = new URL(url); | ||
| + | - is = url.openStream(); | ||
| + | HttpsURLConnection urlConn = (HttpsURLConnection)u.openConnection(); | ||
| + | + is = urlConn.getInputStream(); | ||
| + | </pre> | ||
| + | |||
| + | ===KitKat(4.4)でSSLのConnection reset by peerエラーが出るとき=== | ||
| + | 以下エラーが出るとき | ||
| + | <pre> | ||
| + | Error Msg: SSL handshake aborted: ssl=0x761439c0: I/O error during system call, Connection reset by peer | ||
| + | </pre> | ||
| + | 以下を入れると直った。 | ||
| + | <pre> | ||
| + | try { | ||
| + | ProviderInstaller.installIfNeeded(mContext.getApplicationContext()); | ||
| + | } catch (GooglePlayServicesRepairableException e) { | ||
| + | e.printStackTrace(); | ||
| + | } catch (GooglePlayServicesNotAvailableException e) { | ||
| + | e.printStackTrace(); | ||
| + | } | ||
| + | </pre> | ||
| + | 参考:https://www.it-swarm.dev/ja/android/javaxnetsslsslexception%EF%BC%9Aandroid%E5%8F%A4%E3%81%84%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%A7ssl%E3%83%8F%E3%83%B3%E3%83%89%E3%82%B7%E3%82%A7%E3%82%A4%E3%82%AF%E3%81%8C%E4%B8%AD%E6%AD%A2%E3%81%95%E3%82%8C%E3%81%BE%E3%81%97%E3%81%9F/829670631/ | ||
2020年9月4日 (金) 15:23時点における最新版
目次
準備
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
サンプル
同期処理のみ(AsyncTaskなどで実行すること)
get
CustomHttpURLConnection http = new CustomHttpURLConnection();
HashMap<String, String> params = new HashMap<String, String>();
params.put("errorlog", stackTrace);
http.setParams(params);
http.execGet("https://api.github.com/feeds");
post
CustomHttpURLConnection http = new CustomHttpURLConnection();
HashMap<String, String> params = new HashMap<String, String>();
params.put("errorlog", stackTrace);
http.setParams(params);
http.execPost("https://api.github.com/feeds");
CustomHttpURLConnection.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.HashMap;
import java.util.Set;
import android.net.Uri;
import android.util.Log;
class CustomHttpURLConnection
{
HttpURLConnection urlConn = null;
HashMap<String,String> mParams = new HashMap<String,String>();
String body = "";
public void setParams(HashMap<String,String> params) {
mParams = params;
}
public void execGet(String strUrl) {
// System.setProperty("http.agent", "Dalvik/2.1.0 (Linux; U; Android 9; H8216 Build/PDP-PKQ1.180708.001-10229)"); // System.getProperty("http.agent");
Log.i("HttpURLConnection", "ua=" + System.getProperty("http.agent"));
InputStream in = null;
BufferedReader reader = null;
try {
if (mParams.size() > 0) {
Uri.Builder builder = new Uri.Builder();
Set keys = mParams.keySet();
for (Object key : keys) {
builder.appendQueryParameter((String) key, mParams.get((String) key));
}
String join = builder.build().getEncodedQuery();
Log.i("HttpURLConnection", "join=" + join);
strUrl = strUrl + "?" + join;
}
Log.i("HttpURLConnection", "url=" + strUrl);
URL url = new URL(strUrl);
urlConn = (HttpURLConnection) url.openConnection();
urlConn.addRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlConn.setRequestMethod("GET");
urlConn.setConnectTimeout(10000); // 10s
urlConn.setReadTimeout(1000); // 1s
urlConn.connect();
int status = urlConn.getResponseCode();
Log.i("HttpURLConnection", "status_code=" + status);
if (status == HttpURLConnection.HTTP_OK) {
in = urlConn.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder output = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
output.append(line);
}
Log.i("HttpURLConnection", "res=" + output.toString());
body = output.toString();
}
} catch (SocketTimeoutException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
if (urlConn != null) {
urlConn.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void execPost(String strUrl) {
// System.setProperty("http.agent", "Dalvik/2.1.0 (Linux; U; Android 9; H8216 Build/PDP-PKQ1.180708.001-10229)"); // System.getProperty("http.agent");
Log.i("HttpURLConnection", "ua=" + System.getProperty("http.agent"));
HttpURLConnection urlConn = null;
InputStream in = null;
BufferedReader reader = null;
try {
URL url = new URL(strUrl);
urlConn = (HttpURLConnection) url.openConnection();
urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
urlConn.setRequestMethod("POST");
urlConn.setConnectTimeout(10000); // 10s
urlConn.setReadTimeout(1000); // 1s
urlConn.setInstanceFollowRedirects(false);
urlConn.setRequestProperty("Accept-Language", "jp");
urlConn.setDoOutput(true);
OutputStream outputStream = urlConn.getOutputStream();
Log.i("HttpURLConnection", "mParams.size()=" + mParams.size());
if (mParams.size() > 0) {
Uri.Builder builder = new Uri.Builder();
Set keys = mParams.keySet();
for (Object key : keys) {
builder.appendQueryParameter((String) key, mParams.get((String) key));
}
String join = builder.build().getEncodedQuery();
Log.i("HttpURLConnection", "join=" + join);
PrintWriter ps = new PrintWriter(outputStream);
ps.print(join);
ps.close();
}
outputStream.close();
int status = urlConn.getResponseCode();
String resmessage = urlConn.getResponseMessage();
Log.i("HttpURLConnection", "status_code=" + status);
Log.i("HttpURLConnection", "message=" + resmessage);
if (status == HttpURLConnection.HTTP_OK) {
in = urlConn.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder output = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
output.append(line);
}
Log.i("HttpURLConnection", "res=" + output.toString());
body = output.toString();
}
} catch (SocketTimeoutException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
if (urlConn != null) {
urlConn.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public String getBody() {
return body;
}
}
urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); はjsonでなくpost時はこんな感じにしないとならない。
uaはサーバに接続して変更設定されていることを確認済み。
ドメイン接続許可しないエラーが出るときはこちらを確認
android/開発環境/Android8 [ショートカット]
参考
https://itsakura.com/java-httpurlconnection
http://d.hatena.ne.jp/Kazuhira/20131026/1382796711
uaを設定しない場合とwebviewからもてっくる場合
HttpURLConnectionのuaデフォ(System.getProperty("http.agent");)
Dalvik/2.1.0 (Linux; U; Android 9; Pixel 2 XL Build/PPR2.181005.003)
webviewのua android/webview/useragent [ショートカット]
Mozilla/5.0 (Linux; Android 9; Pixel 2 XL Build/PPR2.181005.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/70.0.3538.110 Mobile Safari/537.36
retry処理
本来のget処理をexecGetCore()に入れる
public boolean execGet() throws Exception {
Exception tmpException = null;
for (int retry = 0; retry <= mRetry; retry++) {
try {
boolean ret = execGetCore();
if (ret) {
return ret;
}
} catch (Exception e) {
tmpException = e;
}
}
if (Exception != null) {
throw tmpException;
}
return false;
}
AsyncTask経由
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.AsyncTask;
import android.util.Log;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/*
HttpAsyncTask task = new HttpAsyncTask();
task.setParam1("hoge");
task.execute();
*/
public class HttpAsyncTask extends AsyncTask<String, Integer, Long>
implements OnCancelListener {
private final String TAG = "MyAsyncTask";
private Context mContext;
private Activity mActivity;
private String param1;
public HttpAsyncTask(Context context) {
this.mContext = context;
}
public void setActivity(Activity activity) {
mActivity = activity;
}
public void setParam1(String str) {
this.param1 = str;
}
@Override
protected void onPreExecute() {
Log.d(TAG, "onPreExecute");
}
@Override
protected Long doInBackground(String... urls) {
CustomHttpURLConnection http = new CustomHttpURLConnection();
try {
String encode = URLEncoder.encode(param1, "UTF-8");
String url = "ttps://hoge.example.com/hoge?param1=" + encode;
http.execGet(url);
Log.d(TAG, url);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return 123L;
}
@Override
protected void onProgressUpdate(Integer... values) {
Log.d(TAG, "onProgressUpdate=" + values[0]);
}
@Override
protected void onCancelled() {
Log.d(TAG, "onCancelled");
}
@Override
protected void onPostExecute(Long result) {
Log.d(TAG, "onPostExecute=" + result);
}
public void onCancel(DialogInterface dialog) {
Log.d(TAG, "Dialog onCancell... calling cancel(true)");
this.cancel(true);
}
}
-MainActivity.java
HttpAsyncTask task = new HttpAsyncTask();
task.setParam1("hoge");
task.execute();
try {
task.get(); // awaitのように待機待ちする場合はget()で待機待できる
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
ThreadRunnable経由
-MainActivity.java
HandlerThread thread = new HandlerThread("other");
thread.start();
final Handler handler = new Handler(thread.getLooper());
new Thread(new Runnable() {
@Override
public void run() {
if (handler != null) {
handler.post(new Runnable() {
@Override
public void run() {
CustomHttpURLConnection http = new CustomHttpURLConnection();
try {
String encode = URLEncoder.encode(param1, "UTF-8");
String url = "ttps://example.com/hoge?param1=" + encode;
http.execGet(url);
Log.i("test", http.getBody());
Log.d("test", url);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
}
}
}).start();
android.os.NetworkOnMainThreadExceptionエラーが出る場合
UIThreadでネットワークにアクセスするとそうなるので、
HandlerThread thread = new HandlerThread("other");
thread.start();
final Handler handler = new Handler(thread.getLooper());
が
Handler handler = new Handler(Looper.getMainLooper());
になってないか確認する。
戻り値を受けたい場合
Listenerを使うとか、CountDownLatchを使うとか。
CountDownLatchの参考
https://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/CountDownLatch.html
https://qiita.com/maromaro3721/items/c9e16068d13e8ca217f5
Causee: java.security.cert.CertificateException: Chain validation failedエラーが出るとき
以下add分を追加すればよい。
URL url = new URL(url);
urlConn = (HttpsURLConnection) url.openConnection();
urlConn.setRequestMethod("GET");
// add start
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
}
};
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, trustAllCerts, new SecureRandom());
SSLSocketFactory factory = ctx.getSocketFactory();
urlConn.setSSLSocketFactory(factory);
// add end
urlConn.connect();
openStreamで起こる場合
以下のように、urlのopenStrem()を削除してHttpsURLConnectionのgetInputStream()を追加して、上記項目のように、TLSの記述をHttpsURLConnectionへ追加する。
URL url = new URL(url); - is = url.openStream(); HttpsURLConnection urlConn = (HttpsURLConnection)u.openConnection(); + is = urlConn.getInputStream();
KitKat(4.4)でSSLのConnection reset by peerエラーが出るとき
以下エラーが出るとき
Error Msg: SSL handshake aborted: ssl=0x761439c0: I/O error during system call, Connection reset by peer
以下を入れると直った。
try {
ProviderInstaller.installIfNeeded(mContext.getApplicationContext());
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
