반응형
안드로이드에서 HTTP통신을 서버와 통신을 할 때 AsyncTaksk(비동기)로 통신을 해야 한다. 왜냐하면 안드로이드의 메인 스레드는 전부 UI관련 처리를 위해 사용되기 때문이다.
- Rest 아키텍처의 제약 조건을 준수하는 애플리케이션 프로그래밍 인터페이스
- 서버와 클라이언트 구조
- Socket 통신과는 다르게 양방향이 아닌 단방향 통신
- Request와 Response로 이루어짐
- Get, Post, Put, Delete등의 메서드를 사용
- 아래 클래스나 라이브러리를 사용해 통신을 구현
- OkHttp
- Retrofit
- HttpURLConnection/HttpsURLConnection
HttpURLConnection/HttpsURLConnection
- Post와 Get 두가지 방식
- Post : Post에서 URI를 통해 요청하면 리소스를 생성한다.
- Get : URL을 통해 접속해 리소스 값을 조회하는 행위이다.
참고 : https://android-uni.tistory.com/9
POST
public class onHTTPConnection {
String EXCEPTION_ERROR = "Exception Occured. Check the url";
public String POSTFunction(String mUrl, String params) {
try {
//받아온 String을 url로 만들어주기
URL url = new URL(mUrl);
//conn으로 url connection을 open 해주기
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//불러오는데 시간이 오래 걸리는 경우 Time out 설정
conn.setReadTimeout(10000);
//연결하는데 시간이 오래 걸리는 경우 Time out 설정
conn.setConnectTimeout(15000);
//연결 방법 설정
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
//Accept-Charset 설정 UTF-8 or ASCII
conn.setRequestProperty("Accept-Charset", "UTF-8");
conn.setRequestProperty("Context_Type", "application/x-www-form-urlencoded;charset=UTF-8");
// POST로 넘겨줄 파라미터 생성.
byte[] outputInBytes = params.getBytes(StandardCharsets.UTF_8);
OutputStream os = conn.getOutputStream();
os.write(outputInBytes);
os.close();
//결과값을 받아온다.
InputStream is = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer response = new StringBuffer();
while ((line = br.readLine()) != null) {
response.append(line);
response.append('\\r');
}
br.close();
String res = response.toString();
res = res.trim();
return res;
} catch (Exception e) {
e.printStackTrace();
}
Log.d("ERROR", EXCEPTION_ERROR);
return null;
}
}
}
GET
public class onHTTPConnection {
String EXCEPTION_ERROR = "Exception Occured. Check the url";
public String GETFunction(String mUrl) {
try {
URL url = new URL(mUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(15000);
conn.setReadTimeout(10000);
conn.setDoInput(true);
conn.setDoOutput(true);
InputStream is = conn.getInputStream();
StringBuilder sb = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String result;
while ((result = br.readLine()) != null) {
sb.append(result + '\\n');
}
result = sb.toString();
return result;
} catch (Exception e) {
e.printStackTrace();
}
Log.d("ERROR", EXCEPTION_ERROR);
return null;
}
}
}
OkHttp
- RestAPi, HTTP통신을 간편하게 구현할 수 있도록 다양한 기능을 제공해 주는 Square에서 제공하는 Java 오픈소스 라이브러리이다.
- OkHttp 라이브러리는 Retrofit 이라는 라이브러리의 베이스가 된다.
- 이 라이브러리를 이용하면 간편하게 몇 줄로 Rest호출을 전송, Http 기반의 요청 및 응답을 처리할 수 있다.
참고 : https://jade314.tistory.com/entry/Android-Library-OKHttp-http
- gradle에 dependencies 설정
- // define a BOM and its version implementation(platform("com.squareup.okhttp3:okhttp-bom:4.9.1")) // define any required OkHttp artifacts without version implementation("com.squareup.okhttp3:okhttp") implementation("com.squareup.okhttp3:logging-interceptor")
- URL을 다운로드하고 그 내용을 문자열로 출력
- OkHttpClient client = new OkHttpClient(); String run(String url) throws IOException { Request request = new Request.Builder() .url(url) .build(); try (Response response = client.newCall(request).execute()) { return response.body().string(); } }
- json을 서버로 전송
public static final MediaType JSON
= MediaType.get("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
*Get/Head/Delete 예제
public boolean getUserInfo(String key) {
try {
String url = "<http://127.0.0.1:8080/v1/test/get?key=>" + key;
OkHttpClient client = new OkHttpClient();
// GET 요청을 Request.Builder 를 통해 만듦 (get 요청임을 명시)
Request.Builder builder = new Request.Builder().url(url).get();
builder.addHeader("password", "BlahBlah");
Request request = builder.build();
// client 객체의 newCall() 메소드에 만들어진 Request를 전달하고, execute() 메소드를 실행
Response response = client.newCall(request).execute();
// execute() 메소드는 요청에 대한 응답이 올때까지 기다렸다가 반환
if (response.isSuccessful()) {
ResponseBody body = response.body();
if (body != null) {
System.out.println("Response:" + body.string());
}
}else{
System.err.println("Error Occurred");
}
return true;
} catch(Exception e) {
e.printStackTrace();
return false;
}
}
GET요청
GET http://127.0.0.1:8080/v1/test/get?key=123 HTTP/1.1
Request.Builder builder =new Request.Builder().url(url).get();
HEAD요청
HEAD http://127.0.0.1:8080/v1/test/get?key=123 HTTP/1.1
Request.Builder builder =new Request.Builder().url(url).head();
DELETE 요청
DELETE http://127.0.0.1:8080/v1/test/get?key=123 HTTP/1.1
Request.Builder builder =new Request.Builder().url(url).delete();
Retrofit
- 안드로이드 애플리케이션 통신기능에 사용하는 코드를 사용하기 쉽게 만들어 놓은 라이브러리
- Rest 기반의 웹 서비스를 통해 JSON 구조의 데이터를 쉽게 가져오고 업로드할 수 있다.
- 앱-서버 통신을 okhttp 라이브러리로 AsyncTask를 사용하여 구현했다고 할 수 있지만, AsyncTask로 서버와 통신을 구현하는 것은 어렵고 시간이 많이 든다.(비동기 처리 코드를 개발자가 하나하나 작성) 그리고 AsyncTask가 안드로이드에서 deprecated되었다. 이것 대신 Retrofit을 사용하는 것이 가독성이 좋고 훨씬 간편하고 쉽고 빠르다.
세 가지의 클래스 필요
- JSON 형태의 모델 클래스 (kotlin 에서는 data class 를 사용)
- HTTP 작업을 정의하는(onSuccess/onFail) 인터페이스
- Retrofit.Builder를 선언한 클래스 (baseUrl과 Converter등을 선언한다. Interceptor를 추가하여 응답을 가공할수도 있다.)
- Retrofit 라이브러리를 Gradle에 추가
implementation 'com.squareup.retrofit2:retrofit:2.7.2'
implementation 'com.squareup.retrofit2:converter-gson:2.7.2'
- Manifest 파일에 인터넷 permission을 추가
<uses-permission android:name="android.permission.INTERNET"/>
- JSON 형테의 모델 클래스를 작성
data class ResponseDTO ( var result: String )
- RetrofitService interface 를 작성
interface RetrofitService{
//post1
// 매개변수를 미리 정해두는 방식
@POST("/test")
fun postRequest(
@Field("id") id: String,
@Field("pw") pw: String
): Call<ResponseDTO>
//post2
// 호출하는 곳에서 매개변수를 HashMap 형태로 보내는 방식
@POST("/{path}")
fun testRequest(
@Path("path")path: String,
@Body parameters: HashMap<String, Any>
): Call<ResponseDTO>
}
- Retrofit.Builder 로 Retrofit 객체를 초기화
val retrofit = Retrofit.Builder()
.baseUrl("<https://server-url.com/>")
.addConverterFactory(GsonConverterFactory.create())
.build()
val server: RetrofitService = retrofit.create(RetrofitService::class.java)
- Retrofit 객체에 enqueue() 를 사용하여 서버와 통신했을때 콜백을 작성하여 사용
//post1
// 매개변수를 미리 정해두는 방식
server.postRequest("userid","asd1234").enqueue(object : Callback<ResponseDTO>{
override fun onFailure(call: Call<ResponseDTO>?, t: Throwable?) {
Log.e("retrofit", t.toString())
}
override fun onResponse(call: Call<ResponseDTO>?, response: Response<ResponseDTO>?) {
Log.d("retrofit", response?.body().toString())
}
})
//post2
// 호출하는 곳에서 매개변수를 HashMap 형태로 보내는 방식
var params:HashMap<String, Any> = HashMap<String, Any>()
params.put("id", "hello")
params.put("pw", 123123)
server.testRequest("test", params).enqueue(object : Callback<ResponseDTO>{
override fun onFailure(call: Call<ResponseDTO>?, t: Throwable?) {
Log.e("Retrofit", t.toString())
}
override fun onResponse(call: Call<ResponseDTO>?, response: Response<ResponseDTO>?) {
var res: ResponseDTO? = response?.body()
Log.d("Retrofit", res?.result)
}
})
728x90
반응형
'안드로이드 앱 개발 공부 > 안드로이드 기본(노션 이동)' 카테고리의 다른 글
[Android] 디자인 패턴 (MVC, MVP, MVVM) (0) | 2023.03.16 |
---|---|
[Android] List View와 Recycler View의 차이 정리 (0) | 2023.03.16 |
[Android] LayoutInflater 란? (0) | 2023.03.07 |
[Android] Rx (RxJava, RxAndroid,...)란? (0) | 2023.03.07 |
[Android] Context (0) | 2023.03.07 |
댓글