Servlet+安卓端+mysql實現註冊登錄操作

笨笨的博主在搗鼓了快一週之後,終於成功實現了Servlet+安卓端的註冊登錄操作!!!可歌可泣嗚嗚嗚嗚。在網上找了很多例子,但是代碼都沒跑通,加上自己真的很菜(Java編程啥的沒什麼經驗),所以踩了很多坑。現在寫一篇小教程,要注意的細節我儘量提及!讓大家都能體會到自己實現這個的激動心情。

好,廢話不多說,咱們開始!



準備工作

安裝Eclipse、mysql、AndroidStudio、Navicat,並且可以實現用Sevlet對mysql數據庫的讀寫操作。看到這裏你可能準備告辭了,但是不管在哪你都得先學會這些吖!我也是從0(真的是24k純0!!)起步的,推薦去跟着【一步一個腳印】Tomcat+MySQL爲自己的APP打造服務器這個教程學,不懂的可以問我!(趁着我剛學過還有印象)這個教程系列你從(1)服務器環境搭建學到(2-3)Servlet連接MySQL數據庫,學完就可以來看我這篇了,我這篇其實就是原教程的(3-1)Android 和 Service 的交互之GET方式,只是原教程有很多基礎的地方都沒講(原博主大神估計覺得這些基礎到不用講,我眼淚掉下來),導致我很多地方都不知道要改,或者不知道怎麼操作。
所以!!!!將心比心,天下小白是一家,我這篇博客就力求做到無微不至吧!!!

害,廢話還是說了這麼多,咱們現在真的真的要開始了!


用Navicat連接mysql數據庫

通過這個可以比較方便地在mysql的可視化窗口(就是Navicat)裏面創建表格。
因爲這次交互是想達到:註冊的話,就在表格裏添加賬號和密碼;登陸的話,就驗證賬號和密碼是否匹配。所以我們先用Navicat連接上數據庫,怎麼創建連接和創建庫參考這篇文章
連接好之後,在你創建的新連接(建議小白們都和我取一樣的名字,免得後面不知道怎麼改代碼,我的新連接名是localhost_3306)下面自己建的一個庫(我的庫名叫first_mysql_test)下面建一個表格,如下:
在這裏插入圖片描述
輸入如下的信息,輸入好之後,再點擊空白區域:
在這裏插入圖片描述
會出現藍色塊(不一定是account,有藍色塊出現就行),右鍵它,選擇“添加欄位”:
在這裏插入圖片描述
輸入password欄,如下,然後點擊保存。
在這裏插入圖片描述
名字叫table_id。(如果是0基礎小白就不要起別的名字了,免得複製我後面給的代碼之後又不知道去哪改,我勸你對自己好一點
在這裏插入圖片描述
好啦,數據庫的創建工作告一段落,下面是Eclipse的內容~


用Eclipse連接mysql數據庫

新建項目

首先,右鍵file,選new,然後選others。在這裏插入圖片描述
在Web文件夾下找到dynamic web project。
這裏說明一下,博主的Eclipse是JavaEE的,直接就有dynamic web project,其他版本的好像還要裝插件之類的。避免麻煩可以再裝一個我這個版本的(建議這樣做),反正Eclipse是免安裝的直接用。諾,鏈接在這,密碼:qpxu。

找到.jar文件

找到一個類似這個名字的文件,mysql-connector-java-版本號-bin.jar,
在這裏插入圖片描述
如果沒有的話,就去官網下載,
在這裏插入圖片描述
如果你和我一樣是windows就選platform independent。
在這裏插入圖片描述

在這裏插入圖片描述
下載就開始辣!會hin慢,如果不嫌棄的話可以嘗試直接用我的,不過版本不是最新的,是5.1.40。諾,鏈接在這,提取碼:ox4o。
把.jar文件複製到對應目錄下:
在這裏插入圖片描述
然後add to build path,具體操作可以參考這篇文章

至此Eclipse和數據庫的連接就搞定辣!下一步!


Eclipse創建RegisterServlet1和LoginServlet

爲什麼是個1,因爲我創建過RegisterServlet,然後沒成功,後來修改RegisterServlet1成功了我就不敢改回去,萬一又不行我就生氣氣了。所以,就麻煩你也耐着性子把servlet的名字設成RegisterServlet1叭,免得後面代碼出錯!好啦操作如下:
在這裏插入圖片描述
參數設置:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
加載一會之後,在主頁面左側的欄上看到ServletTest1.
在這裏插入圖片描述

新建一個DBUtil.java類

這個是一些配置信息。新建一個類:在src文件夾右鍵,new——other——class。
在這裏插入圖片描述
在這裏插入圖片描述
簡單粗暴,把這段代碼貼上去(記得修改用戶名和密碼!!!)

DBUtil.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBUtil {
	// table
	public static final String Table_Account="table_id";
 
	// connect to MySql database
	public static Connection getConnect() {
		String url = "jdbc:mysql://localhost:3306/first_mysql_test"; // 數據庫的Url
		Connection connecter = null;
		try {
			Class.forName("com.mysql.jdbc.Driver"); // java反射,固定寫法
			//劃重點!!下面的root和password要改成你創建連接時候用的用戶名和密碼!!!
			connecter = (Connection) DriverManager.getConnection(url, "root", "password");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			System.out.println("SQLException: " + e.getMessage());
			System.out.println("SQLState: " + e.getSQLState());
			System.out.println("VendorError: " + e.getErrorCode());
		}
		return connecter;
	}
}

用戶名和密碼就是你創建連接時候用的那個:
在這裏插入圖片描述

新建註冊servlet

在這裏插入圖片描述
在這裏插入圖片描述
省點事兒,直接finish:
在這裏插入圖片描述

RegisterServlet1.java
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * Servlet implementation class RegisterServlet1
 */
@WebServlet(description = "用來和客戶端交互", urlPatterns = { "/RegisterServlet1" })
public class RegisterServlet1 extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
	/**
	 * Default constructor.
	 */
	public void RegisterServlet() {
		log("RegisterServlet construct...");
	}
 
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String method = request.getMethod();
		if ("GET".equals(method)) {
			log("請求方法:GET");
			doGet(request, response);
		} else if ("POST".equals(method)) {
			log("請求方法:POST");
			doPost(request, response);
		} else {
			log("請求方法分辨失敗!");
		}
	}
 
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/* 先設置請求、響應報文的編碼格式  */
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		String code = "";
		String message = "";
 
		String account = request.getParameter("account");
		String password = request.getParameter("password");
		log(account + ";" + password);
 
		Connection connect = DBUtil.getConnect();
		try {
			Statement statement = connect.createStatement();
			String sql = "select account from " + DBUtil.Table_Account + " where account='" + account + "'";
			log(sql);
			ResultSet result = statement.executeQuery(sql);
			if (result.next()) { // 能查到該賬號,說明已經註冊過了
				code = "100";
				message = "該賬號已存在";
			} else {
				String sqlInsert = "insert into " + DBUtil.Table_Account + "(account, password) values('"
						+ account + "', '" + password + "')";
				log(sqlInsert);
				if (statement.executeUpdate(sqlInsert) > 0) { // 否則進行註冊邏輯,插入新賬號密碼到數據庫
					code = "200";
					message = "註冊成功";
				} else {
					code = "300";
					message = "註冊失敗";
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
 
		response.getWriter().append("code:").append(code).append(";message:").append(message);
	}
 
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException { 
	}
 
	@Override
	public void destroy() {
		log("RegisterServlet destory.");
		super.destroy();
	}

}

在這裏插入圖片描述
咳咳,這裏默認你會Tomcat了哈,不會的回去看前面的【準備工作】。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

新建登錄Servlet

和新建RegisterServlet1一樣的,名字改一下就行
在這裏插入圖片描述

LoginServlet.java
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet(description = "處理登錄邏輯", urlPatterns = { "/LoginServlet" })
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
 
	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public LoginServlet() {
		super();
	}
 
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		/* 先設置請求、響應報文的編碼格式  */
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		
		String code = "";
		String message = "";
 
		String account = request.getParameter("account");
		String password = request.getParameter("password");
		log(account + ";" + password);
 
		Connection connect = DBUtil.getConnect();
		try {
			Statement statement = connect.createStatement();
			String sql = "select account from " + DBUtil.Table_Account + " where account='" + account
					+ "' and password='" + password + "'";
			log(sql);
			ResultSet result = statement.executeQuery(sql);
			if (result.next()) { // 能查到該賬號,說明已經註冊過了
				code = "200";
				message = "登陸成功";
			} else {
 
				code = "100";
				message = "登錄失敗,密碼不匹配或賬號未註冊";
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
 
		response.getWriter().append("code:").append(code).append(";message:").append(message);
	}
 
	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		log("不支持POST方法");
	}
 
}

測試一下

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
然後,我們再點LoginServlet,運行。
在這裏插入圖片描述
在這裏插入圖片描述
好了!服務器端終於搞掂了,接下來就是安卓端!堅持住姐妹們!!!


安卓端

建個項目,名字隨便取,

來到你的AndroidStudio界面,建個新項目,主界面file——new——new project
在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述
欸其實就是一路next直到finish,但是體諒到一些糾結的姐妹我還是耐心地全貼出來,你們也耐心地跟着康康…(抱拳!)

主頁面佈局

項目創建成功之後,點左側的project1。
在這裏插入圖片描述
在這裏插入圖片描述

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    //賬號輸入框
    <EditText
        android:id="@+id/et_account"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="請輸入賬號" />

    //密碼輸入框
    <EditText
        android:id="@+id/et_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="請輸入登錄密碼"
        android:inputType="textPassword" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:orientation="horizontal">

        //註冊按鈕
        <Button
            android:id="@+id/btn_register"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Register" />

        //登錄按鈕
        <Button
            android:id="@+id/btn_login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Login" />

    </LinearLayout>

    <!-- 用來顯示報文返回結果 -->
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

配置文件

新建一個類,命名爲constant。
在這裏插入圖片描述
在這裏插入圖片描述
第一行的package代碼保留你自己的,然後把下面的代碼粘貼上去(記得修改192.168.13.1爲你自己的IP地址!)<

Constant.java

public class Constant {
    public static String URL = "http://192.168.13.1:8080/ServletTest1/"; // IP地址請改爲你自己的IP

    public static String URL_Register = URL + "RegisterServlet1";
    public static String URL_Login = URL + "LoginServlet";
}

不知道自己IP地址咋看的參考這篇文章

主Activity文件

在這裏插入圖片描述

MainActivity.java

同樣,保留第一行的package代碼,後面的代碼如下:

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


public class MainActivity extends Activity {

    private EditText etAccount;
    private EditText etPassword;
    private TextView tvResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etAccount = (EditText) findViewById(R.id.et_account);
        etPassword = (EditText) findViewById(R.id.et_password);
        tvResult = (TextView) findViewById(R.id.tv_result);

        Button btnRegister = (Button) findViewById(R.id.btn_register);
        //註冊監聽,點擊運行register()
        btnRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!TextUtils.isEmpty(etAccount.getText().toString())
                        && !TextUtils.isEmpty(etPassword.getText().toString())) {
                    Log.e("WangJ", "都不空");
                    register(etAccount.getText().toString(), etPassword.getText().toString());
                } else {
                    Toast.makeText(MainActivity.this, "賬號、密碼都不能爲空!", Toast.LENGTH_SHORT).show();
                }
            }
        });

        Button btnLogin = (Button) findViewById(R.id.btn_login);
        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!TextUtils.isEmpty(etAccount.getText().toString())
                        && !TextUtils.isEmpty(etPassword.getText().toString())) {
                    Log.e("WangJ", "都不空");
                    login(etAccount.getText().toString(), etPassword.getText().toString());
                } else {
                    Toast.makeText(MainActivity.this, "賬號、密碼都不能爲空!", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    private void register(String account, String password) {
        String registerUrlStr = Constant.URL_Register + "?account=" + account + "&password=" + password;
        new MyAsyncTask(tvResult).execute(registerUrlStr);
    }

    private void login(String account, String password) {
        String registerUrlStr = Constant.URL_Login + "?account=" + account + "&password=" + password;
        new MyAsyncTask(tvResult).execute(registerUrlStr);
    }

    /**
     * AsyncTask類的三個泛型參數:
     * (1)Params: 開始異步任務執行時傳入的參數類型,對應excute()中傳遞的參數
     * (2)Progress:後臺任務執行過程中,如果需要在UI上先是當前任務進度,則使用這裏指定的泛型作爲進度單位
     * (3)Result:任務執行完畢後,如果需要對結果進行返回,則這裏指定返回的數據類型
     */
    public static class MyAsyncTask extends AsyncTask<String, Integer, String> {

        private TextView tv; // 舉例一個UI元素,後邊會用到

        public MyAsyncTask(TextView v) {
            tv = v;
        }

        @Override
        protected void onPreExecute() {
            Log.w("WangJ", "task onPreExecute()");
        }

        /**
         * @param params 這裏的params是一個數組,即AsyncTask在激活運行時調用execute()方法傳入的參數
         */
        @Override
        protected String doInBackground(String... params) {
            Log.w("WangJ", "task doInBackground()");
            HttpURLConnection connection = null;
            StringBuilder response = new StringBuilder();
            try {
                URL url = new URL(params[0]); // 聲明一個URL,注意如果用百度首頁實驗,請使用https開頭,否則獲取不到返回報文
                connection = (HttpURLConnection) url.openConnection(); // 打開該URL連接
                connection.setRequestMethod("GET"); // 設置請求方法,“POST或GET”,我們這裏用GET,在說到POST的時候再用POST
                connection.setConnectTimeout(8000); // 設置連接建立的超時時間
                connection.setReadTimeout(8000); // 設置網絡報文收發超時時間
                InputStream in = connection.getInputStream();  // 通過連接的輸入流獲取下發報文,然後就是Java的流處理
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return response.toString(); // 這裏返回的結果就作爲onPostExecute方法的入參
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            // 如果在doInBackground方法,那麼就會立刻執行本方法
            // 本方法在UI線程中執行,可以更新UI元素,典型的就是更新進度條進度,一般是在下載時候使用
        }

        /**
         * 運行在UI線程中,所以可以直接操作UI元素
         * @param s
         */
        @Override
        protected void onPostExecute(String s) {
            Log.w("WangJ", "task onPostExecute()");
            tv.setText(s);
        }

    }
}

添加聯網權限

在這裏插入圖片描述
在AndroidManifest.xml文件裏面添加兩句:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

測試

在這裏插入圖片描述
賬號或密碼爲空時,直接點REGISTER或者LOGIN,都會彈出下面的消息。
在這裏插入圖片描述
隨便填一個賬戶和密碼,點擊REGISTER,會出現註冊成功!
在這裏插入圖片描述
然後再用這個賬戶和密碼點登錄,就會顯示登陸成功!
在這裏插入圖片描述
如果改一下密碼,就會顯示錯誤!
在這裏插入圖片描述
到這裏我想你就要落淚了,真的不容易嗚嗚嗚嗚嗚。


跑起來了,就有信心去研究代碼啦~衝鴨!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章