首页 理论教育 探究Web服务器的访问机制

探究Web服务器的访问机制

时间:2026-01-23 理论教育 安安 版权反馈
【摘要】:本实验介绍的是Android应用程序与Web服务器整合的应用程序。熟悉基本的服务器端环境搭建方法。熟悉Android客户端和Web服务器端数据交互的方式。掌握Web服务器端的Servlet和数据库技术,主要包括HttpServlet、c3p0数据库连接池配置和使用,数据库常用操作包括预处理语句PreparedStatement对象、结果集ResultSet对象、数据库连接Connection的获取和关闭。在命令行终端执行“mysqld--install”命令安装mysqld服务,执行“net start mysql”命令启动MySQL服务。图5.21配置Tomcat应用服务器5.Eclipse环境设置设置Eclipse的默认字符集。

1.实验目的

移动设备的硬件资源比较有限,从而限制了移动设备的计算能力、存储能力、共享能力等。移动设备具有便于携带、可随时访问网络等特点,比较适合做客户端。目前很多应用中都使用了客户端/服务器端这种方式,服务器端可以向客户端推送信息,客户端向服务器端请求数据,服务器端还可以承担数据保存、数据处理等消耗资源的任务。

本实验介绍的是Android应用程序与Web服务器整合的应用程序。服务器端使用MySQL数据库和Eclipse Java EE版本进行开发,中间层采用Servlet,数据库连接使用c3p0技术对数据库进行操作。

本实验的主要目的包括以下几点。

(1)熟悉基本的服务器端环境搭建方法。

(2)熟悉Android客户端和Web服务器端数据交互的方式。

(3)掌握Android客户端和Web服务器端JSON数据封装和解析的方式。

(4)掌握Web服务器端的Servlet和数据库技术,主要包括HttpServlet、c3p0数据库连接池配置和使用,数据库常用操作包括预处理语句PreparedStatement对象、结果集ResultSet对象、数据库连接Connection的获取和关闭。

2.安装MySQL

(1)下载MySQL,这里以MySQL Community Server 8.0.17为例,如图5.17所示。MySQL分为安装版和压缩版,这里推荐下载压缩版。下载完成后解压压缩包,这里解压至C:\Program Files目录下。

图示

图5.17 下载MySQL

(2)在解压后的目录C:\Program Files\mysql-8.0.17-winx64下创建文件my.ini,并且设置该文件的内容如下。

图示

注意:datadir需要设置成自己的MySQL的解压缩目录。

(3)配置MySQL的环境变量,首先创建MYSQL_HOME系统变量,然后将%MYSQL_HOME%\bin加入环境变量,如图5.18和图5.19所示。

图示

图5.18 配置MYSQL_HOME系统变量

(4)以管理员身份运行cmd进入Windows命令行终端,执行“mysqld--initialize”命令对MySQL进行初始化,此时会在C:\Program Files\mysql-8.0.17-winx64目录下生成一个新目录data,命令执行完毕后可以看到root用户生成的随机密码,如图5.20所示。

(5)安装和启动MySQL服务。在命令行终端执行“mysqld--install”命令安装mysqld服务,执行“net start mysql”命令启动MySQL服务。

(6)登录MySQL并修改随机密码。在命令行终端执行“mysql-u root-p”命令,连接MySQL数据库,输入类似图5.20中随机生成的密码,执行以下SQL命令重置root密码。

图示

图5.19 配置path环境变量

图示

图5.20 初始化MySQL

图示

(7)不需要使用MySQL时输入“exit;”退出。

(8)删除MySQL数据库。首先输入“net stop mysql”命令,停止MySQL服务;然后输入“mysqld-remove”移除mysqld服务;最后删除MySQL所在目录。

3.安装Eclipse Java EE

(1)下载Eclipse Java EE。下载地址为https://www.eclipse.org/downloads/packages,本实验以“eclipse-jee-2018-09-win32-x86_64”这个版本为例。

(2)下载完成后解压缩“eclipse-jee-2018-09-win32-x86_64.zip”至“C:\Program Files”目录。

(3)下载并解压Java EE SDK。Oracle官网下载地址为https://www.oracle.com/technetwork/java/javaee/downloads/java-ee-sdk-downloads-3908423.html,下载完成后解压至任意目录。

(4)安装GlassFish应用服务器。运行解压后的文件glassfish4\bin\pkg.bat,提示“是否安装输入y/n”时,输入“y”后按“Enter”键,直至完成安装。

(5)在操作系统桌面创建Eclipse的快捷方式。右击C:\Program Files\eclipse\Eclipse.exe,在弹出的快捷菜单中选择“发送到”|“桌面快捷方式”,并将快捷方式命名为“Eclipse”,以后双击系统桌面上的快捷图标即可运行。

4.配置Tomcat应用服务器

(1)下载Tomcat应用服务器。下载地址为http://tomcat.apache.org/,Tomcat的版本较多,本实验以“apache-tomcat-9.0.13-windows-x64”这个版本为例。

(2)解压缩“apache-tomcat-9.0.13-windows-x64.zip”至“C:\Program Files”目录。

(3)运行Eclipse Java EE,依次选择菜单栏中的“Window”|“Preferences”,然后选择“Server”|“Runtime Environments”,如图5.21(a)所示,单击“Add”按钮弹出图5.21(b)所示的界面,新建一个服务器,这里选择“Apache Tomcat v9.0”。在弹出的窗口的“Tomcat installation directory”文本框中输入Tomcat的安装目录,单击“Finish”完成配置。

图示

图5.21 配置Tomcat应用服务器

5.Eclipse环境设置

(1)设置Eclipse的默认字符集。在Eclipse中默认使用当前操作系统的字符集,一般为GBK,然而我们开发Web应用程序时,一般使用UTF-8,所以需要设置默认字符集。依次选择菜单栏中的“Window”|“Preferences”,选择“General”|“Workspace”,在“Text file encoding”|“Other”区域选择“UTF-8”,如图5.22所示。这样以后新建项目时会默认使用UTF-8字符集。

图示

图5.22 设置Eclipse的默认字符集

(2)设置Build Path。在开发Web应用程序时会用到Tomcat,需要将Tomcat/lib加入编译路径中,否则在建立JSP文件时会出现图5.23所示的错误。为了解决该问题,需要为Eclipse中设置编译运行Java Web项目所需要的jar依赖。具体操作过程为:选择菜单栏中的“Window”|“Preferences”,在弹出的窗口中选择“Java”|“Build Path”|“Classpath Variables”,单击“New…”按钮,新建名为“Tomcat Server”的变量,将Path设置为Tomcat安装目录下的lib目录,如图5.24所示,lib目录下有Web项目所需要的jar包,然后单击“OK”按钮。

图示

图5.23 报错找不到HttpServlet类

图示

图5.24 设置项目基本依赖

然后添加User Libraries,即向以后的每个工程添加依赖的jar包。在图5.24所示的界面中选择“Java”|“Build Path”|“User Libraries”,单击“New…”按钮,新建名为“Tomcat Server”的User Libraries。然后单击“Add External JARs…”按钮,将之前安装的tomcat/lib目录下的所有jar文件选中(快捷键为“Ctrl+A”)后单击“OK”,完成后如图5.25所示。

图示

图5.25 设置User Libraries

(3)新建Web服务器。在Eclipse主界面依次选择“Window”|“Show View”|“Other”|“Server”|“Servers”查看已创建的Web服务器,如图5.26所示。

为避免启动服务器时出现图5.27所示的错误,右击“Tomcat v9.0 Server at localhost”删除该服务器。单击链接“No servers are available…”,如图5.28所示,重新创建一个Web服务器。在图5.29所示的界面中选择“Tomcat v9.0 Server”,单击“Finish”按钮完成服务器的创建。

图示

图5.26 Web服务器窗口

图示

图5.27 Web服务器报错

图示

图5.28 Web服务器报错信息

6.HttpServlet介绍

Servlet由两个Java包组成:javax.servlet和javax.servlet.http。在javax.servlet包中定义了所有Servlet类都必须实现或扩展的通用接口和类。在javax.servlet.http包中定义了采用HTTP(超文本传输协议)的HttpServlet类。HTTP的请求方式包括GET、POST、HEAD、DELETE、OPTIONS、PUT和TRACE,在HttpServlet类中提供了相对应的服务方法,分别为doGet()、doPost()、do Head()、doDelete()、doOptions()、doPut()和do Trace(),本实验主要使用了doGet()和doPost()两种方法。

图示

图5.29 新建Web服务器

GET请求和POST请求差异较多,最本质的区别主要包括以下几点。

(1)安全性:GET请求的参数放在URL中,如将用户名和密码放入URL中:http://localhost:8080/index/login?username=123456&password=1q2w3e4r,而POST请求的参数是放在请求body中的,所以GET相对来说安全性有所欠缺,不能用于传递敏感信息。

(2)长度:GET请求的URL传参有长度限制,一般来说提交的数据最大是2 KB,而POST请求没有长度限制。

(3)编码:GET请求的参数只能是ASCII码,所以中文需要URL编码,而POST请求传参没有这个限制。

本实验中使用HttpServlet容器响应Android客户端请求的整个流程如下所述。

(1)Android客户端向服务器端Servlet容器发出HTTP请求。

(2)Servlet容器解析来自Android客户端的HTTP请求。

(3)Servlet容器创建一个Http Request对象,在这个对象中封装HTTP请求信息。

(4)Servlet容器创建一个Http Response对象。

(5)Servlet容器调用HttpServlet的service()方法,把Http Request和Http Response对象作为service()方法的参数传给HttpServlet对象。

(6)HttpServlet调用Http Request的相关方法,获取HTTP请求信息。

(7)服务器端根据请求信息调用相关方法,如数据库操作的方法等,获取数据后,HttpServlet调用Http Response的相关方法,生成JSON响应数据。

(8)Servlet容器把HttpServlet的响应结果传送给Android客户端。

(9)Android客户端解析服务器端传送过来的JSON数据,根据数据更新界面。

7.界面与代码结构

本实验模仿App登录功能的实现。在图5.30(a)所示的界面中输入正确的用户名和密码后,跳转到图5.30(b)所示的界面,如果输入的用户名或者密码不正确,则弹出Toast显示“用户名或者密码有误!”。启动应用程序后第一个界面如图5.30(a)所示,对应的代码是图5.30(c)中的Main Activity.java,输入正确的用户名和密码后通过Http Util.java文件中的post()方法发送请求给服务器端,服务器端收到消息后会根据Servlet文件中的配置执行LoginServlet.java这个类,然后通过JDBCUtils.java获取数据库连接,由User Dao.java执行数据查询,查询的结果返回给LoginServlet.java,封装成User Login Dto对象,最后通过Json Utils.java封装成JSON消息返回给客户端,客户端接收到JSON消息后进行解析,如果解析结果为“success”则跳转到图5.30(b)所示的界面,否则弹出Toast提示信息。客户端和服务器端的代码结构分别如图5.30(c)和图5.30(d)所示。

图示

图5.30 App13界面与代码结构

8.实验步骤

步骤1:在Android Studio中新建一个Android工程并将其命名为App13,根据图5.30(a)和图5.30(b)编写界面部分代码,注册“登录”监听事件。(https://www.xing528.com)

步骤2:在确保MySQL服务已经启动的情况下,登录MySQL数据库。登录后执行以下脚本(注解无须输入)。

图示

图示

若执行以上SQL语句没有报错,则输入“exit”退出。执行完毕后创建了一张表t_users,并且添加了用户名为“Tom”密码为“123456”的一条数据。若执行过程中有报错信息,则根据报错提示信息解决问题。

步骤3:在客户端设置Gson的依赖,并将以下3个jar包复制至app13\libs目录下。由于在模块的build.gradle文件中已经加入了“implementation fileTree(include:[*.jar],dir:libs)”描述,因此libs目录下的jar包会自动设置为模块的依赖,编译、链接、打包时会自动加载图5.31所示的jar包。

图示

图5.31 客户端需要的jar包

步骤4:创建包路径“cn.edu.android.app13.response”和“cn.edu.android.app13.Util”。右击模块的包路径“cn.edu.android.app13”,在弹出的菜单中依次选择“New”|“Package”,在弹出的对话框中输入“response”,然后以同样的方法创建另一个包路径。

步骤5:在cn.edu.android.app13.response包路径下新建User类,为该类创建4个成员变量,分别表示用户ID、用户名、密码和性别,并创建带有4个参数的构造方法,生成所有成员变量的setter()和getter()方法。

图示

图示

步骤6:在cn.edu.android.app13.response包路径下新建UserDto类,在该类中新建两个成员变量,并生成setter()和getter()方法,用于解析服务器端发来的JSON消息。

图示

步骤7:在cn.edu.android.app13.Util包路径下新建Json Util类,在该类中增加将对象转换成JSON数据、将数组转换成JSON数据、将JSON数据转换成对象的方法。

图示

图示

步骤8:在cn.edu.android.app13.Util包路径下新建Http Util类,本实验采用Apache Http Client与远程服务器通信,为了简化Http Client的用法,定义了Http Util对get()方法和post()方法发送请求的方法并进行了封装,本实验中采用post()方法,代码如下所示。

图示

图示

图示

步骤9:在Main Activity中获取界面控件,并为“登录”按钮设置触发函数,对应的代码请读者自行完成。

步骤10:该类中需要的全局变量如下所示。

图示

步骤11:Main Activity的“登录”按钮调用login()方法,在login()方法中调用Http Util类中的方法发送post请求,并将结果通过Handler更新到Login Activity,Login Activity请读者根据前面讲述的内容自行编写。

图示

图示

步骤12:客户端最后需要在Android Manifest.xml文件中的manifest节点内增加网络访问权限,至此,客户端的设计完成。

图示

步骤13:下面介绍服务器端的代码。首先打开Eclipse新建项目,在Eclipse中依次选择“File”|“new”|“project”,在图5.32(a)所示的界面中选择“Dynamic Web Project”。在接着出现的界面中输入工程名称,如“My Web”,如图5.32(b)所示,单击“Next”进入下一个界面,再次单击“Next”。

图示

图5.32 新建项目(一)

步骤14:在图5.33所示的界面中需要勾选“Generate web.xml deployment descriptor”选项,项目会自动生成web.xml配置文件,单击“Finish”,此工程项目创建完毕。

图示

图5.33 新建项目(二)

步骤15:在该工程内建立LoginServlet类,用于处理客户端发送过来的请求(Request),并且回复一个响应(Response)。该类的包名称为cn.edu.android,并继承HttpServlet类,即在图5.34所示的界面中的“Superclass:”文本框内选择“javax.servlet.http.HttpServlet”。类HttpServlet定义了HTTP下运行的Servlet类所需要的各种方法。

图示

图5.34 新建类

步骤16:在项目中选择“File”|“new”|“Servlet”新建Servlet,即在web.xml文件中创建Servlet和Java类“LoginServlet”的映射关系。在图5.35所示的界面中的“Class name”处单击“Browse…”,并选择LoginServlet,单击“Next”按钮。

步骤17:修改URL映射路径(URL mapping),将默认的LoginServlet修改为Login,如图5.36所示,客户端使用地址“http://localhost:8080/LoginServlet/Login”进行访问,修改完成后单击“Finish”。打开WebContent目录下的web.xml文件查看确认,该文件比原来多了servlet和servlet-mapping节点,修改完成后web.xml文件的内容如下所示。

图示

图5.35 新建Servlet

图示

图5.36 修改URL mapping

图示

图示

Servlet的执行过程即为根据访问地址的路径信息,找到servlet-mapping中urlpattern对应的servlet-name,对应找到servlet中该servlet-class,从而实例化该Servlet并执行。

注意:如果需要处理多个客户端发来的请求,可以在本步骤中增加其他Servlet,并定义对应的类,在新定义的类中实现业务逻辑的处理。

步骤18:复制图5.37所示的4个jar包至My Web\WebContent\WEB-INF\lib目录下,其中c3p0-0.9.1.2.jar用于连接数据库、创建数据库连接池,mysql-connector-java-8.0.13.jar是MySQL数据库提供的jar包。根据图5.30(d)复制客户端的User Dto.java、User.java、Json Utils.java文件至My Web\src\cn\edu\android目录下,并修改包路径。

图示

图5.37 服务器端需要的jar包

步骤19:在My Web\config目录下新建一个XML文件并将其命名为c3p0-config.xml,该文件用于存储数据库用户名和密码、最大连接数等信息,文件的主要内容如下所示。

图示

图示

图示

步骤20:创建JDBCUtils类。该类使用c3p0数据库连接池创建和关闭数据库连接,该类会读取c3p0-config.xml。

图示

图示

步骤21:创建User Dao.java类。在该类中将调用JDBCUtils类中的connDb()方法获取数据库连接,并使用该连接对数据库进行操作,使用完成后调用JDBCUtils类中的closeDb()方法释放数据库连接。为了保证只需要执行一次数据库连接,并防止数据库的多次连接给服务器造成负担,该类采用单例模式返回数据库连接。单例模式的必要条件如下所述。

①私有的构造方法:防止在类外使用new关键字实例化对象。

②私有的成员变量:防止在类外引入这个存放对象的变量。

③公有静态的实例化对象的方法:通过该方法可让用户进行实例化对象的操作。

具体代码如下所示。

图示

图示

图示

步骤22:在LoginServlet.java中增加对客户端的响应代码。该类继承自HttpServlet,创建一个HttpServlet的主要步骤如下所述。

①扩展HttpServlet抽象类。

②覆盖HttpServlet的部分方法,如覆盖doGet()或doPost()方法。

③获取HTTP请求信息。通过get Parameter(String para Name)方法获取请求参数。

④生成HTTP响应结果。通过HttpServlet Response对象生成响应结果,它有一个get Writer()方法,该方法返回一个Print Writer对象,调用该类的void print(String str)方法设置响应消息。

当Android客户端发送请求后,因为在web.xml文件中对LoginServlet进行了注册和声明,当用户发送的URL中匹配到字符串“login”时会调用该类。该类通过对doPost()方法和doGet()方法的实现,可以处理客户端发送过来的POST请求和GET请求。从HttpServletRequest中获取参数后,查询数据库,将从数据库中获取的结果封装成JSON消息,通过HttpServlet Response返回给Android客户端。

图示

图示

图示

步骤23:运行服务器端代码和客户端代码,对代码进行测试。

知识拓展:第三方库

在以往的实验中经常要调用第三方库,主要为jar包,事实上Android中常见的第三方库包括:*.so、*.jar、*.aar三种类型。

JAR(Java Archive,Java归档)是与平台无关的文件格式,它允许将若干*.class文件组合成一个压缩文件,JAR文件一般情况下只包含class文件与清单文件,不包含资源文件,如图片等所有res中的文件。

AAR文件是Android库项目的二进制归档文件,可以包含项目所有资源class文件以及res资源。要将某个模块打包成AAR文件,需要新建模块时选择“Android Library”模块类型,如图5.38所示,不要建成Android Project,运行该模块后,Android Studio自动把该模块打包成aar包。

Android中的SO文件是动态链接库,一般来说,SO文件是C或C++语言的内容打包成的库,多用于NDK开发中,例如,底层的硬件调用等情况就需要使用SO文件。SO文件的调用具有以下优点:让开发者最大化利用已有的C和C++代码,达到重用的目的;SO文件是二进制文件,没有解释编译的开销,用SO文件实现的功能比纯Java实现的功能要快;相对于Java代码、二进制代码,SO文件的反编译难度更大,一些核心代码可以考虑放在SO文件中。

图示

图5.38 新建Android Library模块

思考

为了扩展系统功能,如何实现增加一张表或多张表?

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈