Android
HttpURLConnection
수색…
통사론
- abstract void disconnect ()
- abstract boolean usingProxy ()
- 정적 부울 getFollowRedirects ()
- static void setFollowRedirects (boolean set)
- String getHeaderField (int n)
- 캐릭터 라인 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
은 웹에서 데이터를 송수신하는 데 사용되는 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()
를 호출하여 연결을 닫아야합니다.
다음은 그 예입니다.
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
의 값으로 전송되는 파일에description
.file
은 전송할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()
메서드가 호출됩니다. 데이터는 요청의 HTTP 상태 코드와 응답을 포함하는 문자열을 나타내는 상태 코드가있는 APIResponseObject
클래스의 객체로 반환됩니다. 이 응답을 클래스 (예 : 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();
}