Android
HttpURLConnection
サーチ…
構文
- abstract void disconnect()
- abstract boolean usingProxy()
- static boolean getFollowRedirects()
- static void setFollowRedirects(boolean set)
- String getHeaderField(int n)
- String getHeaderFieldKey(int n)
- String getRequestMethod()
- String getResponseMessage()
- int getResponseCode()
- long getHeaderFieldDate(String name、longデフォルト)
- boolean getInstanceFollowRedirects()
- パーミッションgetPermission()
- InputStream getErrorStream()
- void setChunkedStreamingMode(int chunklen)
- void setFixedLengthStreamingMode(int contentLength)
- void setFixedLengthStreamingMode(long contentLength)
- void setInstanceFollowRedirects(boolean followRedirects)
- void setRequestMethod(String method)
備考
HttpURLConnection
は、Web上でデータを送受信するために使用される、Android用の標準HTTPクライアントです。 HTTP(RFC 2616)用のURLConnectionの具体的な実装です。
HttpURLConnectionの作成
新しいAndroid HTTPクライアントHttpURLConnection
を作成するには、URLインスタンスでopenConnection()
を呼び出します。 openConnection()
はURLConnection
返すので、返された値を明示的にキャストする必要があります。
URL url = new URL("http://example.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// do something with the connection
新しいURL
作成する場合は、URL解析に関連する例外も処理する必要があります。
try {
URL url = new URL("http://example.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// do something with the connection
} catch (MalformedURLException e) {
e.printStackTrace();
}
レスポンスボディが読み込まれ、接続が不要になったら、 disconnect()
呼び出すことでdisconnect()
終了する必要があります。
次に例を示します。
URL url = new URL("http://example.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
// do something with the connection
} finally {
connection.disconnect();
}
HTTP GETリクエストを送信する
URL url = new URL("http://example.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
// read the input stream
// in this case, I simply read the first line of the stream
String line = br.readLine();
Log.d("HTTP-GET", line);
} finally {
connection.disconnect();
}
上記の例では例外が処理されないことに注意してください。 (些細な)例外処理を含む完全な例は次のとおりです。
URL url;
HttpURLConnection connection = null;
try {
url = new URL("http://example.com");
connection = (HttpURLConnection) url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
// read the input stream
// in this case, I simply read the first line of the stream
String line = br.readLine();
Log.d("HTTP-GET", line);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
}
HTTP GETリクエストの本文を読む
URL url = new URL("http://example.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
// use a string builder to bufferize the response body
// read from the input strea.
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append('\n');
}
// use the string builder directly,
// or convert it into a String
String body = sb.toString();
Log.d("HTTP-GET", body);
} finally {
connection.disconnect();
}
上記の例では例外が処理されないことに注意してください。
multipart / form-dataにHttpURLConnectionを使用する
multipart / form-data HttpURLConnectionリクエストを呼び出すカスタムクラスを作成する
MultipartUtility.java
public class MultipartUtility {
private final String boundary;
private static final String LINE_FEED = "\r\n";
private HttpURLConnection httpConn;
private String charset;
private OutputStream outputStream;
private PrintWriter writer;
/**
* This constructor initializes a new HTTP POST request with content type
* is set to multipart/form-data
*
* @param requestURL
* @param charset
* @throws IOException
*/
public MultipartUtility(String requestURL, String charset)
throws IOException {
this.charset = charset;
// creates a unique boundary based on time stamp
boundary = "===" + System.currentTimeMillis() + "===";
URL url = new URL(requestURL);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setUseCaches(false);
httpConn.setDoOutput(true); // indicates POST method
httpConn.setDoInput(true);
httpConn.setRequestProperty("Content-Type",
"multipart/form-data; boundary=" + boundary);
outputStream = httpConn.getOutputStream();
writer = new PrintWriter(new OutputStreamWriter(outputStream, charset),
true);
}
/**
* Adds a form field to the request
*
* @param name field name
* @param value field value
*/
public void addFormField(String name, String value) {
writer.append("--" + boundary).append(LINE_FEED);
writer.append("Content-Disposition: form-data; name=\"" + name + "\"")
.append(LINE_FEED);
writer.append("Content-Type: text/plain; charset=" + charset).append(
LINE_FEED);
writer.append(LINE_FEED);
writer.append(value).append(LINE_FEED);
writer.flush();
}
/**
* Adds a upload file section to the request
*
* @param fieldName name attribute in <input type="file" name="..." />
* @param uploadFile a File to be uploaded
* @throws IOException
*/
public void addFilePart(String fieldName, File uploadFile)
throws IOException {
String fileName = uploadFile.getName();
writer.append("--" + boundary).append(LINE_FEED);
writer.append(
"Content-Disposition: form-data; name=\"" + fieldName
+ "\"; filename=\"" + fileName + "\"")
.append(LINE_FEED);
writer.append(
"Content-Type: "
+ URLConnection.guessContentTypeFromName(fileName))
.append(LINE_FEED);
writer.append("Content-Transfer-Encoding: binary").append(LINE_FEED);
writer.append(LINE_FEED);
writer.flush();
FileInputStream inputStream = new FileInputStream(uploadFile);
byte[] buffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.flush();
inputStream.close();
writer.append(LINE_FEED);
writer.flush();
}
/**
* Adds a header field to the request.
*
* @param name - name of the header field
* @param value - value of the header field
*/
public void addHeaderField(String name, String value) {
writer.append(name + ": " + value).append(LINE_FEED);
writer.flush();
}
/**
* Completes the request and receives response from the server.
*
* @return a list of Strings as response in case the server returned
* status OK, otherwise an exception is thrown.
* @throws IOException
*/
public List<String> finish() throws IOException {
List<String> response = new ArrayList<String>();
writer.append(LINE_FEED).flush();
writer.append("--" + boundary + "--").append(LINE_FEED);
writer.close();
// checks server's status code first
int status = httpConn.getResponseCode();
if (status == HttpURLConnection.HTTP_OK) {
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpConn.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
response.add(line);
}
reader.close();
httpConn.disconnect();
} else {
throw new IOException("Server returned non-OK status: " + status);
}
return response;
}
}
それを使用する(非同期の方法)
MultipartUtility multipart = new MultipartUtility(requestURL, charset);
// In your case you are not adding form data so ignore this
/*This is to add parameter values */
for (int i = 0; i < myFormDataArray.size(); i++) {
multipart.addFormField(myFormDataArray.get(i).getParamName(),
myFormDataArray.get(i).getParamValue());
}
//add your file here.
/*This is to add file content*/
for (int i = 0; i < myFileArray.size(); i++) {
multipart.addFilePart(myFileArray.getParamName(),
new File(myFileArray.getFileName()));
}
List<String> response = multipart.finish();
Debug.e(TAG, "SERVER REPLIED:");
for (String line : response) {
Debug.e(TAG, "Upload Files Response:::" + line);
// get your server response here.
responseString = line;
}
パラメータ付きHTTP POSTリクエストの送信
HashMapを使用して、POSTパラメーターを介してサーバーに送信するパラメーターを保管します。
HashMap<String, String> params;
params
HashMapに値が設定されたら、それらをサーバーに送信するために使用されるStringBuilderを作成します。
StringBuilder sbParams = new StringBuilder();
int i = 0;
for (String key : params.keySet()) {
try {
if (i != 0){
sbParams.append("&");
}
sbParams.append(key).append("=")
.append(URLEncoder.encode(params.get(key), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
i++;
}
次に、HttpURLConnectionを作成し、接続を開き、POSTパラメータを送信します。
try{
String url = "http://www.example.com/test.php";
URL urlObj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.connect();
String paramsString = sbParams.toString();
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(paramsString);
wr.flush();
wr.close();
} catch (IOException e) {
e.printStackTrace();
}
次に、サーバーから返された結果を受け取ります。
try {
InputStream in = new BufferedInputStream(conn.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
Log.d("test", "result from server: " + result.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();
}
}
HttpURLConnectionを使用したアップロード(POST)ファイル
リモートサーバにファイルを送信/アップロードするためには、イメージ、ビデオ、オーディオ、またはアプリケーションデータベースのバックアップをリモートプライベートサーバに送信する必要があります。サーバーがコンテンツのPOSTリクエストを期待していると仮定して、Androidでこのタスクを完了する方法の簡単な例を次に示します。
ファイルアップロードは、 multipart/form-data
POSTリクエストを使用して送信されます。実装が非常に簡単です:
URL url = new URL(postTarget);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
String auth = "Bearer " + oauthToken;
connection.setRequestProperty("Authorization", basicAuth);
String boundary = UUID.randomUUID().toString();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
DataOutputStream request = new DataOutputStream(uc.getOutputStream());
request.writeBytes("--" + boundary + "\r\n");
request.writeBytes("Content-Disposition: form-data; name=\"description\"\r\n\r\n");
request.writeBytes(fileDescription + "\r\n");
request.writeBytes("--" + boundary + "\r\n");
request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.fileName + "\"\r\n\r\n");
request.write(FileUtils.readFileToByteArray(file));
request.writeBytes("\r\n");
request.writeBytes("--" + boundary + "--\r\n");
request.flush();
int respCode = connection.getResponseCode();
switch(respCode) {
case 200:
//all went ok - read response
...
break;
case 301:
case 302:
case 307:
//handle redirect - for example, re-post to the new location
...
break;
...
default:
//do something sensible
}
もちろん、例外はスローされるか、宣言される必要があります。このコードについて注意する点は次のとおりです。
-
postTarget
はPOSTの宛先URLです。oauthToken
は認証トークンです。fileDescription
はファイルの説明で、フィールドのdescription
値として送信されます。file
は送信されるファイルです。タイプはjava.io.File
です。ファイルパスがある場合は、代わりにnew File(filePath)
使用できます。 - oAuth認証の
Authorization
ヘッダーを設定します。 - これはApache Common
FileUtil
を使用してファイルをバイト配列に読み込みます。ファイルの内容が既にバイト配列やその他の方法でメモリに格納されている場合は、読み込む必要はありません。
すべてのタイプのHTTP要求を処理するための多目的HttpURLConnectionクラス
次のクラスは、 GET
、 POST
、 PUT
、 PATCH
、およびその他の要求を処理できる単一のクラスとして使用できます。
class APIResponseObject{
int responseCode;
String response;
APIResponseObject(int responseCode,String response)
{
this.responseCode = responseCode;
this.response = response;
}
}
public class APIAccessTask extends AsyncTask<String,Void,APIResponseObject> {
URL requestUrl;
Context context;
HttpURLConnection urlConnection;
List<Pair<String,String>> postData, headerData;
String method;
int responseCode = HttpURLConnection.HTTP_OK;
interface OnCompleteListener{
void onComplete(APIResponseObject result);
}
public OnCompleteListener delegate = null;
APIAccessTask(Context context, String requestUrl, String method, OnCompleteListener delegate){
this.context = context;
this.delegate = delegate;
this.method = method;
try {
this.requestUrl = new URL(requestUrl);
}
catch(Exception ex){
ex.printStackTrace();
}
}
APIAccessTask(Context context, String requestUrl, String method, List<Pair<String,String>> postData, OnCompleteListener delegate){
this(context, requestUrl, method, delegate);
this.postData = postData;
}
APIAccessTask(Context context, String requestUrl, String method, List<Pair<String,String>> postData,
List<Pair<String,String>> headerData, OnCompleteListener delegate ){
this(context, requestUrl,method,postData,delegate);
this.headerData = headerData;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected APIResponseObject doInBackground(String... params) {
Log.d("debug", "url = "+ requestUrl);
try {
urlConnection = (HttpURLConnection) requestUrl.openConnection();
if(headerData != null) {
for (Pair pair : headerData) {
urlConnection.setRequestProperty(pair.first.toString(),pair.second.toString());
}
}
urlConnection.setDoInput(true);
urlConnection.setChunkedStreamingMode(0);
urlConnection.setRequestMethod(method);
urlConnection.connect();
StringBuilder sb = new StringBuilder();
if(!(method.equals("GET"))) {
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"));
writer.write(getPostDataString(postData));
writer.flush();
writer.close();
out.close();
}
urlConnection.connect();
responseCode = urlConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
}
return new APIResponseObject(responseCode, sb.toString());
}
catch(Exception ex){
ex.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(APIResponseObject result) {
delegate.onComplete(result);
super.onPostExecute(result);
}
private String getPostDataString(List<Pair<String, String>> params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for(Pair<String,String> pair : params){
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(pair.first,"UTF-8"));
result.append("=");
result.append(URLEncoder.encode(pair.second, "UTF-8"));
}
return result.toString();
}
}
使用法
POST
データを送信するか、余分なヘッダを送る必要があるかに応じて、クラスの指定されたコンストラクタを使用します。
データのフェッチが完了すると、 onComplete()
メソッドが呼び出されます。データはAPIResponseObject
クラスのオブジェクトとして返されます。このクラスには、要求のHTTPステータスコードとレスポンスを含む文字列を示すステータスコードが含まれています。このレスポンスは、クラス(XMLまたはJSON)で解析できます。
次の例に示すように、クラスのオブジェクトに対してexecute()
を呼び出して要求を実行します。
class MainClass {
String url = "https://example.com./api/v1/ex";
String method = "POST";
List<Pair<String,String>> postData = new ArrayList<>();
postData.add(new Pair<>("email","whatever");
postData.add(new Pair<>("password", "whatever");
new APIAccessTask(MainActivity.this, url, method, postData,
new APIAccessTask.OnCompleteListener() {
@Override
public void onComplete(APIResponseObject result) {
if (result.responseCode == HttpURLConnection.HTTP_OK) {
String str = result.response;
// Do your XML/JSON parsing here
}
}
}).execute();
}