Android經過Http鏈接MySQL 實現登錄/註冊(數據庫+服務器+客戶端)

各種it學習視頻,你們均可以看看哦!我本身本人都是經過這些來學習it只知識的!
下面是視頻連接
https://shop61408405.taobao.com/?spm=a1z10.5-c.0.0.cAfZMN&qq-pf-to=pcqq.group
1
Android經過Http鏈接MySQL 實現登錄/註冊(數據庫+服務器+客戶端) 2 時間 2015-08-22 11:31:00 博客園-原創精華區 3 原文 4 http://www.cnblogs.com/yzxk/p/4749440.html 5 主題 MySQL HTTP 6 7 寫在最前: 8 9 在實際開發中,相信每一個項目都會有 用戶登錄註冊 功能,這個實現的方法不少,下面是我實現的方法,供你們交流。 10 11 新人發帖,萬分緊張,怎麼樣才能裝做一副常常發帖的樣子不被別人看出來呢-,- 12 13 好了,下面進入正題。 14 15 1、開發環境的部署 16 17 程序結構: 18 19 android+servlet+service+mysql 20 21 僅供參考:能實現相關功能便可 22 23 操做系統:ubuntu 14.10 24 25 數據庫:mysql-5.5 數據庫工具:emma 26 27 服務器:tomcat 服務器工具:Myeclipse 10 28 29 安卓端:真機 android4.4 安卓段工具:eclipse+adt 30 31 注意: 32 33 程序調試過程可能會產生亂碼,只需保持全部工具編碼方式相同便可。 34 35 2、數據庫設計 36 37 數據庫名稱:test 38 39 表名稱:student 40 41 建表語句: 42 43 CREATE TABLE `student` ( 44 `Id` int(11) NOT NULL AUTO_INCREMENT, 45 `username` char(20) NOT NULL DEFAULT '', 46 `password` char(20) NOT NULL DEFAULT '', 47 PRIMARY KEY (`Id`) 48 ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 49 50 表格視圖: 51 52 3、服務器端設計 53 54 1、新建Web Project,命名爲HelloWeb,同時刪除掉WebRoot的index.jsp 55 56 2、項目結構圖以下: 57 58 這裏咱們採用servlet編程,因此不須要任何jsp頁面。 59 60 LogLet類和RegLet類分別用於處理客戶端的登錄和註冊請求;Service類用於完成servlet對數據庫的具體操做;DBManager類用於進行數據庫基本操做; 61 62 左側是項目圖,右側是web.xml配置文件截圖。 63 64 3、項目代碼: 65 66 DBManager.java 67 68 <1> 私有化DBManager的構造函數,定義一個靜態的成員變量,在一個共有方法中實例化該成員變量。若要實例化對象調用此方法便可。 69 70 同一時間該類只能存在一個對象。符合sql對象習慣。 (此方式有缺陷,具體自行搜索) 71 72 <2> 定義數據庫鏈接、關閉以及增刪改查的基本操做,返回結果集。 73 74 package com.db; 75 import java.sql.*; 76 public class DBManager { 77 // 數據庫鏈接常量 78 public static final String DRIVER = "com.mysql.jdbc.Driver"; 79 public static final String USER = "root"; 80 public static final String PASS = "root"; 81 public static final String URL = "jdbc:mysql://localhost:3306/test"; 82 // 靜態成員,支持單態模式 83 private static DBManager per = null; 84 private Connection conn = null; 85 private Statement stmt = null; 86 // 單態模式-懶漢模式 87 private DBManager() { 88 } 89 public static DBManager createInstance() { 90 if (per == null) { 91 per = new DBManager(); 92 per.initDB(); 93 } 94 return per; 95 } 96 // 加載驅動 97 public void initDB() { 98 try { 99 Class.forName("com.mysql.jdbc.Driver"); 100 } catch (Exception e) { 101 e.printStackTrace(); 102 } 103 } 104 // 鏈接數據庫,獲取句柄+對象 105 public void connectDB() { 106 System.out.println("Connecting to database..."); 107 try { 108 conn = DriverManager.getConnection(URL, USER, PASS); 109 stmt = conn.createStatement(); 110 } catch (SQLException e) { 111 e.printStackTrace(); 112 } 113 System.out.println("SqlManager:Connect to database successful."); 114 } 115 // 關閉數據庫 關閉對象,釋放句柄 116 public void closeDB() { 117 System.out.println("Close connection to database.."); 118 try { 119 stmt.close(); 120 conn.close(); 121 } catch (SQLException e) { 122 e.printStackTrace(); 123 } 124 System.out.println("Close connection successful"); 125 } 126 // 查詢 127 public ResultSet executeQuery(String sql) { 128 ResultSet rs = null; 129 try { 130 rs = stmt.executeQuery(sql); 131 } catch (SQLException e) { 132 e.printStackTrace(); 133 } 134 return rs; 135 } 136 // 增添/刪除/修改 137 public int executeUpdate(String sql) { 138 int ret = 0; 139 try { 140 ret = stmt.executeUpdate(sql); 141 } catch (SQLException e) { 142 e.printStackTrace(); 143 } 144 return ret; 145 } 146 } 147 148 Service.java 149 150 這個簡單,根據傳參獲得sql語句,經過DBManager類的 createInstance() 方法實例化對象,調用本類的操做方法,完成數據操做。 151 152 寫到這裏,能夠預見:下一個類會經過調用本類方法完成登錄/註冊的服務。 153 154 package com.service; 155 import java.sql.ResultSet; 156 import java.sql.SQLException; 157 import com.db.DBManager; 158 public class Service { 159 public Boolean login(String username, String password) { 160 // 獲取Sql查詢語句 161 String logSql = "select * from user where username ='" + username 162 + "' and password ='" + password + "'"; 163 // 獲取DB對象 164 DBManager sql = DBManager.createInstance(); 165 sql.connectDB(); 166 // 操做DB對象 167 try { 168 ResultSet rs = sql.executeQuery(logSql); 169 if (rs.next()) { 170 sql.closeDB(); 171 return true; 172 } 173 } catch (SQLException e) { 174 e.printStackTrace(); 175 } 176 sql.closeDB(); 177 return false; 178 } 179 public Boolean register(String username, String password) { 180 // 獲取Sql查詢語句 181 String regSql = "insert into student values('"+ username+ "','"+ password+ "') "; 182 183 // 獲取DB對象 184 DBManager sql = DBManager.createInstance(); 185 sql.connectDB(); 186 int ret = sql.executeUpdate(regSql); 187 if (ret != 0) { 188 sql.closeDB(); 189 return true; 190 } 191 sql.closeDB(); 192 return false; 193 } 194 } 195 196 LogLet.java 197 198 一個簡單的Servlet,用於處理Http請求(get/post)。果真,實例化上一個類的對象,並調用了 login方法,返回值爲布爾類型。 199 200 RegLet.java和該類近乎相同,只是在 serv.login(username, password); 換成了 serv.register(username, password); 此處省去~ 201 202 package com.servlet; 203 import java.io.IOException; 204 import java.io.PrintWriter; 205 import javax.servlet.ServletException; 206 import javax.servlet.http.HttpServlet; 207 import javax.servlet.http.HttpServletRequest; 208 import javax.servlet.http.HttpServletResponse; 209 import com.service.Service; 210 public class LogLet extends HttpServlet { 211 private static final long serialVersionUID = 369840050351775312L; 212 public void doGet(HttpServletRequest request, HttpServletResponse response) 213 throws ServletException, IOException { 214 // 接收客戶端信息 215 String username = request.getParameter("username"); 216 username = new String(username.getBytes("ISO-8859-1"), "UTF-8"); 217 String password = request.getParameter("password"); 218 System.out.println(username + "--" + password); 219 // 新建服務對象 220 Service serv = new Service(); 221 // 驗證處理 222 boolean loged = serv.login(username, password); 223 if (loged) { 224 System.out.print("Succss"); 225 request.getSession().setAttribute("username", username); 226 // response.sendRedirect("welcome.jsp"); 227 } else { 228 System.out.print("Failed"); 229 } 230 // 返回信息到客戶端 231 response.setCharacterEncoding("UTF-8"); 232 response.setContentType("text/html"); 233 PrintWriter out = response.getWriter(); 234 out.print("用戶名:" + username); 235 out.print("密碼:" + password); 236 out.flush(); 237 out.close(); 238 } 239 public void doPost(HttpServletRequest request, HttpServletResponse response) 240 throws ServletException, IOException { 241 } 242 } 243 244 4、客戶端設計 245 246 1、新建Android App Project,命名爲AndroidHTTPDemo 247 248 2、如今開始思考須要什麼東西... 249 250 <1> 登錄和註冊頁面:佈局文件 251 252 login.xml , register.xml 253 254 <2> 登錄和註冊頁面對應的Activity組件,在activity中進行具體操做 255 256 login.java , register.java 257 258 <3> 可以實現Http以get/post方式通訊的類 259 260 WebService.java , WebServicePost.java 261 262 <4> 網絡通訊權限 263 264 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 265 266 <uses-permission android:name="android.permission.INTERNET" /> 267 268 OK,項目結構出爐,右側是Manifeast配置文件的主要內容 269 270 3、如今,咱們開始關注具體的代碼。 271 272 <1> 首先要作的,登錄註冊界面,這個不用多說。我直接放圖, 大體就是下面這個樣子 ,你們能夠按照本身愛好設計。 273 274 (注意一點,由於登錄和註冊的xml、activity都是近乎徹底同樣,最不同的sql語句咱們在以前已經處理過了,因此這裏只寫其中的一個便可) 275 276 <2> 在服務器端編程時咱們瞭解到:服務器端接收客戶端發送的信息,對信息進行一系列處理後,最終信息返回到客戶端。 277 278 首先要想的,就是獲取信息併發送出去,而後接收信息並顯示出來。 279 280 獲取信息好辦,getText()嘛,很差辦的是發送,還有發送所需的線程。 281 282 (網絡服務因爲耗時問題,放在主線程極可能因爲網絡故障致使ANR;因此要開闢子線程留給http網絡服務。固然不使用主線程也能夠,只是不推薦) 283 284 <3> Login.java 有三點須要注意 285 286 第一個是檢測網絡狀態,只能檢測流量,沒法檢測wifi; 287 288 第二個是在子線程中,咱們利用得到的用戶名密碼調用了http通訊類最後返回的info值,不能直接在子線程中更改主線程的頁面值,這裏用了handle解決。 289 290 第三個是這裏有get/post兩種http請求方式,兩個實現類,咱們須要那一個,只要把另外一個註釋掉便可,返回的數據都是同樣的。 291 292 package com.httpdemo; 293 import com.rxz.androidhttpdemo.R; 294 import com.web.WebService; 295 import com.web.WebServicePost; 296 import android.app.Activity; 297 import android.app.ProgressDialog; 298 import android.content.Context; 299 import android.content.Intent; 300 import android.net.ConnectivityManager; 301 import android.os.Bundle; 302 import android.os.Handler; 303 import android.view.Gravity; 304 import android.view.View; 305 import android.view.View.OnClickListener; 306 import android.widget.Button; 307 import android.widget.EditText; 308 import android.widget.TextView; 309 import android.widget.Toast; 310 public class Login extends Activity implements OnClickListener { 311 // 登錄按鈕 312 private Button logbtn; 313 // 調試文本,註冊文本 314 private TextView infotv, regtv; 315 // 顯示用戶名和密碼 316 EditText username, password; 317 // 建立等待框 318 private ProgressDialog dialog; 319 // 返回的數據 320 private String info; 321 // 返回主線程更新數據 322 private static Handler handler = new Handler(); 323 @Override 324 protected void onCreate(Bundle savedInstanceState) { 325 super.onCreate(savedInstanceState); 326 setContentView(R.layout.login); 327 // 獲取控件 328 username = (EditText) findViewById(R.id.user); 329 password = (EditText) findViewById(R.id.pass); 330 logbtn = (Button) findViewById(R.id.login); 331 regtv = (TextView) findViewById(R.id.register); 332 infotv = (TextView) findViewById(R.id.info); 333 // 設置按鈕監聽器 334 logbtn.setOnClickListener(this); 335 regtv.setOnClickListener(this); 336 } 337 @Override 338 public void onClick(View v) { 339 switch (v.getId()) { 340 case R.id.login: 341 // 檢測網絡,沒法檢測wifi 342 if (!checkNetwork()) { 343 Toast toast = Toast.makeText(Login.this,"網絡未鏈接", Toast.LENGTH_SHORT); 344 toast.setGravity(Gravity.CENTER, 0, 0); 345 toast.show(); 346 break; 347 } 348 // 提示框 349 dialog = new ProgressDialog(this); 350 dialog.setTitle("提示"); 351 dialog.setMessage("正在登錄,請稍後..."); 352 dialog.setCancelable(false); 353 dialog.show(); 354 // 建立子線程,分別進行Get和Post傳輸 355 new Thread(new MyThread()).start(); 356 break; 357 case R.id.register: 358 Intent regItn = new Intent(Login.this, Register.class); 359 // overridePendingTransition(anim_enter); 360 startActivity(regItn); 361 break; 362 } 363 ; 364 } 365 // 子線程接收數據,主線程修改數據 366 public class MyThread implements Runnable { 367 @Override 368 public void run() { 369 info = WebService.executeHttpGet(username.getText().toString(), password.getText().toString()); 370 // info = WebServicePost.executeHttpPost(username.getText().toString(), password.getText().toString()); 371 handler.post(new Runnable() { 372 @Override 373 public void run() { 374 infotv.setText(info); 375 dialog.dismiss(); 376 } 377 }); 378 } 379 } 380 // 檢測網絡 381 private boolean checkNetwork() { 382 ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 383 if (connManager.getActiveNetworkInfo() != null) { 384 return connManager.getActiveNetworkInfo().isAvailable(); 385 } 386 return false; 387 } 388 } 389 390 <4> WebService.java 391 392 這裏的IP是你的服務器IP,不肯定時看下是否能用手機ping工具ping通。 393 394 由於我用的是真機,因此模擬器我還真不太清楚,我簡單說一下真機與windows/linux下的服務器網絡鏈接流程,詳情請百度。 395 396 ① 你的服務器端程序已發佈到互聯網:這好辦,就是你的IP地址。 397 398 ② 你是在本地電腦上,這要求你的真機和你的電腦在同一個局域網。兩種較方便的方法:路由器/筆記本的無線網卡 399 400 是我的都能看出來第二種方便,誰也不能到哪都帶個路由器吧,那麼好,筆記本開啓無線熱點,手機wifi鏈接熱點,這是客戶端和服務器就在一個局域網內。 401 402 查看筆記本ip地址中的無線網卡地址([win]ipconfig/[lnx]ifconfig -- wlan),加上你的服務器端口號(服務器爲開啓狀態),訪問便可。 403 404 conn.setConnectTimeout(3000); 須要設置超時時間,不然會執行默認超時時間,30s ? 405 406 接收到的輸入流須要先轉換成比特位,在轉換成string類型。 407 408 package com.web; 409 import java.io.ByteArrayOutputStream; 410 import java.io.IOException; 411 import java.io.InputStream; 412 import java.net.HttpURLConnection; 413 import java.net.URL; 414 public class WebService { 415 private static String IP = "10.42.0.1:8080"; 416 // 經過Get方式獲取HTTP服務器數據 417 public static String executeHttpGet(String username, String password) { 418 HttpURLConnection conn = null; 419 InputStream is = null; 420 try { 421 // 用戶名 密碼 422 // URL 地址 423 String path = "http://" + IP + "/HelloWeb/servlet/MyServlet"; 424 path = path + "?username=" + username + "&password=" + password; 425 conn = (HttpURLConnection) new URL(path).openConnection(); 426 conn.setConnectTimeout(3000); // 設置超時時間 427 conn.setReadTimeout(3000); 428 conn.setDoInput(true); 429 conn.setRequestMethod("GET"); // 設置獲取信息方式 430 conn.setRequestProperty("Charset", "UTF-8"); // 設置接收數據編碼格式 431 if (conn.getResponseCode() == 200) { 432 is = conn.getInputStream(); 433 return parseInfo(is); 434 } 435 }catch (Exception e) { 436 e.printStackTrace(); 437 } finally { 438 // 意外退出時進行鏈接關閉保護 439 if (conn != null) { 440 conn.disconnect(); 441 } 442 if (is != null) { 443 try { 444 is.close(); 445 } catch (IOException e) { 446 e.printStackTrace(); 447 } 448 } 449 } 450 return null; 451 } 452 // 將輸入流轉化爲 String 型 453 private static String parseInfo(InputStream inStream) throws Exception { 454 byte[] data = read(inStream); 455 // 轉化爲字符串 456 return new String(data, "UTF-8"); 457 } 458 // 將輸入流轉化爲byte型 459 public static byte[] read(InputStream inStream) throws Exception { 460 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 461 byte[] buffer = new byte[1024]; 462 int len = 0; 463 while ((len = inStream.read(buffer)) != -1) { 464 outputStream.write(buffer, 0, len); 465 } 466 inStream.close(); 467 return outputStream.toByteArray(); 468 } 469 } 470 471 <5> WebServicePost.java 和上一個大同小異,只不過參數不是放在url中,而是在HashMap中傳輸,數據傳輸方式略有不一樣。 472 473 處理方式不變,還有注意別忘了設置超時。 474 475 package com.web; 476 import java.io.InputStream; 477 import java.util.ArrayList; 478 import java.util.HashMap; 479 import java.util.List; 480 import java.util.Map; 481 import org.apache.http.HttpEntity; 482 import org.apache.http.HttpResponse; 483 import org.apache.http.NameValuePair; 484 import org.apache.http.client.entity.UrlEncodedFormEntity; 485 import org.apache.http.client.methods.HttpPost; 486 import org.apache.http.impl.client.DefaultHttpClient; 487 import org.apache.http.message.BasicNameValuePair; 488 import org.apache.http.params.CoreConnectionPNames; 489 public class WebServicePost { 490 private static String IP = "10.42.0.1:8080"; 491 // 經過 POST 方式獲取HTTP服務器數據 492 public static String executeHttpPost(String username, String password) { 493 try { 494 String path = "http://" + IP + "/HelloWeb/servlet/MyServlet"; 495 // 發送指令和信息 496 Map<String, String> params = new HashMap<String, String>(); 497 params.put("username", username); 498 params.put("password", password); 499 return sendPOSTRequest(path, params, "UTF-8"); 500 } catch (Exception e) { 501 e.printStackTrace(); 502 } 503 return null; 504 } 505 // 處理髮送數據請求 506 private static String sendPOSTRequest(String path, Map<String, String> params, String encoding) throws Exception { 507 List<NameValuePair> pairs = new ArrayList<NameValuePair>(); 508 if (params != null && !params.isEmpty()) { 509 for (Map.Entry<String, String> entry : params.entrySet()) { 510 pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); 511 } 512 } 513 UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs, encoding); 514 HttpPost post = new HttpPost(path); 515 post.setEntity(entity); 516 DefaultHttpClient client = new DefaultHttpClient(); 517 // 請求超時 518 client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000); 519 // 讀取超時 520 client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000); 521 HttpResponse response = client.execute(post); 522 // 判斷是否成功收取信息 523 if (response.getStatusLine().getStatusCode() == 200) { 524 return getInfo(response); 525 } 526 // 未成功收取信息,返回空指針 527 return null; 528 } 529 // 收取數據 530 private static String getInfo(HttpResponse response) throws Exception { 531 HttpEntity entity = response.getEntity(); 532 InputStream is = entity.getContent(); 533 // 將輸入流轉化爲byte型 534 byte[] data = WebService.read(is); 535 // 轉化爲字符串 536 return new String(data, "UTF-8"); 537 } 538 } 539 540 5、運行效果 541 542 以上工做完成後,只須要講服務器端發佈到本地( 附上--mysql-jdbc驅動地址-- ),安卓端發佈到手機,確保局域網內部,ip正確,便可正常訪問。 543 544 客戶端截圖:測試成功 545 546 服務器端截圖:測試成功 547 548 6、源碼 549 550 以上不足之處,還望你們多多指正。 若有問題歡迎給我留言。 551 552 代碼並未涉及到Session保持,自動登錄等,正在改進中,最終效果應該相似於虎牙直播的登錄註冊(恰好舉個例子)
相關文章
相關標籤/搜索