API 정의
예제에 사용할 api 정의이다. 위 URL에 HTTP 헤더값으로 apikey를 추가하고 email과 password를 입력받아 전송해서 결과값을 출력해보려 한다.
인터넷 접근 권한 허용
<uses-permission android:name="android.permission.INTERNET" />
Androidmanifest.xml의 <manifest ...> </manifest> 안에 넣어서 인터넷을 접근할 수 있도록 한다.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edit_email"
android:hint="email 입력"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edit_password"
android:hint="password 입력"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="로그인"
android:id="@+id/btn_login"
/>
<TextView
android:id="@+id/tv_outPut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="출력 공간"
/>
</LinearLayout>
화면을 구성하는 xml이다. 로그인을 눌렀을때 다음 화면으로 넘어가는 것 말고 api에서 결과값만 받아올 것이기 때문에 한 장만 작성한다. email과 password를 입력하고 버튼을 누르면 해당 결과값이 텍스트뷰에 출력된다.
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.content.ContentValues;
import android.os.AsyncTask;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView tv_outPut;
public EditText edit_email,edit_password;
public Button btn_login;
public static String email,password;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 위젯에 대한 참조.
tv_outPut = (TextView) findViewById(R.id.tv_outPut);
btn_login=(Button)findViewById(R.id.btn_login);
edit_email=(EditText)findViewById(R.id.edit_email);
edit_password=(EditText)findViewById(R.id.edit_password);
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
email=edit_email.getText().toString();
password=edit_password.getText().toString();
String url = "http://XXX.XXX.XXX.XXX/api/index.php/linkb_member/login_member/";
// AsyncTask를 통해 HttpURLConnection 수행.
NetworkTask networkTask = new NetworkTask(url, null);
networkTask.execute();
}
});
// URL 설정.
}
public class NetworkTask extends AsyncTask<Void, Void, String> {
private String url;
private ContentValues values;
public NetworkTask(String url, ContentValues values) {
this.url = url;
this.values = values;
}
@Override
protected String doInBackground(Void... params) {
String result; // 요청 결과를 저장할 변수.
RequestHttpURLConnection requestHttpURLConnection = new RequestHttpURLConnection();
result = requestHttpURLConnection.request(url, values); // 해당 URL로 부터 결과물을 얻어온다.
return result;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//doInBackground()로 부터 리턴된 값이 onPostExecute()의 매개변수로 넘어오므로 s를 출력한다.
tv_outPut.setText(s);
}
}
}
스트링을 저장할 변수 email과 password는 다른 클래스에서 참조가능해야 하므로 static으로 작성한다. 버튼을 눌렀을때 입력한 에디트텍스트의 값이 RequestHttpURLConnection 클래스에서 가공되어 서버로 전송되고 결과값을 아래 텍스트뷰에 출력할 것이다. 원래는 결과가 Success라면 다음 화면으로 넘어가게 되고 그렇지 않다면 예외처리를 하겠지만 테스트를 위해 결과값만 출력하려 한다.
주의할점은 url 주소에 마지막 / 을 빠뜨리면 에러가 발생한다.
RequestHttpURLConnection.java
import android.content.ContentValues;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import static com.group6.myapplication.MainActivity.email;
import static com.group6.myapplication.MainActivity.password;
public class RequestHttpURLConnection {
public String request(String _url, ContentValues _params){
// HttpURLConnection 참조 변수.
HttpURLConnection urlConn = null;
// URL 뒤에 붙여서 보낼 파라미터.
StringBuffer sbParams = new StringBuffer();
/**
* 1. StringBuffer에 파라미터 연결
* */
// 보낼 데이터가 없으면 파라미터를 비운다.
if (_params == null)
sbParams.append("email="+email+"&password="+password);
// 보낼 데이터가 있으면 파라미터를 채운다.
else {
// 파라미터가 2개 이상이면 파라미터 연결에 &가 필요하므로 스위칭할 변수 생성.
boolean isAnd = false;
// 파라미터 키와 값.
String key;
String value;
for(Map.Entry<String, Object> parameter : _params.valueSet()){
key = parameter.getKey();
value = parameter.getValue().toString();
// 파라미터가 두개 이상일때, 파라미터 사이에 &를 붙인다.
if (isAnd)
sbParams.append("&");
sbParams.append(key).append("=").append(value);
// 파라미터가 2개 이상이면 isAnd를 true로 바꾸고 다음 루프부터 &를 붙인다.
if (true)
if (_params.size() >= 2)
isAnd = true;
}
}
/**
* 2. HttpURLConnection을 통해 web의 데이터를 가져온다.
* */
try{
URL url = new URL(_url);
urlConn = (HttpURLConnection) url.openConnection();
// [2-1]. urlConn 설정.
urlConn.setConnectTimeout(15000);
urlConn.setReadTimeout(5000);
urlConn.setDoInput(true);
urlConn.setDoOutput(true);
urlConn.setUseCaches(false);
urlConn.setRequestMethod("POST"); // URL 요청에 대한 메소드 설정 : POST.
urlConn.setRequestProperty("Accept-Charset", "UTF-8"); // Accept-Charset 설정.
urlConn.setRequestProperty("Context_Type", "application/x-www-form-urlencode");
urlConn.setRequestProperty("apikey", ""); // ""안에 apikey를 입력
// [2-2]. parameter 전달 및 데이터 읽어오기.
String strParams = sbParams.toString(); //sbParams에 정리한 파라미터들을 스트링으로 저장. 예)id=id1&pw=123;
OutputStream os = urlConn.getOutputStream();
os.write(strParams.getBytes("UTF-8")); // 출력 스트림에 출력.
os.flush(); // 출력 스트림을 플러시(비운다)하고 버퍼링 된 모든 출력 바이트를 강제 실행.
os.close(); // 출력 스트림을 닫고 모든 시스템 자원을 해제.
// [2-3]. 연결 요청 확인.
// 실패 시 null을 리턴하고 메서드를 종료.
if (urlConn.getResponseCode() != HttpURLConnection.HTTP_OK)
return null;
// [2-4]. 읽어온 결과물 리턴.
// 요청한 URL의 출력물을 BufferedReader로 받는다.
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), "UTF-8"));
// 출력물의 라인과 그 합에 대한 변수.
String line;
String page = "";
// 라인을 받아와 합친다.
while ((line = reader.readLine()) != null){
page += line;
}
return page;
} catch (MalformedURLException e) { // for URL.
e.printStackTrace();
} catch (IOException e) { // for openConnection().
e.printStackTrace();
} finally {
if (urlConn != null)
urlConn.disconnect();
}
return null;
}
}
메인 액티비티에 있는 email,password값을 받아와야 하기 때문에 해당 변수들을 import한다. 패키지명은 필자의 코드와 달라질 것이다. StringBuffer에 파라미터를 연결한다. 서버에서 비교할 값은 email과 password이다. 둘을 연결할 때는 &를 사용한다. 그래서 email=test@test.com&password=1234 처럼 작성한다. 해당 계정은 테스트를 위해 만든 계정이다. 그리고 HTTP의 헤더에 apikey값을 입력해 줘야한다. urlConn.setRequestProperty("apikey", "XXXX"); <- XXXX 대신 입력하면 된다.
출력 결과
이렇게 되면 정상적으로 작동 한 것이다. 오른쪽은 테스트용 계정의 DB값을 입력하고 정상적으로 Success를 받은 모습이고 왼쪽은 해당 사용자의 정보가 DB에 존재하지 않는다는 뜻이다.
apikey값이 올바르지 않다면 위처럼 결과가 나올 것이다.
'Client > Android' 카테고리의 다른 글
Android - ViewPager 사용하기 (+CircleIndicator) (0) | 2020.08.13 |
---|---|
Android - JSON 파싱 예제 (6) | 2020.08.13 |
Android - Rest API에 GET 통신하기 (0) | 2020.08.03 |