Play framework 框架入门学习文档(play-1.2.3)

2012 年最新整理的Play framework 框架学习文档


一、什么是Playframework

Play Framework 是一个功能完整的Java Web 开发框架。采用RESTful 架构设计,简便灵

活。Play Framework 使用MVC 模式作为Web 层,集成Hibernate管理持久层,Play Framework

还使用一个基于Groovy 的模板引擎。

Play Framework 让开发者无须重新编译打包发布应用,即可看到修改后的效果,方便

开发人员调试应用。

Play Framework 采用了无状态模型,是一个真正意义上的“无共享”系统,能够在多

个服务器上部署多个Play Framework 的实例,所有实例都不会互相干扰。

Play Framework 采用了Groovy 作为模板引擎,让表示层真正做到了开发高效简洁

Play Framework 拥有精确的错误定位机制,当错误发生的时候,可以精确的定位到错

误代码的位置。

Play Framework 的速度很快,启动快,运行的速度也十分快。

注:RESTful 架构:REST (REpresentation StateTransfer) 描述了一个架构样式的

网络系统,比如web 应用程序。它首次出现在2000 年Roy Fielding 的博士论文

中,他是HTTP 规范的主要编写者之一。

REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计

就是RESTful

Web 应用程序最重要的REST 原则是,客户端和服务器之间的交互在请求之间是

无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服

务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由

任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性

能。

另一个重要的REST 原则是分层系统,这表示组件无法了解它与之交互的中间层以外

的组件。通过将系统知识限制在单个层,可以限制整个系统的复杂性,促进了底层的

独立性。

当REST 架构的约束条件作为一个整体应用时,将生成一个可以扩展到大量客户

端的应用程序。它还降低了客户端和服务器之间的交互延迟。统一界面简化了整个系

统架构,改进了子系统之间交互的可见性。REST 简化了客户端和服务器的实现。

详细介绍:http://baike.baidu.com/view/5798116.htm

Groovy 模块引擎:Groovy 是一种新兴的Java 2 平台语言。Groovy 代码能够与Java 代码

很好地结合,也能用于扩展现有代码。目前的Groovy 版本是1.6.3,在Java1.4 和Java

5 平台上都能使用,也能在Java 6 上使用。

Groovy 是JVM 的一个替代语言— 替代是指可以用Groovy 在Java 平台上进行Java

编程,使用方式基本与使用Java 代码的方式相同。注意:不是指Groovy 替代java,而是

指Groovy 和java 很好的结合编程

● 是一个基于Java 虚拟机的敏捷动态语言。

● 构建在强大的Java 语言之上并添加了从Python,Ruby和Smalltalk 等语言中学

到的诸多特征。

● 为Java 开发者提供了现代最流行的编程语言特性,而且学习成本很低(几乎为零)。

● 支持DSL(Domain Specific Languages 领域定义语言)和其它简洁的语法,让你的

代码变得易于阅读和维护。

● Groovy 拥有处理原生类型,面向对象以及一个Ant DSL,使得创建Shell Scripts

变的非常简单。

● 在开发Web,GUI,数据库或控制台程序时通过减少框架性代码大大提高了开发

者的效率。

● 支持单元测试和模拟(对象),可以简化测试。

● 无缝集成所有已经存在的Java 对象和类库。

● 直接编译成Java 字节码,这样可以在任何使用Java 的地方使用Groovy。

Groovy 的一个好处是,它的语法与Java 语言的语法很相似。虽然Groovy 的语法源

于Smalltalk 和Ruby 这类语言的理念,但是可以将它想像成Java 语言的一种更加简单、

表达能力更强的变体。(在这点上,Ruby 与Groovy 不同,因为它的语法与Java 语法差异

很大。)

许多Java 开发人员非常喜欢Groovy 代码和Java 代码的相似性。从学习的角度看,

如果知道如何编写Java 代码,那就已经了解Groovy 了。Groovy 和Java 语言的主要区

别是:完成同样的任务所需的Groovy 代码比Java 代码更少。(有时候会少很多!)

二、playframework 框架的优点

1) 修改代码及时生效!

编辑java 文件,保存,刷新浏览器,即可看到效果!无须编译,部署,重启服务

器。

2) 全栈式

集成Hibernate,OpenID,Memcached…还有强大的插件系统,提供了创建一个酷炫的

web 应用所需要的一切。

3) 无状态模式

4) Play 是一个真正的“Share nothing”的系统。适合REST,通过在多台服务器运行

同一个应用的多个实例,可以很容易地实现容量扩展。

5) 快速的解决错误

当发生错误时,Play 会向你准确展示源代码中产生问题的那一行代码,即使是发生

在模板中。

6) 高校的模块系统

一个简单的基于Groovy 作为表达式语言的模块系统。它提供了模块的继承,包含

和标签的功能。

7) 有趣&高校

帮助你节省等待java 应用重启的时间,提高生产效率,更快地完成工程。

8) 异步

基于非阻塞IO 模型,允许创建基于长轮询和WebSockets 的现代WebSockets 的现

代Web 应用。

9) 纯粹的Java

使用Java 进行编码,可以使用任何的Java 库,可以使用你喜欢的IDE,可以与

eclipse 或者netbeans 优雅地结合。

三、Play FrameWork 开发入门

1、准备工作

官方网站:www.playframework.org下载最新版本的play-1.2.3.zip 开发包。将下载的

包解压,解压后的路径最好不要包括空格、中文之类的,好像会有问题。

2、新建项目

将下载的play-1.2.3.zip 开发包解压并进行环境变量的配置(也可不需要配置环境变

量,但要在运行时要完整绝对路径)

打开cmd 命令窗口,键入cd play 压缩目录,接着输入play new 新建项目名称,

运行项目输入play run 项目名称。

如果没有报错证明项目可以运行,接着输入play eclipsify 项目名称,才可导入项目

到eclipsify,

打开eclipse,导入刚才新建的项目即可。

3、环境变量配置

Path: C:\Program Files\Java\jdk1.6.0_21\bin;

CLASSPATH: .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;

JAVA_HOME: C:\JDK(jdk 安装路径)

4、MVC 模型

Play 应用遵循Web 架构使用的MVC 架构模式。

它将应用分离到不同的层中:表现层(Presentation)和模型层(Model)。表现层进一步分为视

(View)和控制器(Controller)

Model 是应用所处理信息的领域表述(Domain-SpecificRepresentation)

绝大多数应用使用持久化机制如数据库存储数据。但是MVC 并没有特别提到数

据访问层,因为它属于下层,由模型封装。

View 将模型渲染成适合交互的表单,通常是用户界面。一个模型可有多个不同

目的视图。Web 应用中,View 通常以HTMLXML JSON 形式呈现,也可

能是二进制的Chart

Controller 处理事件(通常是用户动作),并对模型做相应改变。Web 应用中,

事件通常是HTTP 请求:Controller 监听HTTP 请求,从其中提取数据,如查

询字符串参数,请求头,然后改变下层模型对象。

Play 将此三层分在app 目录下的不同package 中。

app/controllers

一个Controller 就是一个Java 类,它的静态公共方法则是动作(Action)。动作是接收HTTP

请求后的Java 处理入口点。Controller 类实际是面向过程的,非OOAction HTTP 请求

中提取数据,读或更新Model 对象,然后返回一个包装成HTTP 响应(HTTP Response)的结

果。

app/models

Model 是一组具有所有OO 特性的Java 类。包含数据结构和应用可使用的操作。(译注:即充

血模型)。支持通过JPA 持久化。

app/views

应用的视图由Play 的模板系统生成。Controller Model 获取数据,然后使用模板呈现它。

package 包含HTML,XML 等模板文件,用作动态生成模型的表述(Representation)

5、应用程序布局

app 目录

包含所有可执行的工件:Java 源代码和视图模板。其下有三个标准package,每个代表MVC

的一层。你也能添加你自己的包,如示例的utils 包。

View pacakge 可以在分子packages:

tags 存储应用的ta。如可重用的模板片段。

一个Controller一个view 目录,按惯例,每个Controller 的相关模板存储

在自己的子目录中。

.class 文件在哪儿?

Play 在运行时编译Java 源代码,并将编译的类缓存在tmp\bytecode 目录下。Play 应用的

可执行工件时.java 源文件,不是已编译的.class(译注:包括jar 文件)。

public 目录

存储静态的、由Web 服务器直接处理的资源。分为三个子目录:images,stylesheets 和

javascripts,分别放图片,css 和js。

conf 目录

包含应用的所有配置文件。两个必须文件为:

application.conf: 应用主配置文件,包含所有标准的配置选项。

routes:url路由规则定义文件。

此目录包含在Java ClassPath 中。

lib 目录

存放应用依赖的标准Java 类库。此目录自动添加到Java classpath 中。

6、创建简单的helloworld 程序

打开CMD,执行:

play new helloworld

Play new 命令在当前路径下创建了一个helloworld 目录,其中包含一系列文件和目录,

重要的如下:

app/ 包含应用核心,分为models,controllers和views 目录。.java 生活的地方^_^

conf/包含应用的所有配置。application.conf 应用主配置.routes 定义url 路由规则,

messages 国际化用。

lib/ 包含应用依赖的标准.jar 文件。

public/包含所有外部可访问的资源:js,css 和image。

test/包含所有应用的测试程序。测试程序基于JUnit 或Selenium。

注:Play 要求所有文件必须是UTF-8 编码。

等等应用的.class 文件在哪儿。恩,Play 不使用class 文件而是直接读取Java 源文件,并

使用Eclipse compiler 编译他们。

这导致两件重要的事情。首先运行时Play 会检查你对源文件所作的变更并自动加载它们。

其次,当发生异常时,Play 将创建更好的错误报告并附加相关

运行应用

在cmd 中键入play run helloworld,play 启动Web Server 并监听9000 端口

打开浏览器键入http://localhost:9000/,应用显示了一个缺省的欢迎页

现在,看下此页是如何显示的。

应用的主入口点配置在conf/routes 文件中。它定义了应用所有可访问的URL。打开routes

文件,会看到第一个route:

GET /Application.index

它告诉Play,当/路径收到GET 请求后调用Application.indexJava方法。它是

controllers.Application.index的缩写,因为controllers 包是隐式的附加的。

创建标准Java 应用时,通常使用一个入口点即main 方法。Play 应用则有多个,一个URL

一个。这些方法称为action 方法。定义action 方法的类称为controller。

打开helloworld/app/controllers/Application.java:

package controllers;

import play.*;

import play.mvc.*;

import java.util.*;

import models.*;

public class Application extends Controller{

public static void index() {

render();

}

}

看到Application 扩展了play.mvcController 类。它提供了所有Controller 需要使用的方

法,如index 动作中使用的render 方法。

index 方法定义成public static void,因为Controller 永远无需实例化和返回值。(译注:

为了防止被使用者引入状态,并让Controller自然、干净而如此设计。但副作用是render

只能通过throw 扔出结果,用异常当GOTO,可谓兵行诡道)。

缺省的index 动作调用render 方法,通知Play 渲染一个模板。模板是app/views 目录下一

个简单的text 文件。此处使用Application/index.html

打开helloworld/app/views/Application/index.html文件:

#{extends 'main.html' /}

#{set title:'Home' /}

#{welcome /}

其中的内容是Play tag,类似JSP taglib.#{welcome/}tag 生成了之前看到的欢迎消息。

#{extends/}tags 告诉Play 此模板集成另一个main.html的模板.模板继承可用来创建复杂

的web 也并重用公共部分。

打开helloworld/app/views/main.html模板

<!DOCTYPEhtml>

<html>

<head>

<title>#{get 'title' /}</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<link rel="stylesheet" type="text/css" media="screen" href="@{'/public

/stylesheets/main.css'}">

#{get 'moreStyles' /}

<link rel="shortcut icon" type="image/png" href="@{'/public/images/fav

icon.png'}">

<script src="@{'/public/javascripts/jquery-1.4.2.min.js'}"type="text/

javascript" charset="utf-8"></script>

#{get 'moreScripts' /}

</head>

<body>

#{doLayout /}

</body>

</html>

看到#{doLayout/}tag 吗?是Application/index.html 插入的位置。

创建FORM

编辑helloworld/app/views/Application/index.html模板

#{extends 'main.html' /}

#{set title:'Home' /}

<form action="@{Application.sayHello()}" method="GET">

<input type="text" name="myName" />

<input type="submit" value="Say hello!" />

</form>

我们使用@{…}符号请求Play 自动产生调用Application.sayHello动作的方法。刷新浏览

器。

Oops, 出错了。因为引用了一个不存在的动作。需要在

helloworld/app/controllers/Application.java中创建:

package controllers;

import play.mvc.*;

public class Application extends Controller{

public static void index() {

render();

}

public static void sayHello(String myName){

render(myName);

}

}

我们声明了myName 参数,它会自动映射到form 提交的HTTP 请求的myName参数。刷新浏览

器。

输入name 提交,出现另一个错误.

因为Play 渲染此动作的缺省模板时,没有找到它。我们创建文件

helloworld/app/views/Application/sayHello.html

#{extends 'main.html' /}

#{set title:'Home' /}

<h1>Hello ${myName ?: 'guest'}!</h1>

<a href="@{Application.index()}">Back to form</a>

然后刷新:

提供更好的URL

看下提交的url

http://localhost:9000/application/sayhello?myName=chaos

它不够RESTful。因为Play 通过缺省规则捕获了此URL

* /{controller}/{action} {controller}.{action}

可以编辑helloworld/conf/routes文件在缺省规则前添加一条规则,提供更自然的hello

url

GET /hello Application.sayHello

自定义布局

可以修改模板更改布局。编辑helloworld/app/views/main.html文件:

添加验证

给form 添加一个验证,要求name 字段必填。我们通过Play validation 实现。编辑

helloworld/app/controllers/Application.java,在sayHello action 处:

public static void sayHello(@Required String myName) {

if (validation.hasErrors()){

flash.error("Oops, please enter your name!");

index();

}

render(myName);

}

并importplay.data.validation.*。@Required 告诉Play 自动检查myName 字段是否填写。

如果验证失败,我们加入一条消息到flashscope 中并重定向到index 动作。flashscope

允许在重定向时保持消息。

编辑helloworld/app/views/Application/index.html显示错误消息

#{extends 'main.html' /}

#{set title:'Home' /}

#{if flash.error}

<p style="color:#c00">

${flash.error}

</p>

#{/if}

<form action="@{Application.sayHello()}"method="GET">

<input type="text" name="myName" />

<input type="submit" value="Say hello!" />

</form>

输入空参数并提交,OK 起作用了。

自动化测试

Selenium Test

在测试模式下运行应用。在cmd 中输入play test helloworld。

打开浏览器,输入http://localhost:9000/@tests 启动测试器。

执行测试

Selenium 测试用例通常写成一个html 文件。Play 使用Play 模板引擎生成这些文件。

helloworld/test/Application.test.html文件:

*{ You can use plain selenium command using the selenium tag }*

#{selenium}

// Open the home page, and check that no error occured

open('/')

assertNotTitle('Application error')

#{/selenium}

此测试打开home 页,确认响应中没有“Application error”。

让我们来编写自己的测试。编辑测试内容:

*{ You can use plain selenium command using the selenium tag }*

#{selenium}

// Open the home page, and check that no error occurred

open('/')

assertNotTitle('Application error')

// Check that it is the form

assertTextPresent('The Hello world app.')

// Submit the form

clickAndWait('css=input[type=submit]')

// Check the error

assertTextPresent('Oops, please enter your name!')

// Type the name and submit

type('css=input[type=text]', 'bob')

clickAndWait('css=input[type=submit]')

// Check the result

assertTextPresent('Hello bob!')

assertTextPresent('The Hello world app.')

// Check the back link

clickAndWait('link=Back to form')

// Home page?

assertTextNotPresent('Hello bob!')

#{/selenium}

重新执行

详见:http://www.playframework.org/documentation/1.1.1/firstapp

注:app 里controllers 里的所有.java 文件里的所有方法名必须与View 文件里的所

有.html 文件名一样,不然就要指定html 文件名,如:render("User/userList.html",

pageObject);proObject 是对象名。__


[强烈推荐, 文档不多, 很快就可以看完, 看完了, 就会使用play了] 目录 MVC应用程序模型 - 7 - app/controllers - 8 - app/models - 8 - app/views - 8 - 请求生命周期 - 8 - 标准应用程序布局layout - 9 - app目录 - 9 - public目录 - 10 - conf目录 - 10 - lib目录 - 11 - 开发生命周期 - 11 - 连接到java调试器 - 12 - 类增强Enhancement - 13 - 02.HTTP路由 - 13 - 关于REST - 14 - routes文件语法 - 14 - HTTP方法 - 15 - URI范示 Pattern - 15 - Java调用定义 - 17 - 把404当作action来用 - 17 - 指派静态参数 - 17 - 变量和脚本 - 18 - 路由优先级 - 18 - 服务器静态资源 - 18 - staticDir: mapping - 18 - staticFile: mapping - 19 - URL 编码 - 19 - 反转路由:用于生成某些URL - 19 - 设置内容风格(CSS) - 20 - HTTP 内容协商 negotiation - 21 - 从http headers开始设置内容类型 - 21 - 定制格式 - 22 - 03.控制器 - 23 - 控制器概览 - 23 - 获取http参数 - 24 - 使用params map - 25 - 还可以从action方法签名实现转换 - 25 - 高级HTTP Java绑定 - 26 - 简单类型 - 26 - Date类型 - 26 - Calendar日历 - 27 - File - 27 - 支持类型的数组或集合 - 28 - POJO对象绑定 - 29 - JPA 对象绑定 - 30 - 定制绑定 - 30 - @play.data.binding.As - 30 - @play.data.binding.NoBinding - 31 - play.data.binding.TypeBinder - 31 - @play.data.binding.Global - 32 - 结果类型 - 32 - 返回一些文本类型的内容 - 33 - 返回一个JSON字符串 - 33 - 返回一个XML字符串 - 34 - 返回二进制内容 - 34 - 作为附件下载文件 - 34 - 执行一个模板 - 35 - 跳转到其他URL - 36 - Action链 - 36 - 定制web编码 - 37 - 拦截器 - 38 - @Before - 38 - @After - 39 - @Catch - 40 - @Finally - 41 - 控制器继承 - 42 - 使用@With注释添加更多的拦截器 - 42 - Because Java does not allow multiple inheritance, it can be very limiting to rely on the Controller hierarchy to apply interceptors. But you can define some interceptors in a totally different class, and link them with any controller using the @With annotation.由于java不允许多继承,通过控制器继承特点来应用拦截器就受到极大的限制。但是我们可以在一个完全不同的类里定义一些拦截器,然后在任何控制器里使用@With注释来链接他们。 - 42 - Session和Flash作用域 - 42 - 04.模板引擎 - 43 - 模板语法 - 43 - Expressions: ${…} - 44 - Template decorators : #{extends /} and #{doLayout /} - 44 - Tags: #{tagName /} - 45 - Actions: @{…} or @@{…} - 46 - Messages: &{…} - 46 - Comment: *{…}* - 46 - Scripts: %{…}% - 46 - Template inheritance继承 - 47 - 定制模板标签 - 48 - 检索tag参数 - 48 - 调用标签体 - 48 - 格式化特定标签 - 49 - 定制java标签 - 49 - 标签命名空间 - 50 - 在模板里的Java对象扩展 - 51 - 创建定制扩展 - 52 - 模板里可以使用的保留对象 - 52 - 05.用play验证http数据 - 53 - 在play里验证如何进行的? - 53 - 验证的错误消息 - 54 - Localised validation messages 局部验证消息 - 55 - 验证消息参数 - 55 - 定制局部验证消息 - 56 - 定制teral(非局部)验证消息 - 57 - 在模板里显示验证错误消息 - 57 - 验证注释 - 60 - 验证复杂对象 - 60 - 内建验证 - 61 - 使用@CheckWith定制验证 - 61 - 定制注释 - 62 - 06.域对象模型 - 64 - 属性模仿 - 65 - 设置数据库来持久化模型对象 - 68 - 用hibernate持久化对象模型 - 69 - 保持模型stateless - 70 - 07.JPA持久化 - 70 - 启动JPA实体管理器 - 70 - 获取JPA实体管理器 - 70 - 事务管理 - 71 - play.db.jpa.Model支持类 - 71 - 为GenreicModel定制id映射 - 72 - Finding对象 - 72 - Find by ID - 72 - Find all - 73 - 使用简单查询进行查找 - 73 - 使用JPQL 查询进行查找 - 74 - Counting统计对象 - 74 - 用play.db.jpa.Blob存储上传文件 - 74 - 强制保存 - 75 - 更多公共类型generic typing问题 - 77 - 08.Play.libs库包 - 78 - 用XPath解析XML - 78 - Web Service client - 79 - Functional programming with Java功能扩展? - 79 - Option<T>, Some<T> and None<T> - 80 - Tuple<A, B> - 80 - Pattern Matching模式匹配 - 81 - Promises - 81 - OAuth - 82 - OAuth 1.0 - 82 - OAuth 2.0 - 83 - OpenID - 84 - 09.异步Jobs - 86 - 引导程序任务Bootstrap jobs - 87 - 预定义任务Scheduled jobs - 87 - 触发任务job - 88 - 停止应用程序 - 89 - 10.在HTTP下进行异步编程 - 89 - 暂停http请求 - 89 - Continuations - 90 - 回调Callbacks - 91 - HTTP response流 streaming - 92 - 使用WebSockets - 92 - 11.在play框架里使用Ajax - 94 - 通过jsAction标签使用jQuery - 95 - 12. Internationalization国际化支持 - 96 - 仅使用 UTF-8! - 96 - 国际化你的信息 - 96 - 通过应用程序定义支持的语言 - 96 - 依照你的区域定义日期格式 - 97 - 找回区域信息 - 97 - Message arguments - 97 - 模板输出 - 98 - 多参数 - 98 - 立即数Argument indices - 98 - 13.使用cache - 99 - The cache API - 99 - 不要把Session当成缓存! - 101 - 配置mcached - 101 - 14.发送e-mail - 102 - Mail 和MVC 集成 - 102 - text/html e-mail - 103 - text/plain e-mail - 104 - text/html e-mail with text/plain alternative - 104 - 在应用程序里链接到邮件 - 104 - SMTP配置 - 105 - 使用 Gmail - 105 - 15.测试应用程序 - 105 - 书写测试程序 - 105 - 单元测试 - 106 - 功能性测试 - 106 - Selenium test用例测试 - 107 - Fixtures固定值 - 108 - 运行测试 - 110 - 陆续集成,并自动运行测试 - 111 - 16.安全指南 - 112 - Sessions - 112 - 守住你的安全…安全 - 112 - 不要存储关键性的数据 - 112 - 跨站点脚本攻击 - 112 - SQL注入 - 113 - 跨站点请求伪造 - 114 - 17.Play模块和模块仓库 - 115 - 什么是模块? - 115 - 如何从一个应用程序里加载模块 - 115 - 从模块加载默认的routes - 115 - 为模块增加文档说明 - 115 - 使用模块仓库 - 116 - 贡献新模块到模块仓库里 - 117 - 先决条件 - 117 - 模块注册 - 117 - 发布你的模块 - 118 - 18.依赖管理 - 118 - 依赖格式 - 119 - 动态版本 - 119 - dependencies.yml - 119 - ‘play dependencies’命令 - 120 - 透明依赖 - 121 - 保持lib/和modules/目录同步 - 122 - 冲突判定Conflict resolution - 123 - 增加要的仓库 - 124 - Maven仓库 - 125 - 本地仓库 - 125 - 定制ivy设置(Apache ivy:项目依赖管理工具) - 126 - 清除Ivy缓存 - 127 - 19.管理数据库变化Evolution - 128 - Evolutions脚本 - 128 - 同步同时发生的改变 - 130 - 数据不一致状态 - 133 - Evolutions 命令 - 136 - 20.日志配置 - 139 - 对应用程序进行日志 - 139 - 配置日志级别 - 140 - 生产配置 - 140 - 21.管理多环境下的application.conf - 140 - 框架id(framework ID) - 141 - 从命令行设置框架id - 142 - 22.生产部署 - 142 - application.conf - 142 - 设置框架为prod模式: - 142 - 定义一个真实的数据库: - 143 - 禁止JPA的自动结构更新: - 143 - 定义一个安全的secret key: - 143 - 日志配置 - 143 - 前端http服务器(Front-end HTTP server) - 144 - 部署到lighttpd服务器的设置 - 144 - 部署到Apache服务器的设置 - 145 - Apache作为前端代理服务器,可以允许透明更新你的应用程序 - 145 - 高级代理设置 - 146 - HTTPS配置 - 147 - 不依赖Python进行部署 - 148 - 23.部署选择 - 148 - 独立Play应用程序 - 149 - Java EE应用服务器 - 149 - 支持应用服务器 - 149 - 部署 - 150 - 数据源 - 150 - 定制web.xml - 151 - 基于云的主机Cloud-based hosting - 151 - AWS Elastic Beanstalk - 152 - CloudBees - 152 - Cloud Foundry - 152 - Google App Engine (GAE) - 152 - Heroku - 152 - playapps.net - 153 -
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值