Click framework 的 Page类(五)

Direct Rendering

Pages支持直接呈现页面的方式。具体如下: 你可以直接呈现servlet响应、绕过page模板。 这对于你发送无HTML的上下文到响应到很有用, 例如: PDF、Excel文档。 步骤如下:

  • 获得servlet响应对象
  • 设置响应的类型
  • 获得响应输出流
  • 写入输出流
  • 关闭输出流
  • 将页面path设置为null, 以此来告知ClickServlet页面已经绘制完成


如下提供了一个直接绘制页面的例子:

  
 /**
     * 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);
        }
    } 


Stateful Pages


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中。

Page创建
stateful pages 仅被创建一次, 之后便从session中获取它们。 尽管每次请求都会执行page时间处理器,
包括onInit()方法,
  
当你创建stateful pages 时, 通常你需要将你的控件生成代码放在Page的构造方法里,因此控件
生成代码只执行一次。不将控件的生成代码放在Page的init()方法里是很重要的, 如果放在onInit() 方法里,
在每次request请求时,控件的生成代码都将会被执行。

如果你需要动态的控件生成代码, 通常你需要把这些代码放在onInit() 方法里, 但是, 你需要确保page里
还不存在这些控件和模型。


Page处理
默认的Click page处理是线程安全的, 因为在每次请求和每个线程中都会创建一个新的page实例。
对于stateful pages, 用户可以将一个page重用于多个请求和线程中, 为了确保page的处理是线程安全的,
用户page实例被设置为同步的(synchronized ), 这样在同一时刻, 一个page实例仅且只能被一个请求线程
执行。

Page 销毁
当正常的page被执行完毕之后, 它们应该被销毁并被JVM垃圾收集。 但是,  stateful pages 存在于用户的
HttpSession 中,所以你不能将太多的对象放在stateful pages里, 这样可能导致内存溢出。

当page完成了它们的执行方法后, Page的所有控件都将调用onDestroy()方法, 之后, Page的onDestroy()
方法被调用。 这里也是你销毁大的集合和图的地方。 例如: Table控件在它的onDestroy()方法里销毁rowList 。

Error Handling

当执行一个page对象的处理时或绘制一个模板时, 如果抛出异常, 该异常会被委托给注册的处理器。 默认的
Click错误处理器是 ErrorPage, 它被自动配置如下:
 <page path="click/error.htm" classname="net.sf.click.util.ErrorPage"/> 



为了注册另外一个错误处理器, 你必须继承ErrorPage , 并使用路径click/error.htm来定义路径, 例如:

 <page path="click/error.htm" classname="com.mycorp.page.ErrorPage"/> 


当ClickSevlet 启动后, ClickServlet会检查在web子目录click下是否存在error.htm 模板。 如果
找不到该页面, ClickServlet会自动部署一个。 为适合你的需求你也可以自定义你的click/error.htm , 
ClickServlet 不会覆盖它。
当程序被设置为development 或 debug 模式, 默认的错误模板会显示大量的debug信息。 包括:

引用
NullPointerException - in a page method
ParseErrorException - in a page template


当程序被设置为production 模式, 将只显示简单的错误信息。 


Page Not Found


如果ClickServlet 不能在click.xml配置文件里找到一个对应请求的page,那么将会使用not-found.htm
page。 

Click not found page被自动配置如下:
 
<page path="click/not-found.htm" classname="net.sf.click.Page"/> 



你可以覆写默认的配置文件, 并指定你自己的类, 但不能改变路径。
当ClickSevlet 启动后, 会首先检查在web目录click下是否存在not-found.htm。 如果不能找到, 会自动
部署一个。

你也可以定义click/not-found.htm 。 

消息属性

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主题中 获得更详尽的信息。

你可能感兴趣的:(jvm,多线程,Web,servlet,Excel)