playframework route 路由

  路由组件负责将HTTP请求交给对应的action处理(一个控制器的静态公共方法),一个HTTP请求在MVC框架里被当做一个事件看待。事件包含2个方面的信息,请求的路径(例如/clients/1524,/photos/list),包含查询字符串(参数字符串)。
  表述性状态转移(REST)是一种类似互联网的分布式超媒体软件架构风格,REST的几个关键性地方设计准则:
  1.应用功能分散在资源中
  2.每个资源使用一个唯一的URI来寻址
  3.所有资源在客户端和资源之间使用一个统一的接口来转移状态
  如果你使用过HTTP,这些接口定义了一些可用的HTTP方法。这些协议用于访问资源的状态:
  客户端-服务端   无状态
  缓存   分层

  如果一个应用遵循了REST的主要设计准则,那么这个应用就是REST风格的。play框架使构建REST风格的应用变得更容易:
  Play的路由解释URI和HTTP方法,将一个请求匹配给一个Java调用。
  基于正则表达式的URI模式匹配给你更过的灵活性。协议时无状态的,意味着你不能在2次成功的请求之间在服务器上保存任何状态。
  Play把HTTP当做关键特性,这样框架可以让你接触到HTTP的所有信息。
  Route文件语法
  conf/toutes文件是Router使用的配置文件。该文件显示了应用所需的所有route。
  每一个route由HTTP方法和URI模式匹配和一个Java调用关联。
  让我们看一下,一个的route的定义就像这样。
  GET /clients/{id} Clients.show
  每一个route以一个HTTP方法开始,后面跟着URI模式,最后的是Java调用定义。
  我们可以给route文件增加注释,以#开头
  # 显示一个客户
  GET /clients/{id} Clients.show
  HTTP方法
  HTTP方法可以是任何HTTP所支持的有效的方法。GET,POST,PUT,DELETE,HEAD
  *GET
  *POST
  *PUT
  *DELETE
  *HEAD
  如果使用作为方法,则这个route可以和任何请求的方法相匹配    /clients/{id} Clients.show
  这些route可以独立的接受请求
  GET /clients/1541
  PUT /clients/1212
  URI的模式
  URI模式定义了route(路由)中有一部分可以成为动态的,动态的部分必须包含在”{}” 中
  例如/clients/all可以匹配/clients/all,但是/clients/{id}可以独立的匹配/clients/12121,或者/clients/todo
  一个URI模式可以不止一个动态的部分
  例如 /clients/{id}/accounts/{accountId}
  动态的部分的默认匹配策略是由正则表达式/[^/]+/定义的,你可以为动态部分定义你自己的匹配正则表达式。
  下面这个正则表达式只能接受id为数字的uri请求。
  /clients/{<[0-9]+>id}
  下面这个只接受id是一个包含4位到10位小写字母的单词的请求。
  /clients/{<[a-z]{4,10}>id}
  任何合法的正则表达式都可以在这里使用。
  笔记:
  动态部分是被命名的,控制器可以在HTTP参数map中取得动态部分的值。
  默认Play认为“/”是很重要的,例如下面这个route,
  GET /clients Client.index
  会匹配/clients但是不会匹配/clients/,你可以通过在“/”后加上一个问号,告诉Play 你想让那个route匹配到后面的”/“,例如
  GET /clients/? Clients.index
  URI模式不能有任何可选的部分,除了那个”/“ (不理解)
  定义Java调用
  Route的最后一部分是Java调用定义,这部分是由一个action方法的全名定义的,并且这个action必须是一个控制器类中的静态的公共方法,控制器类必须定义在包controllers中且必须是play.mvc.Controller的子类。
  你可以在控制器类之前增加一个Java包如果它不是直接定义在controllers包中,包controllers本身是默认包含的,所以你不需要指定它。
  例如:
  GET /admin admin.Dashboard.index
  指定静态参数
  在某些情况下,你想重用一个已存在的action,但是想指定一个基于特殊的参数的值的特殊route。
  让我们在例子中看一下。
  public static void page(String id) {
  Page page = Page.findById(id);
  render(page);
  }
  使用对应的route
  GET /pages/{id} Application.page
  GET /pages/{id} Application.page
  现在,我想定义一个URL,其中id指定为’home’,我可以使用静态参数定义另外一个route
  GET /home Application.page(id:’home’)
  GET /pages/{id} Application.page
  当page ID为’home’时,第一个route和第二个route是等价的,但是,它的优先级要高一些,当你使用ID ‘home’ 调用Application.page时,它是默认被调用的。
  路由优先级
  很多路由可以匹配相同的请求,如果有冲突的话,将使用第一个定义的(写在前面的)。
  例如
  GET /clients/all Clients.listAll
  GET /clients/{id} Clients.show
  像这样定义route,URL /client/all 会被第一个route拦截,并调用 Clients.listAll。(尽管第二个路由也和它匹配)
  对静态资源的处理
  使用特殊的action ‘staticDir’,可以开放每一个你想使之成为静态资源容器的文件夹。
  例如:
  GET /public/ staticDir:public
  当你的请求中含有/public/*的路径时,Play会从文件夹/pubic中取得文件。
  优先权对于基本的route也适用。
  方向路由:生成某些URL
  Router 可以被用于从Java 调用中生成URL,所以你可以将URI模式集中的配置在唯一的一个配置文件中,然后可以更有信心的重构你的应用。
  例如,下面的这个定义:
  GET /clients/{id} Clients.show
  在你的代码中,可以根据Clients.show生成相应的URL
  map.put(“id”, 1541);
  String url = Router.reverse(“Clients.show”, map).url; GET /clients/1541
  笔记:生成URL的这个功能集成在框架的很多组件中,你永远不需要直接调用 Router.reverse这个方法。
  如果你的增加的参数不包含在URL模式中,这些参数会被附加在请求参数后面。
  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。
  当Router决定了使用哪个Java调用去匹配HTTP请求时,Play框架会invokes那个Java调用,让我们看一下Controller是怎么工作的.
  设定内容类型
  你可以在route的配置文件中指定文档的内容类型。
  GET /stylesheets/dynamic_css css.SiteCSS(format:’css’)