使用 Click 框架进行 Java Web 应用程序开发/配置
本节讨论如何设置配置 Click Web 应用程序,涵盖以下主题
Click 配置文件包括
|
为了使 Click Web 应用程序正常运行,必须在 Web 应用程序的/WEB-INF/web.xml文件中配置 ClickServlet。下面提供了一个简单的 Web 应用程序,它将所有*.htm请求映射到 ClickServlet。
<web-app>
<servlet>
<servlet-name>click-servlet</servlet-name>
<servlet-class>net.sf.click.ClickServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>click-servlet</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
默认情况下,ClickServlet将尝试使用路径加载应用程序配置文件/WEB-INF/click.xml
如果在WEB-INF目录下找不到此文件,则 ClickServlet 将尝试从类路径中加载它,作为/click.xml.
按照惯例,所有 Click 页面模板都应具有 .htm 扩展名,并且 ClickServlet 应映射到处理所有 *.htm URL 请求。使用此约定,您可以让所有静态 HTML 页面使用 .html 扩展名,它们不会被处理为 Click 页面。
请注意,您应该始终将load-on-startup元素设置为 0,以便在服务器启动时初始化 servlet。这将防止第一个使用该应用程序的客户端出现任何延迟。
TheClickServlet在启动时执行尽可能多的工作以提高以后的性能。Click 启动和缓存策略是在“中的 Click 应用程序模式元素中配置的click.xml”配置文件。
Click 应用程序的核心是click.xml配置文件。此文件指定应用程序页面、标题、格式对象和应用程序模式。
请参阅 附录 C:Click DTD 以了解 click-app XML 定义。
下面提供了一个简单的 Click 应用程序配置文件
<click-app>
<pages package="com.mycorp.page"/>
</click-app>
一个带选项的配置文件示例是
<click-app charset="UTF-8" locale="de">
<pages package="com.mycorp.page">
<page path="index.htm" classname="com.mycorp.page.Home"/>
</pages>
<format classname="com.mycorp.util.Format"/>
<mode value="profile"/>
<file-item-factory classname="com.mycorp.util.AppFileItemFactory"/>
</click-app>
根 click-app 元素定义两个应用程序本地化属性 charset 和 locale。
<!ELEMENT click-app (pages?, headers?, format?, mode?, controls?, file-item-factory?)>
<!ATTLIST click-app charset CDATA #IMPLIED>
<!ATTLIST click-app locale CDATA #IMPLIED>
charset 属性定义
- Velocity 模板
- HttpServletRequest 字符编码
- 页面内容类型字符集
的字符编码集。locale 属性定义应用程序的默认语言环境。如果定义了此值,它将覆盖请求返回的语言环境。
例如,以下配置将应用程序字符集设置为 UTF-8,并将默认语言环境设置为德语 (de)
<click-app charset="UTF-8" locale="de">
..
</click-app>
click-app 的第一个子元素是必需的pages元素,它定义了 Click 页面的列表。
<!ELEMENT pages (page*)>
<!ATTLIST pages package CDATA #IMPLIED>
<!ATTLIST pages automapping (true|false) "true">
<!ATTLIST pages autobinding (true|false) "true">
pages 元素可以指定一个默认的 package 名称,该名称将作为任何定义页面的类名的前缀。
pages 元素还定义了 automapping 属性。
page 元素定义 Click 应用程序页面。
<!ELEMENT page (header*)>
<!ATTLIST page path CDATA #REQUIRED>
<!ATTLIST page classname CDATA #REQUIRED>
每个页面的 path 必须是唯一的,因为 Click 应用程序将 HTTP 请求映射到页面路径。
Click 应用程序将使用配置的页面 classname 为给定请求创建一个新的 Page 实例。所有页面都必须是 Page 的子类并提供一个公共无参数构造函数,以便可以实例化它们。
页面还可以定义 header 值,这些值将在下一主题中讨论。
当 Click 应用程序启动时,它将检查所有页面定义。如果存在严重配置错误,ClickSerlvet 将记录一个ERROR消息并抛出一个 UnavailableException。如果发生这种情况,Click 应用程序将永久不可用,直到修复错误并重新启动 Web 应用程序。
页面自动映射将使用一组简单的规则自动配置应用程序页面。这使您可以大大简化配置文件,因为您只需要定义不符合自动映射规则的页面。
自动映射将尝试将 Web 应用程序中的每个页面模板 (*.htm) 和 JSP 文件(不包括 WEB-INF 和 click 目录下的文件)与一个 Page 类关联。自动映射的页面将在手动定义的页面加载后加载,手动定义的页面优先。当启用自动映射时,Click 应用程序将在调试或跟踪模式下记录页面映射。
例如,给定一个页面路径到类映射
index.htm => com.mycorp.page.Home
search.htm => com.mycorp.page.Search
contacts/contacts.htm => com.mycorp.page.contacts.Contacts
security/login.htm => com.mycorp.page.security.Login
security/logout.htm => com.mycorp.page.security.Logout
security/change-password.htm => com.mycorp.page.security.ChangePassword
这将使用包前缀手动定义配置为
<click-app>
<pages package="com.mycorp.page" automapping="false">
<page path="index.htm" classname="Home"/>
<page path="search.htm" classname="Search"/>
<page path="contacts/contacts.htm" classname="contacts.Contacts"/>
<page path="security/login.htm" classname="security.Login"/>
<page path="security/logout.htm" classname="security.Logout"/>
<page path="security/change-password.htm" classname="security.ChangePassword"/>
</pages>
</click-app>
使用自动映射,您只需要定义 Home 页面,它不会自动映射到 index.html。
<click-app>
<pages package="com.mycorp.page">
<page path="index.htm" classname="Home"/>
</pages>
</click-app>
页面模板名称到类名约定是
change-password.htm => ChangePassword
change_password.htm => ChangePassword
changePassword.htm => ChangePassword
ChangePassword.htm => ChangePassword
在自动映射页面时,如果找不到类,Click 将尝试添加 'Page' 后缀到类名(如果不存在)并映射它。例如
customer.htm => CustomerPage
change-password.htm => ChangePasswordPage
使用页面自动映射,可能存在您不希望应用自动映射的资源。例如,在使用包含大量.htm文件的 JavaScript 库时,您不希望自动映射尝试为每个文件查找 Page 类。
在这些情况下,您可以使用 pagesexcludes元素。
<!ELEMENT excludes (#PCDATA)>
<!ATTLIST excludes pattern CDATA #REQUIRED>
例如,如果我们的应用程序使用 TinyMCE JavaScript 库,我们可以配置我们的页面自动映射以排除所有.htm位于/tiny_mce目录下的文件。
<click-app>
<pages package="com.mycorp.page">
<excludes pattern="/tiny_mce/*"/>
</pages>
</click-app>
排除模式可以使用逗号分隔的符号指定多个目录或文件。例如
<click-app>
<pages package="com.mycorp.page">
<excludes pattern="/dhtml/*, /tiny_mce/*, banner.htm, about.htm"/>
</pages>
</click-app>
从页面自动映射中排除的 HTM 文件由具有启用缓存标头的内部 Page 类处理。
默认情况下,所有页面都启用了自动绑定。启用自动绑定后,ClickServlet 将自动
- 在调用页面构造函数后将所有公共控件添加到页面
- 在调用页面构造函数后将所有请求参数绑定到公共字段
- 在渲染之前将所有公共字段添加到页面模型
您可以通过将 autobinding 属性设置为 false 来关闭此行为,例如
<click-app>
<pages package="com.mycorp.page" autobinding="false"/>
</click-app>
可选的headers元素定义了一个header元素的列表,该列表将应用于所有页面。
<!ELEMENT headers (header*)>
Theheader元素定义将应用于 HttpServletResponse 的标头名称和值对。
<!ELEMENT header (#PCDATA)>
<!ATTLIST header name CDATA #REQUIRED>
<!ATTLIST header value CDATA #REQUIRED>
<!ATTLIST header type (String|Integer|Date) "String">
页面标题在 Page 构造完成但onInit()调用之前设置。页面随后可以使用headerspropertysetHeader()方法修改其
标头通常用于关闭浏览器缓存。默认情况下,如果您未在应用程序中定义,Click 将使用以下无缓存标头值:headers元素。
<headers>
<header name="Pragma" value="no-cache"/>
<header name="Cache-Control"
value="no-store, no-cache, must-revalidate, post-check=0, pre-check=0"/>
<header name="Expires" value="1" type="Date"/>
</headers>
或者,您可以在页面中或通过设置标头值,为所有应用程序页面分别定义标头。例如,要关闭登录页面的缓存,请注意日期类型的值应为长数字值。
<page path="login.htm" classname="com.mycorp.page.Login"/>
<header name="Pragma" value="no-cache"/>
<header name="Expires" value="1" type="Date"/>
</page>
如果要为特定页面启用缓存,可以设置以下页面缓存控制标头。这将标记页面为可缓存,持续时间为 1 小时,之后应重新加载。
<page path="home.htm" classname="com.mycorp.page.Home"/>
<header name="Cache-Control" value="max-age=3600, public, must-revalidate"/>
</page>
要在全局范围内应用标头值,请在标头元素中定义标头值。例如,
<click-app>
<pages>
..
</pages>
<headers>
<header name="Pragma" value="no-cache"/>
<header name="Cache-Control"
value="no-store, no-cache, must-revalidate, post-check=0, pre-check=0"/>
<header name="Expires" value="1" type="Date"/>
</headers>
</click-app>
可选的格式元素定义应用于所有页面的 Format 对象类名。
<!ELEMENT format (#PCDATA)>
<ATTLIST format classname CDATA #FIXED "net.sf.click.util.Format">
默认情况下,所有 Click 页面都配置有 **net.sf.click.util.Format** 对象。该格式对象在使用名称的 Velocity 页面模板中可用:$format.
要指定自定义格式类,请在 click-app 描述符中配置一个格式元素。例如,
<click-app>
..
<format classname="com.mycorp.util.CustomFormat"/>
</click-app>
可选的模式元素定义应用程序日志记录和缓存模式。
<!ELEMENT mode (#PCDATA)>
<ATTLIST mode value (production|profile|development|debug|trace) "development">
默认情况下,Click 应用程序在开发模式下运行,这将关闭页面模板缓存,并将日志记录级别设置为信息.
要更改默认应用程序模式,请在 click-app 描述符中配置一个模式元素。例如,要指定生产模式,您需要添加以下模式元素:
<click-app>
..
<mode value="production">
</click-app>
应用程序模式配置可以通过设置系统属性来覆盖"click.mode"。这可以在生产系统上调试问题的情况下使用,您将模式更改为跟踪通过设置以下系统属性并重新启动应用程序。
- -Dclick.mode=trace
Click 应用程序模式及其对页面自动加载、Velocity 缓存、启动时加载模板和日志记录级别的设置如下所示:
应用程序模式 | 页面自动加载 | Velocity 缓存 | 启动时加载模板 | Click 日志记录级别 | Velocity 日志记录级别 |
---|---|---|---|---|---|
生产 | 否 | 是 | 是 | 警告 | ERROR |
个人资料 | 否 | 是 | 是 | 信息 | ERROR |
开发 | 是 | 否 | 否 | 信息 | ERROR |
调试 | 是 | 否 | 否 | 调试 | ERROR |
跟踪 | 是 | 否 | 否 | 跟踪 | 警告 |
启用页面自动加载时,任何新的页面模板和类都将在运行时自动加载。这些页面使用 页面自动映射 规则加载。
页面自动加载对于快速开发非常方便,因为您不必重新启动应用程序服务器即可获取新的页面。
启用 Velocity 缓存时,Velocity 页面模板和宏文件将加载一次并缓存。启用缓存后,将设置以下 Velocity 运行时属性:
webapp.resource.loader.cache=true
webapp.resource.loader.modificationCheckInterval=0
velocimacro.library.autoreload=false
禁用 Velocity 缓存时,Velocity 模板和宏文件将在每次更改时重新加载。禁用缓存后,将设置以下 Velocity 运行时属性:
webapp.resource.loader.cache=false
velocimacro.library.autoreload=true
模板重新加载对于应用程序开发很有用,因为您可以在运行的应用程序服务器上编辑页面模板,并立即看到更改。但是,这**不应**用于生产环境,因为 Velocity 在内省模板时会使用大量内存,并且模板重新加载速度明显更慢。
Click 和 Velocity 运行时使用 ClickLogger 记录消息。运行时记录器将向控制台发送消息System.out。例如,以下日志记录输出是应用程序模式为时的 HomePage 请求:跟踪:
[Click] [debug] GET https://127.0.0.1:8080/quickstart/home.htm [Click] [trace] invoked: HomePage.<<init>> [Click] [trace] invoked: HomePage.onSecurityCheck() : true [Click] [trace] invoked: HomePage.onInit() [Click] [trace] invoked: HomePage.onGet() [Click] [trace] invoked: HomePage.onRender() [Click] [info ] renderTemplate: /home.htm - 6 ms [Click] [trace] invoked: HomePage.onDestroy() [Click] [info ] handleRequest: /home.htm - 24 ms
任何未处理的Throwable错误由 ClickServlet 记录。
当应用程序不在生产模式下时,错误页面会显示详细的调试信息。当应用程序模式为生产时,不会显示任何调试信息,以防止泄露敏感信息。此行为可以通过修改已部署的click/error.htm页面模板来更改。
可选的控件元素定义了一个控制元素,这些元素将在应用程序启动时部署。
<!ELEMENT controls (control*)>
The控制注册将在 click 应用程序启动时调用其 onDeploy() 方法的 Control 类。
<!ELEMENT control (#PCDATA)>
<!ATTLIST control classname CDATA #REQUIRED>
例如,要注册一个CustomField控件类,您需要将以下元素添加到您的click.xml文件中
<click-app>
..
<controls>
<control classname="com.mycorp.control.CustomField"/>
</controls>
</click-app>
可选的文件项工厂元素定义要用于处理多部分文件上传请求的 Commons FileUpload FileItemFactory 对象。
<!ELEMENT file-item-factory (property*)>
<ATTLIST file-item-factory classname CDATA #FIXED "org.apache.commons.fileupload.disk.DiskFileItemFactory">
<!-- FileItem Factory property set after factory creation. -->
<!ELEMENT property (#PCDATA)>
<!ATTLIST property name CDATA #REQUIRED>
<!ATTLIST property value CDATA #REQUIRED>
默认情况下,文件上传请求使用 DiskFileItemFactory 处理。
还可以通过指定属性元素来设置工厂属性。这些属性值将使用 OGNL 类型强制转换应用于 FileItemFactory。例如,
<click-app>
..
<file-item-factory classname="org.apache.commons.fileupload.disk.DiskFileItemFactory">
<property name="sizeThreshold" name="524288"/>
</file-item-factory>
</click-app>
Velocity 运行时引擎在ClickServlet启动时通过一系列属性进行配置。设置的默认 Velocity 属性为
resource.loader=webapp
webapp.resource.loader.class=org.apache.velocity.tools.view.servlet.WebappLoader
webapp.resource.loader.cache=[true|false] depending on application mode
webapp.resource.loader.modificationCheckInterval=0 depending on application mode
velocimacro.library.autoreload=[true|false] depending on application mode
velocimacro.library=click/VM_global_library.vm
有关这些属性的详细信息,请参阅 Velocity 配置键和值开发者指南。请注意,在跟踪模式下,ClickServlet 将记录启动时使用的 Velocity 属性。
如果您想添加一些自己的 Velocity 属性,或替换 Click 的属性,请在WEB-INF目录中添加一个名为 velocity.properties 的文件。Click 将自动获取此文件并加载这些属性。
例如,假设我们有自己的 Velocity 宏库,名为mycorp.vm,我们可以通过添加一个velocimacro.library属性来覆盖默认的WEB-INF/velocity.properties文件到我们的 Web 应用程序。在此文件中,我们接下来将定义属性为
velocimacro.library=mycorp.vm
请勿将 Velocity 宏放置在 WEB-INF 目录下,因为 Velocity ResourceManager 将无法加载它们。
设置您自己的宏文件的最简单方法是在 Web 应用程序的根目录下添加一个名为macro.vm的文件。在启动时,Click 将首先检查此文件是否存在,如果存在,它将使用该文件,而不是click/VM_global_library.vm.
Click 框架使用 Velocity Tools 的WebappLoader加载模板。这避免了在 JEE 应用程序服务器上使用 Velocity 的FileResourceLoader相关的问题。
为了使预先配置的资源(模板、样式表等)可供 Web 应用程序使用,Click 会在启动时自动将配置的类路径资源部署到/click目录(如果尚未存在)。
您可以修改这些支持文件,Click 不会覆盖它们。这些文件包括
- click/error.htm - 页面 [pages.html#page-error-handling 错误处理] 模板
- click/control.css - 控件级联样式表
- click/control.js - 控件 JavaScript 库
- click/not-found.htm - [pages.html#page-not-found 页面未找到] 模板
- click/VM_Global_library.vm - 一个空的 Velocity 宏库
如果 Click 由于受限的文件系统权限而无法部署这些文件,将记录警告消息。
如果您的应用程序服务器具有受限权限,您将需要将这些自动部署文件打包到 Web 应用程序的 WAR 文件中。为此,您应该在没有这些受限权限的开发机器上运行您的应用程序,然后打包部署的文件。