Android
HttpURLConnection
Поиск…
Синтаксис
- аннотация void disconnect ()
- abstract boolean usingProxy ()
- static boolean getFollowRedirects ()
- static void setFollowRedirects (boolean set)
- Строка getHeaderField (int n)
- Строка getHeaderFieldKey (int n)
- Строка getRequestMethod ()
- Строка getResponseMessage ()
- int getResponseCode ()
- long getHeaderFieldDate (String name, long Default)
- boolean getInstanceFollowRedirects ()
- Разрешение getPermission ()
- InputStream getErrorStream ()
- void setChunkedStreamingMode (int chunklen)
- void setFixedLengthStreamingMode (int contentLength)
- void setFixedLengthStreamingMode (long contentLength)
- void setInstanceFollowRedirects (boolean followRedirects)
- void setRequestMethod (метод String)
замечания
HttpURLConnection
- это стандартный HTTP-клиент для Android, используемый для отправки и получения данных через Интернет. Это конкретная реализация URLConnection для HTTP (RFC 2616).
Создание HttpURLConnection
Чтобы создать новый HTTP HTTP Client HttpURLConnection
, вызовите openConnection()
в экземпляре URL. Поскольку openConnection()
возвращает URLConnection
, вам необходимо явно openConnection()
возвращаемое значение.
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()
.
Вот пример:
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();
}
Обратите внимание, что исключения не обрабатываются в приведенном выше примере.
Использовать HttpURLConnection для multipart / form-data
Создание пользовательского класса для вызова запроса MttpURLConnection multipart / form-data
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;
}
}
Используйте его (Async)
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();
}
}
Загрузить (POST) файл с использованием HttpURLConnection
Довольно часто необходимо отправить / загрузить файл на удаленный сервер, например изображение, видео, аудио или резервную копию базы данных приложения на удаленный частный сервер. Предполагая, что сервер ожидает запроса POST с контентом, вот простой пример того, как выполнить эту задачу в Android.
Загрузка файлов отправляется с использованием POST-запросов multipart/form-data
. Это очень легко реализовать:
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
- это целевой URL-адрес POST;oauthToken
- токен аутентификации;fileDescription
- это описание файла, которое отправляется как значениеdescription
поля;file
- это файл, который нужно отправить - он имеет типjava.io.File
- если у вас есть путь к файлу, вы можете использоватьnew File(filePath)
. - Он устанавливает заголовок
Authorization
для аутентификации oAuth - Он использует Apache Common
FileUtil
для чтения файла в массив байтов - если у вас уже есть содержимое файла в байтовом массиве или каким-то другим способом в памяти, тогда нет необходимости его читать.
Многоцелевой класс HttpURLConnection для обработки всех типов HTTP-запросов
Следующий класс может использоваться как один класс, который может обрабатывать 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();
}