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,会出现注册成功!
在这里插入图片描述
然后再用这个账户和密码点登录,就会显示登陆成功!
在这里插入图片描述
如果改一下密码,就会显示错误!
在这里插入图片描述
到这里我想你就要落泪了,真的不容易呜呜呜呜呜。


跑起来了,就有信心去研究代码啦~冲鸭!!!

发布了32 篇原创文章 · 获赞 40 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Clover_pofu/article/details/105477245