Ajax前后端交互过程与低级分发器的实现

来源:互联网 发布:js最新正则表达式大全 编辑:程序博客网 时间:2024/05/22 13:59

Ajax工作流程:

(1)用户在页面上执行了某个操作,例如鼠标移动等,会根据用户的操作,页面发出相应的DHTML事件

(2)调用该DHTML事件的客户端JavaScript事件函数,其中初始化一个用以向服务器发送异步请求的XMLHttpRequest对象,同时指定一个回调函数(success or error),当服务器响应返回时,自动调用该回调函数

(3)服务器收到XMLHttpRequest对象的请求后,进行一系列处理,后台程序运行完毕后,返回客户端所需要的数据

(4)数据处理完毕后,执行JavaScript回调函数,对页面进行更新和修正


下面进行一个简单的前端后台使用Ajax的过程:

Ajax功能需求与分析(借鉴同学):

--MEC前、后端思想--

主要面对的应用:
    一些页面不固定,需要经常局部更新、替换的站点。
    例如:购物网站,如淘宝、京东。新闻网等具有时效性的网页,数据变化很快但是样式和结构固定,用户不同两次访问该页面,页面的数据肯定不相同。其实大多数可能在未来更改的页面都需要。

    方案:使用Html模板的思想构造页面。对于一个页面的一些组件,如轮播、模态框、输入框组、导航栏等等做成Html模板。对于模板,只包含必要的结构,而模板中的数据无需填充。而在需要的时候,服务器提供数据。由一系列的手段将数据注入到Html模板中(这需要解析Html模板和服务器提供的数据,并且将数据和模板缺省的信息一一对应,并注入),并且发送到客户端。

    详细过程:
    对于一次用户的访问,即在浏览器地址栏输入url。服务器并非直接向客户端发送渲染后的页面数据,如html、css、js文件等,而仅仅是页面的框架(详细文件信息:css文件包括页面框架的基本样式和未来页面数据填充后可能使用的样式;js文件包括整个页面行为控制,如基本的数据model、用于视图的view、用于页面控制的action等,因为页面的组件是以模板注入的,js文件中应该包含所有的Html模板)。(原始的方式是服务器直接向客户端传输页面需求的所有数据,并且渲染页面,但是这样的页面将是固定的,如果需要下次用户访问更新页面的部分数据,就需要服务器发送新的页面,而新页面仅仅是部分数据不同,若不使用模板就得费时的重新写页面,是很不人性化的)这种解决方案是在用户输入url后,服务器发送页面数据,但是页面的数据并非是最终的数据。仅仅是页面的基本框架数据。此时页面实际上仅仅是框架,是一个站点的基本结构,如淘宝网页面的基本结构,是不包含页面的具体数据的。此时,就需要在js文件中以AJAX方式(必须是AJAX请求方式,因为页面框架无需改变,只需要获取页面数据)再次请求服务器。在本次的AJAX请求中,请求内容是页面的数据,因此要附加对应的数据信息。这里的页面数据,是以Xml文件方式存放于服务器端的(不使用数据库的原因:对于Html页面的数据,往往是层次结构的,而数据库是不好描述这种层次结构的,因而以适合描述层次结构的Xml存放)。因此附加的信息是和该页面对应的Xml文件在服务器的Path。对于服务器端,接收到AJAX请求并且得到附加信息后,需要进找到对应的Xml文件并且解析成JSON字符串(这是为了数据到前端的方便处理)。接着服务器将以json方式将数据发送到客户端。客户端以异步的方式得到数据后并且进行一系列处理(将JSON数据解析,解析成和Html模板对应的数据,并且将数据注入到Html中),然后由浏览器渲染页面。此时的页面就是最终的页面。这样页面更改起来方便。假如一个页面1小时更新一次数据,服务器端就仅仅修改Xml文件的数据,而无需重复准备多个页面。

——————————————————————————————————————————————

**Html模板:
    Html模板应该是一些固定的组件,如模态框、导航栏、输入框组等等的结构,并且以字符串形式存在。
并且需要以一定的规则限制模板,例如需要更改的数据以变量的方式描述,对于重复出现的标签以循环的方式描述。

前端模板请参考mecBase.js

**Html模板需求的数据:
    和模板中的变量对应的数据,以JS对象形式存在。值都是字符串。

**服务器端Xml的数据描述:
    以一套自定义标签表示Html模板的数据。

——————————————————————————————————————————————
Ajax例子(前端与后台共同分析):

前端:(这里贴出的js文件中的HTML模板化填充框架,即mecBase.js,暂不开源)

先贴出xml文件:


后台解析好xml文件后,解析后的内容如下

在前端获取到后台解析好的数据之后,用js进行处理,处理结果如下:

完成注入后,页面的显示如图:

最终就实现了只需要修改xml文件,就可以让前端内容进行更改,而不用更改源代码

在这里,贴出html的loadding.js文件以及事件响应viewAction中的ajax请求,在访问网站时,运行loadding.js后,前端发出ajax请求,通过发送请求路径,然后后台通过上面的方法送回网页数据并显示。(html文件中,loadding.js在view.js之前加载)


后台:

在前端的的loadding.js发出ajax请求后,后台通过web.xml的配置进行跳转,先贴出web.xml文件

可以看出,在loadding.js中,url对应到后台的com.mec.video.servlet.IndexViewData类


在这个IndexViewData类中,我们对前端要求访问的xml文件进行解析,然后返回json字符串,前端获取后,通过loadding.js中的方法解析为网页数据,在这里,贴出其doGet方法


前端页面显示后,进行登陆操作,而登陆操作,就会牵扯到分发器(模拟Struts)

模拟分发器基本思路(模拟struts):

观察上面的web.xml在Filter中,对登陆的路径进行Filter的过滤操作,这个过滤器起名为Dispatcher。如果账号密码验证成功,进行个人页面信息的获取并进行页面的跳转至UserLoginAction,或进行其他响应跳转至不同的后台java类。如果账号密码错误,则直接返回ajax请求,在登陆框上显示账号密码错误。就拿UserLoginAction来进行说明,在这个类中,通过service以及dao的MVC模式,进行到最后的数据库查询。那么在Dispatcher中,我们只能截获账号和密码,如果能塞在UserLoginAction中去呢?核心还是xml的解析,对所有action,我们创建一个xml


在这个xml中,我们在Filter中形成一个map,将name和calss作为键值放进去,而所有的action都必须实现IAction类,IAction要求实现excute()方法。map的结构为private static final Map<String, IAction> actionMap;实现了接口的类,以接口方式放入map,相应的action,从view.js中的ajax请求中得到,然后进行解析



在UserLoginAction中,我们处理好账号密码匹配情况与错误请求,最后返回一个值和个人账号信息或响应的json字符串,并且通过实现接口,得到Filter中的session与cookie,先讨论返回值,首先贴出UserLoginAction的代码:

在Filter中,对多种情况进行处理即可,发出跳转命令或者返回ajax请求,而我们需要在Dispatcher进行反射机制,将它获取到的id和password注入至UserLoginAction

再讨论UserLoginAction对Dispatcher的操作,首先实现接口,在这里贴出两个类

ActionSession实现了Dispatcher中对session的方法,并通过接口,实现了Dispatcher对session的操作,cookie同理。