[b]Direct Rendering[/b]
Pages支持直接呈现页面的方式。具体如下: 你可以直接呈现servlet响应、绕过page模板。 这对于你发送无HTML的上下文到响应到很有用, 例如: PDF、Excel文档。 步骤如下:
[list]
[*]获得servlet响应对象
[*]设置响应的类型
[*]获得响应输出流
[*]写入输出流
[*]关闭输出流
[*]将页面path设置为null, 以此来告知ClickServlet页面已经绘制完成
[/list]
如下提供了一个直接绘制页面的例子:
[b]Stateful Pages[/b]
Click支持能保存用户请求之间状态的有状态page。Stateful pages 在如下场合下是很重要的:
1 查找页面和修改页面交互时。
有时你需要从一个有状态的查找页面跳转到编辑页面, 在这个过程中, 查找页面将过滤器应用到
编辑页面上。 一旦编辑页面上的更新操作完成, 用户被重定向到查找页面,过滤器仍是可用的。
2 含有多表单或多表格的复杂页面在交互是需要保存他们的状态时。
为了使一个页面变成有状态的, 你需要将 stateful属性设置成true, 并且是Page实现Serializable 接口。
例如:
状态页面的实例使用页面的class类名做为键值存放在 HttpSession中。 在上面的例子,page使用类名
com.mycorp.page.SearchPage 被保存在用户session中。
[i]Page创建[/i]
stateful pages 仅被创建一次, 之后便从session中获取它们。 尽管每次请求都会执行page时间处理器,
包括onInit()方法,
当你创建stateful pages 时, 通常你需要将你的控件生成代码放在Page的构造方法里,因此控件
生成代码只执行一次。不将控件的生成代码放在Page的init()方法里是很重要的, 如果放在onInit() 方法里,
在每次request请求时,控件的生成代码都将会被执行。
如果你需要动态的控件生成代码, 通常你需要把这些代码放在onInit() 方法里, 但是, 你需要确保page里
还不存在这些控件和模型。
[i]Page处理[/i]
默认的Click page处理是线程安全的, 因为在每次请求和每个线程中都会创建一个新的page实例。
对于stateful pages, 用户可以将一个page重用于多个请求和线程中, 为了确保page的处理是线程安全的,
用户page实例被设置为同步的(synchronized ), 这样在同一时刻, 一个page实例仅且只能被一个请求线程
执行。
[i]Page 销毁[/i]
当正常的page被执行完毕之后, 它们应该被销毁并被JVM垃圾收集。 但是, stateful pages 存在于用户的
HttpSession 中,所以你不能将太多的对象放在stateful pages里, 这样可能导致内存溢出。
当page完成了它们的执行方法后, Page的所有控件都将调用onDestroy()方法, 之后, Page的onDestroy()
方法被调用。 这里也是你销毁大的集合和图的地方。 例如: Table控件在它的onDestroy()方法里销毁rowList 。
[b] Error Handling[/b]
当执行一个page对象的处理时或绘制一个模板时, 如果抛出异常, 该异常会被委托给注册的处理器。 默认的
Click错误处理器是 ErrorPage, 它被自动配置如下:
为了注册另外一个错误处理器, 你必须继承ErrorPage , 并使用路径click/error.htm来定义路径, 例如:
你可以覆写默认的配置文件, 并指定你自己的类, 但不能改变路径。
当ClickSevlet 启动后, 会首先检查在web目录click下是否存在not-found.htm。 如果不能找到, 会自动
部署一个。
你也可以定义click/not-found.htm 。
[b]消息属性[/b]
Page 类提供了一个消息属性, 本质上, 该属性是一个对应于page的本地化信息的MessagesMap。使用messages
作为键来呈现页面时, 在VelocityContext 范围内, 这些信息是可用的。 如果你有一个page的title信息,
在你的page模板中, 你可以这样访问:
该信息map被从page类对应的属性文件中加载。 例如:如果你有一个page类, com.mycorp.page.CustomerList,
那么你就可以在如下文件中设置你的本地化信息。
/com/mycorp/page/CustomerList.properties
我们也可以定义一个全局的信息文件:
/click-page.properties
该信息文件可以适用于你的程序的所有页面。 注意:对应class类的信息文件可以覆盖全局的信息文件。
Page信息也被用于覆盖控件信息,可用从 控件 Message Properties主题中 获得更详尽的信息。
Pages支持直接呈现页面的方式。具体如下: 你可以直接呈现servlet响应、绕过page模板。 这对于你发送无HTML的上下文到响应到很有用, 例如: PDF、Excel文档。 步骤如下:
[list]
[*]获得servlet响应对象
[*]设置响应的类型
[*]获得响应输出流
[*]写入输出流
[*]关闭输出流
[*]将页面path设置为null, 以此来告知ClickServlet页面已经绘制完成
[/list]
如下提供了一个直接绘制页面的例子:
/**
* Render the Java source file as "text/plain".
*
* @see Page#onGet()
*/
public void onGet() {
String filename = ..
HttpServletResponse response = getContext().getResponse();
response.setContentType("text/plain");
response.setHeader("Pragma", "no-cache");
ServletContext context = getContext().getServletContext();
InputStream inputStream = null;
try {
inputStream = context.getResourceAsStream(filename);
PrintWriter writer = response.getWriter();
BufferedReader reader =
new BufferedReader(new InputStreamReader(inputStream));
String line = reader.readLine();
while (line != null) {
writer.println(line);
line = reader.readLine();
}
setPath(null);
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
ClickUtils.close(inputStream);
}
}
[b]Stateful Pages[/b]
Click支持能保存用户请求之间状态的有状态page。Stateful pages 在如下场合下是很重要的:
1 查找页面和修改页面交互时。
有时你需要从一个有状态的查找页面跳转到编辑页面, 在这个过程中, 查找页面将过滤器应用到
编辑页面上。 一旦编辑页面上的更新操作完成, 用户被重定向到查找页面,过滤器仍是可用的。
2 含有多表单或多表格的复杂页面在交互是需要保存他们的状态时。
为了使一个页面变成有状态的, 你需要将 stateful属性设置成true, 并且是Page实现Serializable 接口。
例如:
package com.mycorp.page;
import java.io.Serializable;
import net.sf.click.Page;
public class SearchPage extends Page implements Serializable {
public SearchPage() {
setStateful(true);
..
}
}
状态页面的实例使用页面的class类名做为键值存放在 HttpSession中。 在上面的例子,page使用类名
com.mycorp.page.SearchPage 被保存在用户session中。
[i]Page创建[/i]
stateful pages 仅被创建一次, 之后便从session中获取它们。 尽管每次请求都会执行page时间处理器,
包括onInit()方法,
当你创建stateful pages 时, 通常你需要将你的控件生成代码放在Page的构造方法里,因此控件
生成代码只执行一次。不将控件的生成代码放在Page的init()方法里是很重要的, 如果放在onInit() 方法里,
在每次request请求时,控件的生成代码都将会被执行。
如果你需要动态的控件生成代码, 通常你需要把这些代码放在onInit() 方法里, 但是, 你需要确保page里
还不存在这些控件和模型。
[i]Page处理[/i]
默认的Click page处理是线程安全的, 因为在每次请求和每个线程中都会创建一个新的page实例。
对于stateful pages, 用户可以将一个page重用于多个请求和线程中, 为了确保page的处理是线程安全的,
用户page实例被设置为同步的(synchronized ), 这样在同一时刻, 一个page实例仅且只能被一个请求线程
执行。
[i]Page 销毁[/i]
当正常的page被执行完毕之后, 它们应该被销毁并被JVM垃圾收集。 但是, stateful pages 存在于用户的
HttpSession 中,所以你不能将太多的对象放在stateful pages里, 这样可能导致内存溢出。
当page完成了它们的执行方法后, Page的所有控件都将调用onDestroy()方法, 之后, Page的onDestroy()
方法被调用。 这里也是你销毁大的集合和图的地方。 例如: Table控件在它的onDestroy()方法里销毁rowList 。
[b] Error Handling[/b]
当执行一个page对象的处理时或绘制一个模板时, 如果抛出异常, 该异常会被委托给注册的处理器。 默认的
Click错误处理器是 ErrorPage, 它被自动配置如下:
<page path="click/error.htm" classname="net.sf.click.util.ErrorPage"/>
为了注册另外一个错误处理器, 你必须继承ErrorPage , 并使用路径click/error.htm来定义路径, 例如:
[/code] <page path="click/error.htm" classname="com.mycorp.page.ErrorPage"/>
当ClickSevlet 启动后, ClickServlet会检查在web子目录click下是否存在error.htm 模板。 如果
找不到该页面, ClickServlet会自动部署一个。 为适合你的需求你也可以自定义你的click/error.htm ,
ClickServlet 不会覆盖它。
当程序被设置为development 或 debug 模式, 默认的错误模板会显示大量的debug信息。 包括:
[quote] NullPointerException - in a page method
ParseErrorException - in a page template [/quote]
当程序被设置为production 模式, 将只显示简单的错误信息。
[b]
Page Not Found[/b]
如果ClickServlet 不能在click.xml配置文件里找到一个对应请求的page,那么将会使用not-found.htm
page。
Click not found page被自动配置如下:
[code="java"]<page path="click/not-found.htm" classname="net.sf.click.Page"/>
你可以覆写默认的配置文件, 并指定你自己的类, 但不能改变路径。
当ClickSevlet 启动后, 会首先检查在web目录click下是否存在not-found.htm。 如果不能找到, 会自动
部署一个。
你也可以定义click/not-found.htm 。
[b]消息属性[/b]
Page 类提供了一个消息属性, 本质上, 该属性是一个对应于page的本地化信息的MessagesMap。使用messages
作为键来呈现页面时, 在VelocityContext 范围内, 这些信息是可用的。 如果你有一个page的title信息,
在你的page模板中, 你可以这样访问:
<h1> $messages.title </h1>
该信息map被从page类对应的属性文件中加载。 例如:如果你有一个page类, com.mycorp.page.CustomerList,
那么你就可以在如下文件中设置你的本地化信息。
/com/mycorp/page/CustomerList.properties
我们也可以定义一个全局的信息文件:
/click-page.properties
该信息文件可以适用于你的程序的所有页面。 注意:对应class类的信息文件可以覆盖全局的信息文件。
Page信息也被用于覆盖控件信息,可用从 控件 Message Properties主题中 获得更详尽的信息。