signed

QiShunwang

“诚信为本、客户至上”

编程新实务 实验四

2021/1/28 12:24:03   来源:

实验四 系统登录/注册模块设计文档

  • 实验要求
    • 1、Android App的设计
    • 2、JSP服务器部分

第一次写博客,有什么不对的地方欢迎指正。

实验要求

对于Android app,至少需要有如下界面:
(1)登录界面:包含用户名、密码的文字标识以及相应的输入栏,登录以及注册的按钮。当输入用户名以及密码后,点击登录按钮,则交数据提交至后台进行验证,如通过验证则跳转至欢迎界面,否则跳转回登录界面,并提示用户的验证错误原因;当用户点击注册按钮则跳转至注册界面。
(2)注册界面:包含用户名、密码以及确认密码的文字标识以及相应的输入栏,提交以及取消按钮。当输入相关信息后,首先验证输入的信息是否符合要求(用户名至少5位,最多10位,以英文字母开头,只允许包含英文字母、数字以及_,同时必须至少有一个大写英文字母;密码为6-12位,只允许包含英文字母、数字和_,同时要求确认密码必须与密码一致),如不符合要求则在界面内提示错误,只有符合要求才提交给后台进行注册操作。如注册成功则跳转至欢迎界面,否则跳转回注册界面并提示用户的注册错误原因;当用户点击取消按钮则返回登录界面。
(3)欢迎界面:显示对用户的欢迎信息,其中必须包括用户的登录名。

1、Android App的设计

首先查看工程目录:
在这里插入图片描述
其中EmailUtil是实现邮箱发送验证码的Java类,LoginActivity是实现登录功能的活动类,RandomNumber是实现用随机数n位验证码的Java类,Register是实现注册功能的活动类,Welcome是实现登录成功和注册成功跳转到的欢迎页面的活动类。activity_login.xml是登录页面的布局文件,activity_register.xml是注册页面的布局文件,activity_welcome.xml是欢迎页面的布局文件。
查看登录页面
在这里插入图片描述
查看数据库的数据

在这里插入图片描述
这里我重用了实验二的代码,并且把person表中的username字段作为本次登录的用户名,name字段作为本次登录的密码,teleno作为本次注册进行验证的邮箱。
欢迎页面
在这里插入图片描述
注册页面
在这里插入图片描述
登录页面对应的Activity
登录页面除了登录按钮和注册按钮,还实现了一个记住密码的按钮。下面说一下记住密码功能的实现。
首先讲一下Android数据的持久化,Android数据持久化的实现方式主要有三种,分别是文件的存储、SharePreferences存储和数据库存储。我这里记住密码功能的实现用的是SharePreferences存储。SharePreferences使用的是键值对的方式存储,比较方便。实现方法如下。
首先声明两个对象用来存储和取出数据:
在这里插入图片描述
然后在onCreate()方法中获取到了SharePreferences对象,调用getBoolean()方法去获取对应的键值对,如果存在数据的话,就获取对应的数据然后填入对应的框中。
在这里插入图片描述
在按下登录按钮时,判断复选框是否被选中,如果选中了,就保存框中输入的用户名和密码以及判断复选框是否被选中的Boolean型变量,最后提交即可。
在这里插入图片描述
登录按钮功能实现
因为登录时要进行网络的访问,而网络的访问要在子线程里面进行,否则可能会阻塞主进程,所以主要功能都在Request函数新建的子进程里实现了。
在这里插入图片描述
网络连接部分我用的是由Square公司开发的OkHttp网络通信库而没有用原生的HttpURLConnection库。要使用OkHttp库,首先要在项目中添加OkHttp的依赖。编辑app/build.gradle文件,在dependencies闭包中添加如下内容:
在这里插入图片描述
添加上述依赖会自动下载两个库,一个是OkHttp库,一个是Okio库,后者是前者的通信基础。然后就可以用OkHttp来进行网络通信了。主要代码如下:
在这里插入图片描述
首先声明了一个OkHttpClient实例并设置连接和读取超时。下面的requestBody是用来向服务器post数据的,这里没有用到,直接把数据——username、password写在url中就行了。发起一条http请求主要用到request方法。这里url传入的网络地址要注意,在服务端运行时,网络地址显示的是localhost:8080/DatabaseWeb/Login.jsp,但是我们在AVD模拟器访问时不能这么填,因为localhost只是电脑本地的,而AVD模拟器是属于Android的,不可能访问成功。所以我们要在cmd命令输入ipconfig来获取无线局域网ip地址:

在访问jsp服务器时把localhost换成这个ip地址即可。另外,连不同地方的网的ip可能会不同,例如在宿舍连校园网和在研究生楼连校园网的ip会不同,所以出现无法连接到服务器的情况时,首先要检查一下自己搭建的本地服务器是否正在运行,然后再查一下ip地址是否正确。
之后调用OkHttpClient的newCall()方法来创建一个Call对象,并调用它的execute()方法来发送请求并获取服务器返回的数据。但是返回的数据是如下格式的:
在这里插入图片描述
这显然不是我们真正想要的数据,所以要在服务器把返回的数据进行打包,我选择的是在服务器打包成json格式的数据,键是”result”,value是一个数字对应不同的检测结果,然后客户端用JSONObject来进行解析,直接调用JSONObject的getString(“键值”)方法就可以获取键对应的value。
注:可通过Log日志的方式来展示返回数据,再下面的logcat输入你之前设置好的tag(我设置的是“WY”和“MY”)就可以查看对应的日志。
然后调用result1()函数来展示登录的结果,因为子线程不能进行UI操作,所以result1函数是在UI线程运行的,代码如下:
在这里插入图片描述
因为服务器返回的是一个数字,在这里直接判断返回数据就可以了,如果数据库中有对应的用户名并且密码正确,就返回2,然后用Intent进行活动跳转,跳转到欢迎页面。

注册页面对应的Activity:
注册活动首先进行的是输入的用户名、密码、邮箱地址格式的判断,用户名和密码格式的判断我这里就不过多介绍了,主要是邮箱地址格式的判断。邮箱地址格式的判断主要用到了正则表达式,我也不太理解,只是借鉴了网上的代码,如下:
在这里插入图片描述
各种格式都正确后就可以向邮箱发送验证码来进行新用户注册了。验证码这部分我新申请了一个163邮箱,并完成了相应的设置,具体设置我就不过多介绍了,可以参考下面这个连接:https://www.jb51.net/article/161880.htm。要使用邮箱发送验证码的功能,首先要导入三个包:
在这里插入图片描述
首先在网上下载好这三个包,然后把工程转换到Project模式,把那三个包复制到app文件夹下的libs文件夹下,然后再打开app/build.gradle文件,在dependencies闭包中添加如下内容:
在这里插入图片描述
就可以调用其中的方法了。
在这里我遇到了xxxxxxxxxxx:65579>65535的问题,上网搜了才发现是之前进行各种尝试时导入了过多的包,工程方法超过了65535个,删掉一些没用的包就可以了,其他的解决办法我没有尝试。
然后新增加一个JAVA类EmailUtil来实现邮箱发送验证码的功能,具体代码如下:
在这里插入图片描述
在这里插入图片描述
注意这里是邮箱的授权码,而不是邮箱的登录密码!
写好发送电子邮件的Java类后就可以在Register活动类里面进行邮件验证码发送了。具体实现如下:
在这里插入图片描述
同样是在子线程里面执行的,首先通过生成随机验证码的Java类方法生成一个四位数的随机验证码code,这里code是一个全局变量,然后调用EmailUtil类中的sendHtmlEmail()方法向teleno邮箱发送一个code验证码。获取到验证码后还要检验输入的验证码是否正确,代码如下:
在这里插入图片描述
在做好各种输入格式的验证后就可以进行网络请求来验证用户名是否存在,不存在就注册并存储信息到数据库。网络请求是在Request函数中创建子进程来进行的,和登录活动差不多,我就不过多讲解了,主要代码如下:
在这里插入图片描述
注册结果展示函数:
在这里插入图片描述
至此注册功能实现完毕。
Android端只剩欢迎界面了,由上图就可以看出来我做的欢迎页面有些过于简单了,只是展示了一下登陆成功或注册成功的用户名以及实现一个返回登录界面的按钮。验收时老师都说做得太过简单了,但是没有办法,因为之前没有过Android开发的经验,完全是从零开始,所以在做网络请求、数据返回、邮箱验证以及服务器部分花了太多的时间,加上其他科目实验也很多、选修课期末临近等因素,就只能这样了,剩下部分以后有时间再加上去吧。
最后,Android端千万不要忘了增加对应的网络权限,否则无法进行网络请求和邮箱验证,具体权限如下:
在这里插入图片描述
有些权限是之前打算用Bmob云数据库来实现这次试验的时候加上去的,但是老师说一定要用服务器,所以就放弃用云数据库了,权限也没删掉。

2、JSP服务器部分

先查看工程目录:
在这里插入图片描述
首先时src.database包下的java文件,这些文件是实验一用来进行数据库操作的,这里重用了实验一的代码。下面的jsp文件中,Login.jsp是登录功能的服务器,personWeb.jsp改成了注册功能的服务器。
为我之前实验二的时候已经写好了数据库的查找、插入数据等功能并且能够返回对应的结果,所以这次服务器部分代码比较简单。
登录部分的服务器主要代码如下
在这里插入图片描述
在接收到了服务器传来的用户名和密码后,声明一个int型的变量用来存储返回的结果,然后调用实验一中实现的personDo类中的finddate1函数来查找对应的用户名是否存在,如果不存在,就返回int类型的整数0,如果存在就返回int类型整数1并检查密码是否正确,如果正确就返回int类型整数2。finddate1函数如下:
在这里插入图片描述
获取到返回数据judge后就直接把它封装到json格式的数据中,键为result,value为judge,然后就调用PrintWriter对象的函数write返回给客户端。
这里注意,要使用JSONObject对象来把数据封装成json格式就要导入对应的包,因为Android Studio是自带的所以不用导入,eclipse就要导入。先在网上下载对应的包,我记得要用json应该是要导入6个或者7个包的,这里因为我找的是别人博客的包,有些多余的也一股脑导进去了。记住一定要在正规的网站(最好是官网)或者博客里面去下载,不要到那些乱七八糟的网站去下载,否则运行时发生的错误能够让你崩溃。
在这里插入图片描述
下载完对应的包后,把它们复制粘贴到WEB-INF文件夹下的lib文件夹下面,然后对每一个包点击右键,点击构建路径,增加到构建路径中去。之后就可以调用JSONObject对象的方法了。
注册部分的服务器主要代码如下
在这里插入图片描述
跟登录部分服务器的实现差不多,首先调用finddate()方法获取数据库查找结果,不存在就插入注册填入的信息,然后返回judge判断注册是否成功,0表示数据库没有对应的用户名,1表示用户名已存在。
至此服务器部分完成。
这些功能实现完成后就可以在AVD模拟器上运行了,可以测试出上述功能全部可以通过。这里注意,我没有把自己的服务器部署到服务器平台上,所以只能本地运行测试,如果要用真机测试的话,就要先把手机热点打开,然后用电脑连接上手机热点,使得电脑和手机处于同一局域网环境下,这样网络ip地址才一样,才能用真机进行测试,否则真机测试是无法相应网络请求的。