Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5119572
  • 博文数量: 921
  • 博客积分: 16037
  • 博客等级: 上将
  • 技术积分: 8469
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 02:08
文章分类

全部博文(921)

文章存档

2020年(1)

2019年(3)

2018年(3)

2017年(6)

2016年(47)

2015年(72)

2014年(25)

2013年(72)

2012年(125)

2011年(182)

2010年(42)

2009年(14)

2008年(85)

2007年(89)

2006年(155)

分类: Python/Ruby

2012-10-24 10:20:27

在每个Web服务中,页面的路由请求是非常重要一个方面。主要有两个原因:一是提供用户友好的URL,二是通过服务控制获取服务内容,比如Struts2中的struts.xml,就是为了这而产生的。在Erlang-Web中,是利用E_dispatcher来实现的

在Erlang-Web中,为了实现Url的映射(View到Control的映射),我们必须在dispatch.conf配置文件作配置(dispatch.conf文件在config这个文件夹内)。dispatch.conf配置文件在服务启动时读取,所以如果Web服务启动后,这个配置文件作了改动,我们必须重新加载,除了重新启动Web服务外,还有一个办法可以实现,就是在erlang shell中输入下面的命令实现:

  1. e_dispatcher:reinstall().

分发类型(Types of dispatching)

Erlang-Web中主要有两个路由分发类型:静态分发(static)和动态分发(dynamic)。

静态分发是专门为了访问那些不需要经过服务处理而生成请求页面的静态内容,如CSS、Images以及html页面。

动态分发就是涉及到在控制器中处理请求,然后生成内容返回用户请求页面。用户在浏览器中输入的Url映射到控制器中的相应函数,并且调用这个函数。所以利用动态分发,我们可以用来操作数据库、进行用户的输入验证、控制访问等。

 

分发流程控制(Control flow)

Erlang-Web 在收到客户端的用户请求后,服务端必须以某方式来处理它。首先就是分发管理器判断在所有静态理由中是否有根请求的URL相匹配,如果匹配,一开始就会在Web项目的templates目录中查找对应的目标文件,如果在templates目录中没有找到,则会去docroot目录中查找。在其它情况下,当用户请求的是一个动态路由时,分发管理器将会将请求传递到目标控制器对应的函数,我们可以利用下图来更直观的说明下这个原来:


dispatch.conf

dispatch.conf文件在config目录中,这个文件就是用来配置路由转发,同时也是Web应用中最重要的文件。该文件中的内容是以Erlang中的元组来存储路由转发条件的,也就是说一个路由转发,就是一个Erlang元组。路由转发是通过每个元组中的配置的正则表达式来匹配的,如果找到了对应的路由,则相应的被出路,这里要说明的是,如果有多个路由符合条件,仅仅是最先找到的第一个有效。

在dispatch.conf中,主要用到的路由规则配置有以下两种:

1)、{static, Regexp, File}

静态请求直接到指定的File,其中Regexp是一个正则表达式。在Web应用中File可以放在templates目录,也可以放在docroot目录。为了能够使服务快速的处理静态请求,我们可以设置File为一个enoent原子,这样一来服务器在查找File时就直接去docroot查找。

 

2)、{dynamic, Regexp, {Module, Function}}

在动态路由中,如果Regexp为真,则Module下的Function将会被请求

 

命名子模式(Named subpatterns)

命名子模式就是用于从用户输入的字符中提取一些有用的信息,利用正则表达式,我们可以在Url中指定需要的参数,并且在控制器中获取它。此外,命名子模式也可以让我们做一些简单的语法验证。

命名子模式的配置跟动态路由规则有点相同,但是在正则表达式上需要做一点点的修改,如果我们要绑定输入字符串的一部分的名字,我们
应使用下面的语法:

"HeadOfRegexp(?RegexpPart)TailOfRegexp"

 

因此,当正则表达式匹配请求的URL时,将提取其中指定命名的一部分并且标记它。对提取的值列表将被传递给dataflow列表中的第一个函数。如果我们不使用命名子模式的机制,我们将得到有空列表,通过命名子模式我们将得到下面这样的列表:

[{name_of_the_pattern, Value} | ...]

 

下面我们拿一个例子来说明,我们在浏览器中打开一个博客,并且需要输入/show/post/Post no这样的地址来获取谋篇博客,那么我们可以利用命名子模式来这样处理它:

{dynamic, "^/blog/post/(?[0-9]+)$", {blog, display_post}}.

 

当在浏览器中输入"/blog/post/23"时,则可以用正则表达式”ˆ/blog/post/[0-9]+$”来描述,并且通过命名子模式来提取相应的数据到一个列表中,最后的结果将会是这样:

[{post_no, "23"}]

 

这样一来,这个列表就会传递给dataflow 列表中的第一个函数了。我们还可以在命名子模式中设置多个正则表达式,例如:

{dynamic, "^/blog/post/(?[0-9]+)/comment/(?.+)$}.


对应的Url为"”/blog/post/5/comment/first comment",则最终获取的结果列表为:

[{post_no, "5"}, {comment_title, "first_comment"}]

 

在文章的开头我们说过,路由分发的好处就是提供一个友好的url,并且映射到控制器。但是有时候我们的服务提供了非常简单的API,我们并不需要路由分发来管理Url。此外,利用正则表达式来匹配路由规则也会影响到效率, 为了提高效率,我们也可以希望使用丑陋的URL,而不是多个正则表达式匹配。如果我们不是用路由分发,而直接使用Url地址的话,我们必须在url中加上app前缀,意思就是像下面的这样:

 

这样,请求的路径就被"/"分隔开来,并且请求时Module:Function将会被调用。

文章来自:http://blog.csdn.net/minyskirt/article/details/5054150

阅读(1833) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~