各種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保持,自動登錄等,正在改進中,最終效果應該相似於虎牙直播的登錄註冊(恰好舉個例子)