中英文对照 介绍Play Framework 框架 路由(Route)

lyuehh 发布于 2010/07/11 17:37
阅读 1K+
收藏 4

路由

h1. HTTP routing

路由组件负责将HTTP请求交给对应的action处理(一个控制器的静态公共方法)

The router is the component in charge of translating incoming HTTP Requests into action calls (a static, public method of a Controller).

一个HTTP请求在MVC框架里被当做一个事件看待。事件包含2个方面的信息

  请求的路径(例如/clients/1524,/photos/list),包含查询字符串(参数字符串)

  HTTP方法(GET,POST,PUT,DELETE)

An HTTP request is seen as an event by the MVC framework. The event contains two major pieces of information:

* The Request path (such as /clients/1542, /photos/list), including the query string.

* The HTTP method (GET, POST, PUT, DELETE)

关于REST

h2. <a>About REST</a>

表述性状态转移(REST)是一种类似互联网的分布式超媒体软件架构风格,

Representational state transfer (REST) is a style of software architecture for distributed hypermedia systems such as the World Wide Web.

REST的几个关键性地方设计准则:

应用功能分散在资源中

每个资源使用一个唯一的URI来寻址

所有资源在客户端和资源之间使用一个统一的接口来转移状态

REST states a few key design principles:

* Application functionality is divided into resources

* Every resource is uniquely addressable using an URI

* All resources share a uniform interface for the transfer of state between client and resource. 

如果你使用过HTTP,这些接口定义了一些可用的HTTP方法。

这些协议用于访问资源的状态:

*客户端-服务端

*无状态

*缓存

*分层

If you’re using HTTP, these interfaces are defined by the set of available HTTP methods. The protocol used to access the resource state is:

* Client-server

* Stateless

* Cacheable

* Layered

如果一个应用遵循了REST的主要设计准则,那么这个应用就是REST风格的。

Play框架使构建REST风格的应用变得更容易:

*Play的路由解释URI和HTTP方法,将一个请求匹配给一个Java调用。基于正则表达式的URI模式匹配给你更过的灵活性。

*协议时无状态的,意味着你不能在2次成功的请求之间在服务器上保存任何状态。

*Play把HTTP当做关键特性,这样框架可以让你接触到HTTP的所有信息。

If an application follows the main REST design principles, the application is RESTFul. The Play framework makes it easy to build RESTFul applications:

* The Play router interprets both URI and HTTP methods to route a request to a Java call. Regular expressions-based URI patterns give you even more flexibility. 

* The protocol is stateless. This means you can’t save any state on the server between two successive requests.

* Play considers HTTP as a key feature, thus the framework gives you full access to HTTP information.

Route文件语法

h2. <a name="syntax">The routes file syntax</a>

conf/toutes文件是Router使用的配置文件。该文件显示了应用所需的所有route。

每一个route由HTTP方法和UTI模式匹配和一个Java调用关联。

The **conf/routes** file is the configuration file used by the Router. This file lists all the routes needed by the application. Each route consists of an HTTP method + URI pattern associated with a Java call.

让我们看一下,一个的route的定义就像这样。

Let’s see what a route definition looks like:

bc. GET    /clients/{id}             Clients.show           

每一个route以一个HTTP方法开始,后面跟着URI模式,最后的是Java调用定义。

Each route starts with the HTTP method, followed by the URI pattern. The last element of a route is the Java call definition.

我们可以给route文件增加注释,以#开头

You can add a comment to the route file, with the **"#"** character.

bc. # Display a client

GET    /clients/{id}             Clients.show      

     

HTTP方法

h3. The HTTP method

HTTP方法可以是任何HTTP所支持的有效的方法。GET,POST,PUT,DELETE,HEAD

The HTTP method can be any one of the any valid methods supported by HTTP:

* **GET**

* **POST**

* **PUT**

* **DELETE**

* **HEAD**

如果使用*作为方法,则这个route可以和任何请求的方法相匹配

If you specify * as method, this route will match the HTTP Request for any method.

bc. *   /clients/{id}             Clients.show           

这些route可以独立的接受请求

This route will accept independently:

bc. GET /clients/1541

PUT /clients/1212

URI的模式

h3. The URI Pattern

URI模式定义了route(路由)中有一部分可以成为动态的,动态的部分必须包含在"{}" 中

The URI pattern defines the request path needed by the route Some parts of the route can be dynamic. Any dynamic part must be specified within braces {…}.

例如/clients/all可以匹配/clients/all,但是/clients/{id}可以独立的匹配/clients/12121,或者/clients/todo

bc. /clients/all

exactly matches:

bc. /clients/all

but…

bc. /clients/{id}

independently matches:

bc. /clients/12121

/clients/toto

一个URI模式可以不止一个动态的部分

A URI pattern may have more than one dynamic part:

例如 /clients/{id}/accounts/{accountId}

bc. /clients/{id}/accounts/{accountId}

动态的部分的默认匹配策略是由正则表达式/[^/]+/定义的,你可以为动态部分定义你自己的匹配正则表达式。

The default matching strategy for a dynamic part is defined by the regular expression **/[^/]+/**. You can define your own regular expression for a dynamic part.

下面这个正则表达式只能接受id为数字的uri请求。

This regex will only accept numerical values as id:

bc. /clients/{<[0-9]+>id}

下面这个只接受id是一个包含4位到10位小写字母的单词的请求。

This one will ensure id is a word containing between 4 and 10 lower case characters only:

bc. /clients/{<[a-z]{4,10}>id}

任何合法的正则表达式都可以在这里使用。

Any valid regular expression can be used here.

笔记:

p(note). **Note**

 

动态部分是被命名的,控制器可以在HTTP参数map中取得动态部分的值。

Dynamic parts are named. The Controller can later retrieve the dynamic parts from the HTTP params map.

默认Play认为“/”是很重要的,例如下面这个route,

GET /clients        Client.index

 会匹配/clients但是不会匹配/clients/,你可以通过在“/”后加上一个问号,告诉Play 你想让那个route匹配到后面的"/",例如

GET     /clients/?       Clients.index

By default Play considers the trailing URL slash as important. For example, this route:

bc. GET     /clients         Clients.index

will match the */clients* URL but not */clients/*. You can tell Play that you want to match both URL adding a question mark after the trailing slash. For example:

bc. GET     /clients/?       Clients.index

笔记:

URI模式不能有任何可选的部分,除了那个"/" (不理解)

p(note). The URI pattern cannot have any optional part except for that trailing slash.

定义Java调用

h3. Java call definition

Route的最后一部分是Java调用定义,这部分是由一个action方法的全名定义的,并且这个action必须是一个控制器类中的静态的公共方法,控制器类必须定义在包controllers中且必须是play.mvc.Controller的子类。

The last part of a route definition is the Java call. This part is defined by the fully-qualified name of an action method. The action method must be a static, public method of a Controller class. A Controller class must be defined in the **controllers** package and must be a subclass of **play.mvc.Controller**.

你可以在控制器类之前增加一个Java包如果它不是直接定义在controllers包中,包controllers本身是默认包含的,所以你不需要指定它。

例如:

GET    /admin             admin.Dashboard.index         

You can add a Java package before the Controller class name if it isn’t defined directly under the controllers package. The **controllers** package itself is implicit, so you don’t need to specify it. 

bc. GET    /admin             admin.Dashboard.index           

指定静态参数

h3. Assign static args

在某些情况下,你想重用一个已存在的action,但是想指定一个基于特殊的参数的值的特殊route。

让我们在例子中看一下。

In some cases, you want to reuse an existing action but define a more specific route based on the values of some of the arguments.

Let’s see how in this example:

bc. public static void page(String id) {

    Page page = Page.findById(id);

    render(page);

}

使用对应的route

GET    /pages/{id}         Application.page

With the corresponding route:

bc. GET    /pages/{id}         Application.page

现在,我想定义一个URL,其中id指定为'home',我可以使用静态参数定义另外一个route

Now, I want to define a URL alias for the page with ID ‘home’. I can define another route with a static argument:

bc. GET    /home           Application.page(id:'home')

GET    /pages/{id}         Application.page

page ID为'home'时,第一个route和第二个route是等价的,但是,它的优先级要高一些,当你使用ID 'home' 调用Application.page时,它是默认被调用的。

The first route is equivalent to the second one when the page ID is ‘home’. However, since it has higher priority, this route will be used as the default for the call to Application.page with ID ‘home’.

路由优先级

h2. <a name="priority">Routes priority</a>

很多路由可以匹配相同的请求,如果有冲突的话,将使用第一个定义的(写在前面的)。

Many routes can match the same request. If there is any conflict, the first route (following the declaration order) is used.

例如

For example:

bc. GET    /clients/all          Clients.listAll

GET    /clients/{id}         Clients.show

像这样定义route,URL /client/all 会被第一个route拦截,并调用 Clients.listAll。(尽管第二个路由也和它匹配)

With these definitions, the URI:

bc. /client/all

will be intercepted by the first route and will call Clients.listAll. (even if the second route matched the request too).

对静态资源的处理

h2. <a name="static">Serving static resources</a>

使用特殊的action 'staticDir',可以开放每一个你想使之成为静态资源容器的文件夹。

Use the special action **staticDir**, to point to each folder you wish to publish as a static resources container.

例如:

For example:

bc. GET    /public/               staticDir:public

当你的请求中含有/public/*的路径时,Play会从文件夹/pubic中取得文件。

When supplied with a request for a /public/* path, Play will serve your files from the application /public folder.

优先权对于基本的route也适用。

Priorities are applied as for a standard route.

方向路由:生成某些URL

h2. <a name="reverse">Reverse routing: generate some URL</a>

Router 可以被用于从Java 调用中生成URL,所以你可以将URI模式集中的配置在唯一的一个配置文件中,然后可以更有信心的重构你的应用。

The Router can be used to generate a URL from within a Java call. So you’re able to centralize in one only configuration file all your URI patterns, and then be more confident when refactoring your application.

例如,下面的这个定义:

For example, with this route definition:

bc. GET    /clients/{id}             Clients.show

在你的代码中,可以根据Clients.show生成相应的URL

From your code, you can generate the URL able to invoke Clients.show:

bc. map.put("id", 1541);

String url = Router.reverse("Clients.show", map).url;  GET /clients/1541

笔记:生成URL的这个功能集成在框架的很多组件中,你永远不需要直接调用 Router.reverse这个方法。

p(note). The URL generation is integrated into many of the framework’s components. You never should use the Router.reverse operation directly.

如果你的增加的参数不包含在URL模式中,这些参数会被附加在请求参数后面。

If you add parameters that are not included in the URI pattern, these parameters will be added to the query string:

bc. map.put("id", 1541);

map.put("display", "full");

String url = Router.reverse("Clients.show", map).url; GET /clients/1541?display=full

Router会根据优先级顺序找到最符合条件的route去生成URL。

The priority order is again used to find the most specific Route able to generate the URL.

笔记:继续讨论

p(note). **Continuing the discussion**

 

Router决定了使用哪个Java调用去匹配HTTP请求时,Play框架会invokes那个Java调用,让我们看一下Controller是怎么工作的.

When the Router has determined which Java call to invoke for the received HTTP Request, the Play framework then invokes that Java call. "Let’s see how the Controller works":controllers.

设定内容类型

h2. <a name="content-types">Setting content types</a>

你可以在route的配置文件中指定文档的内容类型。

You can specify the response’s content type in the routes file:

bc. GET      /stylesheets/dynamic_css          css.SiteCSS(format:'css')

格式比较乱,不好意思啊.

加载中
0
红薯
红薯

辛苦了,呵呵

这个排版有点乱哦,看得不舒服,格式可以参考下这里:http://www.oschina.net/bbs/thread/9610

返回顶部
顶部