【文档说明】注册登录和注销培训资料.pptx,共(62)页,350.646 KB,由精品优选上传
转载请保留链接:https://www.ichengzhen.cn/view-281906.html
以下为本文档部分文字说明:
第4章注册、登录和注销➢4.1开发步骤➢4.2知识点:模式➢4.3知识点::接口➢4.4知识点::接口➢4.5知识点:2:➢4.6知识点:2:表达式➢4.7知识点:2:标签库第4章注册、登录和注销用户注册是网上书店的基本功能之一。用户如果想从网上书店购买商品
,必须有一个网上书店的账号,用户可以通过“注册”功能获得账号,注册页面效果如图4-1所示。当注册成功之后,会进入注册成功页面;如果注册信息不对,则显示注册失败。图4-1用户注册界面第4章注册、登录和注销当用户购物完成离开网站的时候,应该让用户
注销,关闭会话。在用户没有登录的时候,菜单栏目应该显示包含“登录”;当用户登录以后,菜单栏目显示包含“注销”。效果如图4-3、图4-4所示。图4-3用户没有登录时的菜单图4-4用户登录以后的菜单4.1开发步骤在J2的开发中,服务器端应用程序分为若干层
。每层在处理程序上都有一项明确的责任。不应该将它们混合,并且每层都要与其它层分开,各个层之间通过通信接口联系。如图4-5所示。Spring容器客户端浏览器数据库Web服务器(Tomcat)ActionServiceDAO核心控制器JSP视图JavaBea
ns图4-5J2的分层结构4.1开发步骤●层层完成连接数据库增删改等实现细节,例如语句怎么写、怎样把对象放入数据库等等。将底层数据访问操作和业务层逻辑分离开,对业务层提供面向对象的数据访问接口。而业务层调用接口实现各种业务方法,如验证用户密码是否正确。●业务层业务层位于上层的表示层和控制
层,依赖于下层的业务层的实现(),而下层业务层不应该依赖于上层的表示层和控制器的实现。业务层提供了处理应用程序的业务逻辑和业务校验,如验证用户登录系统的密码是否正确;提供了管理事务,允许与其它层相互作用的接口。层是面向功能的,一个功能模块比如说银行等级并完成一次存款,把请求给
层,层将这个功能分解成许多步骤调用底层的来实现这次存款。有时,会看到层和层的方法是类似的,是因为层的需求不是很复杂,不用再对层完成太多包装或者处理就可以直接调用的方法。●控制层控制层的控制器接受用户的输入并调用业务层的业务方法和表示层的组件去完成用户的请求。当应用单击页面中的提交
按钮来发送表单时,控制器接受请求并调用相应的业务层方法去处理请求,然后调用相应的视图来显示业务层返回的数据。4.1开发步骤中的控制器由类和类来实现,主要负责接受请求信息,根据配置文件的配置信息,把请求转发给适当的对象。如
果该对象不存在,会先创建这个对象,充当用户请求和业务逻辑处理之间的适配器,其功能是将请求与业务逻辑分开,根据用户请求调用相关的业务逻辑组件,类侧重控制应用程序的流程,而不是实现应用程序的逻辑。●服务器各种组件的生成都
是由容器来控制,被看作是中的一个,它可享受提供的所有服务(依赖注入、实例管理、事务管理等)。●视图层视图是用户看到并与之交互的界面,视图向用户显示相关的数据,并能接受用户的输入数据,但不能进行任何实际的业务处理。视图可以向业务层
查询业务状态,但不能改变业务层,视图还可以接受模型发出的数据更新事件,从而对用户界面进行同步更新。视图其实就是一组文件,在这些文件中没有业务逻辑,也没有业务层信息,只有标签,这些标签可以是标准的标签或客户端标签,如标签库中的标签。使用框架的最大好处是不仅在于
减少重复开发工作量,缩短开发时间,降低开发成本,同时,使程序设计更加合理,程序运行更加稳定等。基于这些原因,基本上现在开发中,都会选择某些合适的开发框架,从而达到快捷,高效的目的。4.1.1注册开发为5个步骤:步骤1步骤2步骤3步骤4步骤5具体步骤如下:步骤1层所涉及的类,接口如图4-6所示。
图4-6层主要类图4.1.1注册其中,接口中的()用于将一个对象保存到数据库中。类中的()具体实现了这个方法。是将对数据库进行的操作进行封装,这样,在中就可以直接使用。在这里使用了模式。这三个类和接口在工程中的位
置如图4-7所示。图4-7文件在项目中的位置4.1.1注册创建,代码如下:包名为;引入另一个包的类;定义用户的接口{保存用户注册的信息();}4.1.1注册创建,代码如下:包名为;引入需要的类;;对一些基本操作进行封装,在它的子类中可以直接使用
{;(){;}(){;}(){();;}}4.1.1注册创建,代码如下:包名;;引入需要的类;;;;;;;{保存用户的信息到数据库中(){();将对象保存到数据库中();();();();}4.1.1注册●步骤2层主要用于处理各种业务。主要的类和接口是:,,如图4-8所示。其中,是一个接口
,定义了两个方法,()方法用于将对象存储到数据库中。()方法用于验证用户输入的名称和密码是否正确。实现接口,通过类,实现了这两个方法。图4-8层的主要类4.1.1注册文件和在项目中的位置如图4-9所示。图4-9文件在项目中的位置4.1.1注册代码如下:包名;引入需要的类;{用户注册时,保存用户的信
息();用户登陆时,验证用户的信息();}代码如下:包名;引入需要的类;;;4.1.1注册{属性,层调用层完成相关操作;保存用户注册时的信息(){();}用户登录时,用于验证用户的信息(,){;}属性的方法()
{;}属性的方法(){;}}4.1.1注册●步骤3类含有是三个方法,如图4-10所示。()方法用于用户注册,()方法用于用户登录,()方法用于用户注销。这些方法的实现依赖于层,在属性中,有一个属性,它的类型是。图4-10类图4.1.1注册
文件在项目中的位置如图4-11所示。图4-11文件在项目中的位置4.1.1注册代码如下:文件中配置,在项目中的位置如图4-12所示。图4-12在项目中的位置<"2.0"""><><""/><"""">
<""""""><""><><><><>4.1.1注册注意在上面代码中,对应名为的动作,对应的类为,方法为该类的方法。但是,其实对应的类为。这里,主要是因为在后面将使用功能,所以,这里为起了一个别名:。●步骤4各种组件的生成都是由容器来控制。
的配置文件项目中的位置,如图4-13所示。图4-13在项目中的位置4.1.1注册代码如下:●步骤5层创建注册视图,注册成功视图。、文件所在的位置如图4-14所示。图4-14文件在工程中的位置4.1.1注册创建文件,代码如下:<";2312"%
><"s"""%><><><"""">用户名*:<""""/><><>密码*:<""""/><><>性别:<""""/><><>年龄:<""""/><><><"""注册"><><><><>创建注册成功页面文
件,代码如下:<";2312"%><"s"""%><><>您好!用户<s:""/>欢迎您注册成功<2><a"">登录<><>4.1.2登录开发为5个步骤:步骤1步骤2步骤3步骤4步骤5具体步骤如下:●步骤1层所设计的类和接口
如图4-6所示。其中,接口的()用于验证用户,类中的()实现了这个方法。根据用户输入的用户名和密码到数据库中查找相关用户。如果找到,返回记录;如果没有找到,返回空记录。这两个类和接口在工程中的位置如图4-5所示。代码如下:;包名;引入相关类{();用户注册时,保存用户信息();用
户登录时,验证用户信息}4.1.2登录代码如下:●步骤2这一层主要涉及到接口和类,如图4-8所示。在接口中定义了()方法,用于用户登录验证。在类类中具体实现了这个类。两个文件在工程中的位置如图4-9所示。创建文件,代码如下:;包名;引入相关类{();保存用户信息(
);验证用户信息}创建文件,代码如下:4.1.2登录●步骤3类()方法用于用户登录,如图4-10所示。方法的实现依赖于层,在属性中,有一个属性,它的类型是。类所在工程中的位置如图4-11所示。修改文件,增加()方法的实现,代码如下:●步骤4修改文件,容器,前面已经配置好
。<""""""><><""""><""><""/><><><""""><""><""/><><>4.1.2登录●步骤5创建文件,文件的位置如图4-14所示。<";2312"%><:""><:><"s"""%><><><>用户登录<
><><><"""""">用户名:<""""/><>密码:<""""/><><"""登录"><><><><>4.1.3注销开发为3个步骤:步骤1步骤2步骤3具体步骤如下:●步骤1类()方法用于用户登录,如图4-10所示。方法的实现依赖于层,在属性中,有一个
属性,它的类型是。类所在工程中的位置如图4-11所示。修改文件,添加()方法,用于注销,代码如下:(){用户注销()();("");;}配置文件,代码片段如下<""""""><""><><4.1.3注销●步骤2已经在前面章节配置好,代码片段如下:<""""""><"">
<""/><><><""""""><>…<""""><""><""/><><>…<""""><""><""/><><>4.1.3注销●步骤3用于存放网页的头部信息,如菜单等。菜单根据用户是否登录有不同的显示。文件的位置如图4-14所示。修改文件,代码片段如下:<a""
>首页<><s:""><a01"">登录<><:><s:><a"">注销<><:><a"">注册<><a"#">联系我们<><a"#">网站地图4.2知识点:模式数据源不同数据访问也不同。根据存储的类型(关系数据库,面向对象数据库,文件等等)和供应商实现不同,持久性存储(比如数据
库)的访问差别也很大。比如,在一个应用系统中使用对数据库进行连接和数据访问,这些与语句分散在系统各个程序文件中,当需要其他(如)时,就面临重写数据库连接和访问数据的模块。一个软件模块(类,函数,代码块等)在扩展性方面应该
是开放的,而在更改性方面应该是封闭的,这就是开闭原则。要实现这个原则,在软件面向对象设计时要精良考虑接口封装机制,抽象机制和多态技术。这里的关键就是将这个软件模块的功能部分和不同的实现细节清晰地分开来。在数据库访问对象中,应该运用这个原则。在数据库编程的
时候,经常遇到这种情况,一个用户的数据访问对象,里面的操作方法有,,,等,对不同数据库其实现的细节是不相同的。因此,不太可能针对每种类型的数据库做一个通用的对象来实现这些操作。但是,可以定义一个用户数据访问对象的接口,提供,,,等抽象方法。不同类型的数据库的用户访问
对象实现这个接口就可以了。如图4-15所示。4.2知识点:模式MySqlImpSQLServerImpOracleMySqlImpClientIUserDAOinsert()delete()update()select()图4-154.3知识点
::接口➢4.3.1绑定参数➢1.使用“?”指定参数➢通过接口可以先设定查询参数,然后通过()等方法,将指定的参数值填入,而不用每次都编写完整的。来看下面的例子➢("s>??")➢(0,25);设置>?中的问号为整型25➢(1,"");设置?中的问号
为字符串""➢2.使用“:”后跟变量的方法设置参数➢可以使用命名参数来取代使用“?”设置参数的方法,这可以不用依据特定的顺序来设定参数值,比如上面的代码可以写为:➢("s>");➢("",25);设置:号后
的变量值➢("","");设置:号后的变量值➢使用命名参数时,在建立时先使用“:”后跟着参数名,然后就可以在()方法中直接指定参数名来设定参数值。命名参数的好处如下:➢●命名参数不依赖于它们在查询字符串中出现的顺序➢●在同一个查询中可以使用多次➢●
可读性好4.3.1绑定参数3.()方法()方法的全称是(,实例,实例类型)。这个方法可以绑定任意类型的参数。在实际应用中,可以根据类实例推断出绝大部分对应的映射类型,因此()中的第三个参数也可以不要。例子如下:"u??";();(0);(1,);4.3.2()方法➢4
.3.2()方法➢的()方法用于取得一个类的示例,此示例中包括的可能是一个集合,也可能是数组集合。➢最常见的是使用()取得一组符合条件实例对象,如下程序所示:➢("s>20";➢();➢(0<()){➢()(i);➢(
());➢}4.4知识点::接口在中,数据查询与检索机制很完善。相对其他实现而言,提供了灵活多样的查询机制。其中包括:●(条件查询)●()●传统的语句采用的是结构化的查询方法,而这种方法对于查询以对象形式存在的数据却无能为力。为用户提供了一种类似于的语言,查询语言()。和不同的
是,是一种面向对象的查询语言,它可以查询以对象形式存在的数据。在中不提倡使用。虽然提供了更加符合面向对象编程模式的查询封装模式,但提供了更加强大的功能。在官方开发手册中,也将作为推荐的查询方式。这里,介绍检索语言。4.4.1实体查询:有关实体查询技术,如下面的例子:"";();();上面的"",将
取出表的所有对应记录,对应为"…"。也可以在中采用全路径名,如:””子句本身大小写无关,但是其中出现的类名和属性名必须注意大小写区分。如果需要取出名为""的用户的记录,可以通过语句加以限定:”‘’”;()
;();这里引入两个子句“”和“”,子句为类名创建了一个别名,而子句指定了限定条件。其中子句可忽略,如:”’’”子句中,可以通过比较操作符指定甄选条件,如:=,<>,<,>,>=,<,,等。几个简单的示例:>202030(18,28)‘’与相同,通过、等逻辑连接
符组合各个逻辑表达式:(>20)(‘’)4.4.2实体的更新和删除在2之前版本中,仅用于数据查询。而在3中,具备了更加强大的功能。实体更新与删除就是其中的主要特性之一。和子句是3中新引入的子句。通过、子句,数据的删除与更新操作可以以更加灵活的方式实现。在2中,完成用户年龄属
性的更新,必须通过以下代码实现:加载1的用户记录()((1));((18));通过方法保存();以上代码完成了1的用户数据的更新。如果需要将库表中所有的用户的年龄设置为18,该如何操作呢?别无他法,只能首先利用“”查询
出所有的实体,设置年龄属性后再逐一保存。3提供了更加灵活边界的实现方式():"181";();();4.4.2实体的更新和删除这段代码完成与上例同样的功能。对于单个对象的更新也许代码量并没有减少太多,但如果对于批量更新操作,其便捷性及性能的提高就相当可观。以下代码将所有
用户的年龄属性更新为18:"18";();();3子句的使用同样非常简单。以下代码删除了所有年龄大于18的用户记录:">18";();();4.5知识点:2:➢4.5.1概述➢2控制器最重要的组成部分就是
,它是框架的控制中心,是连接模型和视图的桥梁和纽带。➢接受来自视图层的请求,并接受请求参数,同时负责调用模型层方法来完成业务逻辑的处理,最后控制程序的流程,选择一个合适的视图将结果显示给客户。4.5.2的定义2中的只需要在一个普通的类中定义一个方法,如:{(){“”;}}:的类名,习
惯上以结尾,更容易阅读和理解:用于接受请求的方法,名称可以自定义,默认情况下,会调用()方法。该方法不能带任何参数,且必须返回字符串类型。:返回值,类型必须是字符串,2会根据返回值控制程序流程。一个简单的例子
。定义一个,访问该的时候在控制台打印“你好”。{(){(“你好”);;}}在配置文件中,将刚才创建的注册到这里。<""""""><>4.5.2的定义:自定义名称,访问时用到,如:。的类名:访问该时,调用()方法。
因为()方法的返回值是,表示不跳转到任何地方。如果返回一个字符串,则必须配置<>的子标签<>,通过该标签映射一个跳转路径,如:<””><>,表示如果方法的返回值为,则跳转到文件。<>是可选的,在定义的响应方法时,如果将方法名称定义为,则<>可省略。如:{(){(“你好”);;}}配置修改如
下:<""""><>4.5.3通过获取请求参数通过的()或()方法固然可以得到从客户端传送过来的请求参数,但是这样做很麻烦,而且增加了应用程序的耦合度,增强了对容器的依赖。2在中改进了获取请求参数的方式,
自动获取请求参数。2获取请求参数的名称,拼成该参数的方法与方法,调用方法实现属性的存取操作。比如,从客户端传送一个名叫的参数,则会拼成和方法名,通过反射调用()方法进行赋值,程序员通过()方法就能取到值了。存取值的代码写在中就可以。上面的操作是交给实现的。以下是一个获取请求参数的例
子。本示例用于演示用户登陆的过程。用户输入用户名和密码,如果分别为和,则显示登陆成功的信息,否则显示登陆失败的信息。…<"""">用户名:<""><>密码:<""""><><"""登录"><>4.5.3通过获取请求参数在表单中,表
单域的属性值必须和中定义的属性名称一致,才能正确被接收,如果读者懂得反射原理,更容易理解。作为控制器则负责接收视图层发送过来的用户名和密码,并通过()方法调用业务方法,根据执行结果控制程序流程:如果登陆成功,则跳转到,否则跳转到。4.5.3通过获取请求参数{;;(){;}(){=;}(
){;}(){=;}(){调用业务组件,如果成功,返回“”;否则,返回“”。(….){“”;}{“”;}}}4.5.3通过获取请求参数提交表单后,请求提交给是在文件中预先配置好的,可以自定义,但最好用一个比较有意义
的名字,增强程序的易读性。的配置<""""><""><><""><><>也可以将定义在中的属性封装成一个实体类,更利于控制器与属性的分离。将属性定义在中的做法,违背了控制器的初衷。2的开发者们提供了一种更好的处理方式,类似
于1中的,但是比更加灵活和解耦。4.5.3通过获取请求参数将和封装到类中,源代码如下:{;;(){;}(){=;}(){;}(){=;}}4.5.3通过获取请求参数在类中,保存一个的引用就行了。该类的配置不需要改变。(修
改版){;(){;}(){=;}(){同上}}4.5.3通过获取请求参数最后,修改中的表单域的属性值,基本格式为:引用名.属性名。在上例中,引用名是指定义在类中的,属性名是指定义在为中的和。为了将用户名传递到类的属性中保存,修改
<"">为<"">即可,所以最后的代码如下:的修改版,代码如下:<><"""">用户名:<""><>密码:<""""><><"""登录"><><>4.5.4在2中,与容器已经做到完全解耦,不再继承某个类或实现某个接口,但是,在
特殊情况下,为了降低编程的工作难度,充分利用2提供的功能,定义时会继承类,该类位于2提供的包2中。类为提供了一些默认实现,主要包括:●预定义常量●从资源文件中读取文本资源●接收验证错误信息●验证的默认实现下面是类所实现的接口:,,,
,{}接口同样位于2包,定义了一些常量和一个()方法。{="";="";="";="";="";();}4.5.4接口中一共定义了五个常量,每个常量都有特定的意义,这些常量被()方法返回,并最终被处理,<>
的子标签<>的属性可以是这些常量中的任何一个。是属性的缺省值。其中,表示请求处理成功,表示请求处理失败,表示请求处理完成后不跳转到任何页面,表示输入时如果验证失败应该跳转到什么地方,表示登陆失败后跳转的目标。接口2的实现类2.定义了三个集合成员,这些
集合用于存储错误或消息。的众多方法主要完成对这些成员的存储操作和判断集合中是否有元素的操作,仅仅实现对这些方法的简单调用。4.6知识点:2:表达式➢4.6.12的表达式➢是(对象图导航语言)的缩写,是一个开源项目。是一种功能强大的(,表达式语言
),可以通过简单的表达式来访问对象中的属性。➢先在项目中得到应用,也是2框架视图默认的表达式语言,可以说,表达式是2框架的特点之一。➢标准的会设定一个根对象(对象)。假设使用标准表达式来求值(不是2),如果上下文有两个对象:对象,对象。同时对象被设置为根对象()。则利用下面
的表达式求值➢#返回()➢返回()➢返回(),因为为根对象➢使用非常简单,如果要访问的对象不是根对象,如示例中的对象,则需要使用命名空间,用“#”来表示,如“”;如果访问一个根对象,则不用指定命名空间,可以直接访问根对象的属性。4.6.12的表达式在2框架中,值栈()就是的根对象,
假设值栈中存在两个对象实例:和,这两个对象实例都有一个属性,有一个属性,有一个属性,假设在值栈的顶部,在后面,如图4-16所示。下面的代码片段能更好地理解表达式。值栈AnimalnamespeciesMannamesalaryTop图4-16一个包含了和的值栈4.6.12的表达式调用()调用()
调用(),因为位于值栈的顶部最后一行实例代码中,返回的是。()返回值,即返回了的属性,因为是值栈的顶部元素,将从顶部元素搜索,所以会返回的属性值。如果要获得的值,则需要如下代码:2允许在值栈中使用索引,实例代码如下
所示:[0]调用()[1]调用()2中的是,如图4-17所示4.6.12的表达式parametersapplicationContextMapsession值找(root)requestattr图4-172的结构示意图
4.6.12的表达式由于值栈是2中的根对象,如果用户需要访问值栈中的对象,则可以通过如下代码访问值栈中的属性:${}获得值栈中的属性如果访问其他中的对象,由于不是根对象,在访问时,需要加#前缀●对象,用于访问,例如或者[""],相当于调用的("");●对象,用来访问,例如或
者[""],相当于调用("")。●对象用来访问属性的,例如或者[""],相当于调用("")。4.6.2的集合操作如果需要一个集合元素的时候(例如对象或者对象),可以使用中同集合相关的表达式。可以使用如下代码直接生成一个对象:{e1,e2,e3…}该表达式中,直接生成了一个对象,该对轩昂中
包含3个元素:e1,e2和e3。如果需要更多的元素,可以按照这样的格式定义多个元素,多个元素之间使用逗号隔开。如下代码可以直接生成一个对象#{:1,2:2,…}类型的集合对对象,使用格式定义,每个元素使用冒
号表示,多个元素之间使用逗号隔开。对于集合类型,表达式可以使用和两个元素符号。其中,表达式用来判断某个元素是否在指定的集合对象中;判断某个元素是否不在指定的集合对象中,代码如下所示:<s:"''{'',''}">…<:>4.6.2的集合操
作除了和之外,还允许使用某个规则获得集合对象的子集,常用的有以下3个相关操作符●?获得所有符合逻辑的元素●^获得符合逻辑的第一个元素●$获得符合逻辑的最后一个元素例如代码:.{''}该代码可以获得的所有性别为的集合。
4.7知识点:2:标签库➢4.7.1数据标签➢●<>标签➢得到””属性。如下所示,在中为。属性赋值,在网页中从中读取值➢<""/>➢<>标签➢标签用于对值栈中的表达式进行求值,并将结果赋给特定作用域中的某个变量名。这对于在中使用临时
变量是相当有作用的,而使用临时变量会另代码更容易阅读,并会执行稍微快一点。➢下面是一个简单例子,展示了标签访问存储于中的对象的多个字段:➢<"['']"/>➢<"['']"/>➢<"['']"/>➢每次都要重复使用['']不仅烦人还容易引发错误。更
好的做法是定义一个临时变量,让这个变量指向对象。使用标签使得代码易于阅读:➢<"""[‘']"/>➢<""/>➢<""/>➢<""/>4.7.1数据标签由于标签可以将表达式重构得更精简,更易于管理。因而,整个页面都变得更简单了。●<>标签基本的2标签提供了一定的数据处理功
能,而有时候,需要更加复杂的功能,标签可以创建简单的,并将其压入栈值中,在标签的其实与结束标记之间,还可以任意地把赋值给某个变量名,一边让它在中能够访问。来看一个例子:用于跟踪计数。<""""><"""100"><><""><><>在这个例子中,首先被创建,接着以100
为参数调用()方法,然后使用标签对其循环取值,而每次循环得到的值将被打印出来。4.7.1数据标签●<>标签有时候,标签还不足以实现复杂的或者可重用的视图。在中执行并且访问相应的数据,而不是将存入中。利用标签,可以
通过简单的方式创建简单的可重用组件,同时不需要在页面增加代码片段。比如在应用系统中,页面左边是一个书的种类的菜单,由于需要在多个页面进行显示,所以创建一个独立获取数据的供各个页面使用。<""""><""><><>设置为。如果没有被设定,在默认情况下,它的值为,即使执行了,也不会
生成任何视图。4.7.2控制标签●<><>标签执行基本的条件流转。如在本章的例子中,判断用户是否登录,如果登录,页面显示”注销”;反之,页面显示”登录”<""><a01"">登录<><><><a"">注销<><>●<>标签标签可以循环遍历任何对象集合,包括,,,及
。同时,可以在中定义一个变量,用于确定与当前循环状态相关的基本信息,例如遍历到了奇数行还是偶数行。下面是一个例子,用于循环遍历由的返回的条目集合:<s:""><s:""/>,<s:"””/><:>表达是调用了()方法,执行后返回一个对象的。随着循环遍历的
进行,在标签内部的内容被调用的时候,每个遍历到的对象都会被暂时压入值栈。在标签内部的内容执行完毕之后,这个对象就会出栈。由于对象被压入到栈中,所以标签能够通过使用和这两个表达式分别()和()方法。习题1.完成用户注册、登录和注销
功能。2.如果需求规定:用户输入的名字和密码不能为空,需要做什么处理?3.在本示例中,只完成了将用户保存到数据库中,没有考虑如果已经用户重名的情况。完成如果用户重名,则注册失败,重新回到注册页面。谢谢23.7.1715:01:1015:0
115:0123.7.1723.7.1715:0115:0123.7.1715:02023年7月17日星期一3时1分10秒