자바 유틸리티를 활용한 외부DB 로그인 - 구현하기
웹 뷰로 로그인을 구현하는 방법에 대해서 소개합니다.
JSP, PHP, SpringFramework 등 언어무관으로 호환됩니다.
1. 안드로이드는 외부 DB를 지원하는가?
지원하지 않습니다.
SQLlite가 있으니, 외부 DB가 지원될 것으로 생각하시는 분도 계실 수 있습니다.
내장 파일처리를 위한 DB하고 외부 DB 지원하고는 별도입니다.
안드로이드로 외부 DB를 처리하고 싶다면, 웹뷰로 메시지 전달 방식으로 처리해야 합니다.
큰 그림에서 살펴보는 프로세스
171127-desc.pptx
이론적인 느낌은 그렇습니다.
구현에 있어서 build.gradle에 Apache 프레임워크를 사용하지 않은 버전입니다.
자바(Java)에서 제공하는 기본 유틸리티를 활용하여 구현한 버전입니다.
2. 시연 - 영상
3. 코드
<? xml version= "1.0" encoding= "utf-8" ?> <manifest xmlns: android = "http://schemas.android.com/apk/res/android" package= "com.localhost.kr.loginexample" > <!-- To auto-complete the email text field in the login form with the user's emails --> <!-- 인터넷 연결 허용하는 퍼미션 --> <uses-permission android :name= "android.permission.INTERNET" /> <application android :allowBackup= "true" android :icon= "@mipmap/ic_launcher" android :label= "@string/app_name" android :roundIcon= "@mipmap/ic_launcher_round" android :supportsRtl= "true" android :theme= "@style/AppTheme" > <activity android :name= ".LoginActivity" android :label= "@string/app_name" > <intent-filter > <action android :name= "android.intent.action.MAIN" /> <category android :name= "android.intent.category.LAUNCHER" /> </intent-filter > </activity > </application > </manifest > AndroidManifest.xml
<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: tools = "http://schemas.android.com/tools" android :layout_width= "match_parent" android :layout_height= "match_parent" android :gravity= "center_horizontal" android :orientation= "vertical" android :paddingBottom= "@dimen/activity_vertical_margin" android :paddingLeft= "@dimen/activity_horizontal_margin" android :paddingRight= "@dimen/activity_horizontal_margin" android :paddingTop= "@dimen/activity_vertical_margin" tools :context= "com.localhost.kr.loginexample.LoginActivity" > <!-- Login progress --> <ScrollView android :id= "@+id/login_form" android :layout_width= "match_parent" android :layout_height= "match_parent" > <LinearLayout android :id= "@+id/email_login_form" android :layout_width= "match_parent" android :layout_height= "wrap_content" android :orientation= "vertical" > <android.support.design.widget.TextInputLayout android :layout_width= "match_parent" android :layout_height= "wrap_content" > <AutoCompleteTextView android :id= "@+id/email" android :layout_width= "match_parent" android :layout_height= "wrap_content" android :inputType= "textEmailAddress" android :maxLines= "1" android :singleLine= "true" /> </android.support.design.widget.TextInputLayout > <android.support.design.widget.TextInputLayout android :layout_width= "match_parent" android :layout_height= "wrap_content" > <EditText android :id= "@+id/password" android :layout_width= "match_parent" android :layout_height= "wrap_content" android :imeActionId= "6" android :imeOptions= "actionUnspecified" android :inputType= "textPassword" android :maxLines= "1" android :singleLine= "true" /> </android.support.design.widget.TextInputLayout > <Button android :id= "@+id/email_sign_in_button" style= "?android:textAppearanceSmall" android :layout_width= "match_parent" android :layout_height= "wrap_content" android : layout_marginTop = "16dp" android :text= "로그인" android :textStyle= "bold" /> </LinearLayout > </ScrollView > </LinearLayout > activity_login.xml
package com.localhost.kr.loginexample;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;/** * Created by lab on 2017-11-26. */ 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("" ); // 보낼 데이터가 있으면 파라미터를 채운다. 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 (!isAnd) if (_params.size() >= 2 ) isAnd = true ; } } /** * 2. HttpURLConnection을 통해 web의 데이터를 가져온다. * */ try { URL url = new URL(_url); urlConn = (HttpURLConnection) url.openConnection(); // [2-1]. urlConn 설정. urlConn.setRequestMethod("POST" ); // URL 요청에 대한 메소드 설정 : POST. urlConn.setRequestProperty("Accept-Charset" , "UTF-8" ); // Accept-Charset 설정. urlConn.setRequestProperty("Context-Type" , "application/x-www-form-urlencoded;charset=UTF-8" ); // [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 ; } } RequestHttpURLConnection.java
package com.localhost.kr.loginexample;import android.content.ContentValues;import android.os.AsyncTask;/** * Created by lab on 2017-11-27. */ 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를 출력한다. //Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show(); } } NetworkTask.java
package com.localhost.kr.loginexample;import android.content.ContentValues;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import java.util.concurrent.ExecutionException;/** * A login screen that offers login via email/password. */ public class LoginActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_login ); final TextView tvID = (TextView)findViewById(R.id.email ); final TextView tvPwd = (TextView)findViewById(R.id.password ); Button button = (Button)findViewById(R.id.email_sign_in_button ); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ContentValues contentValues = new ContentValues(); contentValues.put("email" , tvID .getText().toString().trim()); contentValues.put("pwd" , tvPwd .getText().toString().trim()); NetworkTask networkTask = new NetworkTask("http://192.168.0.1:8080/Member/Check" , contentValues); try { String result = networkTask.execute().get(); Toast.makeText (getApplicationContext(), result, Toast.LENGTH_LONG ).show(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }); } }
LoginActivity.java
[소스코드]
Source-LoginExample.zip
4. 참고 자료
1. http://mailmail.tistory.com/13 , [안드로이드 HTTP 통신] HttpURLConnection으로 웹서버 통신하기
- 소스코드 참고함. / Copy&Paste 했??다.
코드가 잘 되어 있습니다.2. http://seinarin.tistory.com/39 , [Android] HttpClient, HttpPost를 이용한 서버와의 통신
- build.gradle로 구현하는 버전
추가 설명) Apache.http.client로 구현하려면, 아래처럼 구현하면 됩니다.
메니페스트는 인터넷 권한을 사용해주면 됩니다. 위의 내용과 동일합니다.
import java.util.ArrayList;
import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.util.EntityUtils;
............
............
@Override public void onClick(View v) { // TODO Auto-generated method stub String url = "http://xxx.xxx.xxx.xxx:xxxx/login.jsp "; HttpClient http = new DefaultHttpClient();
try {
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); nameValuePairs.add(new BasicNameValuePair("name", "유재석"));
HttpParams params = http.getParams(); HttpConnectionParams.setConnectionTimeout(params, 5000); HttpConnectionParams.setSoTimeout(params, 5000);
HttpPost httpPost = new HttpPost(url); UrlEncodedFormEntity entityRequest = new UrlEncodedFormEntity(nameValuePairs, "EUC-KR"); httpPost.setEntity(entityRequest); HttpResponse responsePost = http.execute(httpPost); HttpEntity resEntity = responsePost.getEntity(); tv_post.setText( EntityUtils.toString(resEntity)); }catch(Exception e){
e.printStackTrace();
} }
1. MainActivity.java
dependencies { implementation fileTree(dir : 'libs' , include : ['*.jar' ]) implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support:design:26.1.0' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' provided 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2' // 신규추가 Apache Client }
2. build.gradle
Source-LoginExample.zip
0.07MB