Apache Tapestry 配置参数详解
解析 Apache Tapestry 5.9.1 配置体系:符号优先级与三种修改途径、常用 tapestry.* 符号总览与分类详解、AppModule 贡献、web.xml 过滤器、log4j2 日志与 JVM 堆参数,并附生产配置模板。
Apache Tapestry 配置参数详解
一、环境信息
本篇参数行为均在以下环境实测验证,所有"实测"标记的结论都有真实执行结果支撑:
| 项目 | 实测值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(CentOS 8 上行为一致) |
| JDK | OpenJDK 17.0.20.1 |
| Maven / 构建 | 3.9.9 / quickstart 生成工程 tapestry-demo |
| 应用框架 | Apache Tapestry 5.9.1(tapestry-core-jakarta 等全套 -jakarta 构件) |
| Web 服务器 | 内嵌 Jetty 11.0.15(jakarta.servlet 5.0) |
| 应用目录 | /root/tapestry-demo |
| 验证方式 | curl 请求页面比对渲染差异 + ps -ef |
二、前置条件
- 已按快速入门流程得到一个可运行的 Tapestry 5.9.1 工程(/root/tapestry-demo),且 pom 已切换为
-jakarta构件、web.xml 为 jakarta 5.0 描述符。 - 能用
mvn -B -DskipTests package与mvn -B jetty:run完成构建与启动。 - 服务器已安装 curl,用于比对配置变更前后的页面输出差异。
三、参数查看与修改方式
3.1 符号体系与优先级
Tapestry 的配置核心是 Symbol(符号)体系:以 tapestry.* 为命名的字符串键,由 SymbolSource 按优先级链解析后注入各服务。优先级从高到低为:
- JVM 系统属性(启动命令
-Dtapestry.production-mode=false)——最高,适合部署期覆盖; - ApplicationDefaults(AppModule 的
contributeApplicationDefaults贡献、web.xml 中tapestry.*context-param)——应用级默认; - FactoryDefaults(AppModule 的
contributeFactoryDefaults贡献、框架内置出厂值)——最低。
注意:官方兼容性类符号 tapestry.compatibility 只允许以 JVM 系统属性方式设置;tapestry.service-reloading-enabled 同样要求用 JVM 系统属性,写在 AppModule 里无效。
3.2 方式一:JVM 系统属性(-D)
以内嵌 Jetty 开发模式为例,把应用切入生产渲染:
export MAVEN_OPTS="-Xms256m -Xmx512m -Dtapestry.production-mode=true"
mvn -B jetty:run
验证参数已进入 JVM:
ps -ef | grep "[j]ava" | grep -oE "\-Xms256m -Xmx512m -Dtapestry.production-mode=true"
实测回显:
-Xms256m -Xmx512m -Dtapestry.production-mode=true
渲染差异实测:设置前首页 HTML 带 data-debug-enabled="true" 属性且处于开发态;设置后该属性消失,模板空白被压缩、输出为单行 HTML。data-debug-enabled 与空白压缩是确认 tapestry.production-mode 是否生效的两个直观观测点。
3.3 方式二:web.xml context-param
web.xml 中可配置 tapestry.app-package(应用根包,必须项)与执行模式相关参数:
<context-param>
<param-name>tapestry.app-package</param-name>
<param-value>com.example</param-value>
</context-param>
<context-param>
<param-name>tapestry.development-modules</param-name>
<param-value>com.example.DevelopmentModule</param-value>
</context-param>
<context-param>
<param-name>tapestry.qa-modules</param-name>
<param-value>com.example.QaModule</param-value>
</context-param>
执行模式的加载规则:JVM 属性 tapestry.execution-mode 为逗号分隔的模式名列表(默认 production)。每个模式名 X 对应 web.xml 中的 tapestry.X-modules context-param,其值列出的模块类会在 AppModule 之后加载。例如 -Dtapestry.execution-mode=development 会加载 tapestry.development-modules 指定的 DevelopmentModule。
3.4 方式三:AppModule 贡献
quickstart 生成的 src/main/java/com/example/services/AppModule.java 演示了两种贡献方法:
public static void contributeFactoryDefaults(MappedConfiguration<String, Object> configuration) {
configuration.override(SymbolConstants.APPLICATION_VERSION, "1.0-SNAPSHOT");
// quickstart 把生产模式出厂值改为 false,方便开发期调试
configuration.override(SymbolConstants.PRODUCTION_MODE, false);
}
public static void contributeApplicationDefaults(MappedConfiguration<String, Object> configuration) {
configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");
// HMAC 口令用于加密并签名表单中的 t:formdata 隐藏字段,上线必须更换
configuration.add(SymbolConstants.HMAC_PASSPHRASE, "change this immediately-" + UUID.randomUUID());
configuration.add(SymbolConstants.ENABLE_PAGELOADING_MASK, Boolean.FALSE);
configuration.add(SymbolConstants.ENABLE_HTML5_SUPPORT, Boolean.FALSE);
}
这说明 quickstart 工程默认渲染表现为"开发态"的来源:不是框架默认值(出厂默认 tapestry.production-mode=true),而是 AppModule 覆盖为 false。用 -Dtapestry.production-mode=true 启动即可在不动代码的情况下切回生产渲染(系统属性优先级最高,实测有效)。
3.5 ⚠️ app.properties 在 5.9.1 中不生效(实测)
传统资料常提到在 src/main/resources/app.properties 中配置符号。实测 5.9.1 并不加载该文件:
cat > /root/tapestry-demo/src/main/resources/app.properties << 'EOF'
tapestry.production-mode=true
EOF
# 重新打包、启动后验证
curl -s http://127.0.0.1:8080/ | grep -c "data-debug-enabled"
实测回显:
1
data-debug-enabled 仍在,说明开发态标记未消除,配置未生效。同时在 tapestry-http-jakarta 5.9.1 构件内检索 TapestryModule 字节码,也不存在 app.properties 资源加载逻辑。结论:配置 Tapestry 符号只有 3.2-3.4 节三种官方途径,app.properties 方案不要采用(注意区分:com/example/pages/Index.properties 是页面消息目录,属于本地化文案配置,与符号配置是两回事)。
3.6 如何确认参数已生效
三个低成本观测点:
- 页面
<html>标签的data-debug-enabled属性:存在即开发态渲染; - 页面输出的空白压缩程度:生产态模板空白被压缩为单行;
<meta content="Apache Tapestry Framework (version 5.9.1)" name="generator"/>:配合tapestry.omit-generator-meta=true可隐藏(设置后该 meta 消失)。
服务启动日志也是可靠证据:org.apache.tapestry5.http.TapestryFilter Startup status: 横幅之后会输出 Application 'app' (version 1.0-SNAPSHOT) startup time: ...,application-version 取值即为符号当前值。
四、参数总览表
下表汇总常用符号(默认值一栏仅列官方 configuration.html 明确标注的值;页面可观测 表示可通过 3.6 节方式验证):
| 符号 | 常量(SymbolConstants) | 默认值 | 作用 |
|---|---|---|---|
| tapestry.app-package | (web.xml 专用) | 无 | 应用根包,Tapestry 据此发现 pages/components/services 子包 |
| tapestry.production-mode | PRODUCTION_MODE | true | 生产/开发模式总开关,影响异常报告详略与渲染行为 |
| tapestry.execution-mode | EXECUTION_MODE | production | 执行模式,决定附加加载哪些模式模块 |
| tapestry.compress-whitespace | COMPRESS_WHITESPACE | true | 压缩模板空白,页面可观测 |
| tapestry.charset | CHARSET | UTF-8 | 输入输出字符编码 |
| tapestry.supported-locales | SUPPORTED_LOCALES | en,it,es,zh_CN,pt_PT,de,ru,hr,fi_FI,sv_SE,fr_FR,da,pt_BR,ja,el | 支持的语言列表,首项为缺省语言;quickstart 收窄为 en |
| tapestry.start-page-name | START_PAGE_NAME | start | 根 URL 页名(已被 Index 页取代,遗留) |
| tapestry.exception-report-page | EXCEPTION_REPORT_PAGE | ExceptionReport | 异常报告页名 |
| tapestry.exception-reports-dir | EXCEPTION_REPORTS_DIR | - | 异常报告文本落盘目录,实测开发态异常写入 build/exceptions/ |
| tapestry.file-check-interval | FILE_CHECK_INTERVAL | 1 s | 类文件变更检查周期(开发态热加载) |
| tapestry.file-check-update-timeout | FILE_CHECK_UPDATE_TIMEOUT | 50 ms | 获取文件检查独占锁的超时 |
| tapestry.persistence-strategy | PERSISTENCE_STRATEGY | session | 页面字段默认持久化策略 |
| tapestry.gzip-compression-enabled | GZIP_COMPRESSION_ENABLED | true | 动态页面与静态资产 GZIP 压缩开关 |
| tapestry.min-gzip-size | MIN_GZIP_SIZE | - | 启用 GZIP 的响应流最小字节数 |
| tapestry.omit-generator-meta | OMIT_GENERATOR_META | false | 隐藏 <meta name="generator"> 版本标识 |
| tapestry.secure-enabled | SECURE_ENABLED | 随 production-mode | 是否启用 @Secure 页面强制 HTTPS |
| tapestry.hmac-passphrase | HMAC_PASSPHRASE | - | t:formdata 表单隐藏字段签名口令 |
| tapestry.service-reloading-enabled | (IOC 符号) | true | IoC 服务实现热重载;仅限 -D 设置 |
| tapestry.enable-pageloading-mask | ENABLE_PAGELOADING_MASK | - | 页面加载遮罩开关(quickstart 关闭) |
| tapestry.enable-html5-support | ENABLE_HTML5_SUPPORT | - | HTML5 支持开关(quickstart 关闭) |
| tapestry.javascript-infrastructure-provider | JAVASCRIPT_INFRASTRUCTURE_PROVIDER | - | JS 基础设施提供者,quickstart 设为 jquery |
| tapestry.application-version | APPLICATION_VERSION | - | 应用版本号,出现在异常报告与资产 URL |
五、核心参数分类详解
5.1 运行模式类
tapestry.production-mode:默认 true。quickstart 工程在 AppModule 中覆盖为 false,因此开发期渲染带 data-debug-enabled 标记、异常时输出完整诊断页(含属性、请求信息、异常栈),并把异常报告写盘(实测开发态报错时日志出现 Wrote exception report to file:/root/tapestry-demo/build/exceptions/2026-10-12/...)。生产环境务必确保该符号为 true(-D 或 web.xml 均可),否则异常页会泄露内部实现细节。
tapestry.execution-mode 与模式模块:默认 production。设置为 development 时加载 web.xml 中 tapestry.development-modules 指定的模块。quickstart 的 DevelopmentModule 将 PRODUCTION_MODE 定为 false、APPLICATION_VERSION 定为 1.0-SNAPSHOT-dev;QaModule 供 qa 模式使用。
tapestry.file-check-interval / file-check-update-timeout:默认 "1 s" / "50 ms"。仅开发态热加载相关;生产态类文件不热加载,此两项无需调整。
tapestry.service-reloading-enabled:默认 true,控制 IoC 服务实现变更后的热重载,官方明确要求只能通过 JVM 系统属性设置,生产可设为 false 降低开销。
5.2 输出与资产压缩类
tapestry.compress-whitespace:默认 true,压缩模板空白。实测无论开发/生产态输出均为压缩后的单行 HTML;关闭后模板换行缩进将原样输出,用于排查模板渲染问题时临时设为 false。
tapestry.gzip-compression-enabled / tapestry.min-gzip-size:GZIP 压缩动态页面与静态资产,默认开启;min-gzip-size 指定启用压缩的最小响应字节数,避免对小响应做无谓压缩。若前方另有专门的压缩层(如独立 Nginx),可将 gzip-compression-enabled 设为 false 避免双重压缩。
tapestry.omit-generator-meta:默认 false。设为 true 后页面 <head> 不再输出 Apache Tapestry Framework (version 5.9.1) 版本 meta,降低信息暴露,生产建议开启。
tapestry.combine-scripts 与 tapestry.enable-minification:合并 JavaScript 栈内多个库文件以减少请求数;minification 控制脚本压缩。开发期建议关闭以便浏览器调试,生产期开启。
tapestry.enable-pageloading-mask / tapestry.enable-html5-support:quickstart 生成的 AppModule 中均显式置 false,分别是页面加载遮罩与 HTML5 特性开关。
5.3 页面与请求类
tapestry.charset:默认 UTF-8,控制输入输出编码。页面含中文时保持 UTF-8,并保证 JVM 运行环境为 UTF-8 locale,否则 properties 消息目录中文可能乱码。
tapestry.supported-locales:逗号分隔的受支持语言,首项为缺省语言。实测将 AppModule 中该值由 en 改为 en,zh_CN,并新增消息目录 src/main/resources/com/example/pages/Index_zh_CN.properties(内容 greeting=欢迎来到 Tapestry 5!该工程模板已就绪。),重新打包启动后:
curl -s http://127.0.0.1:8080/ | grep -oE "data-locale=\"[^\"]+\"" | head -1
curl -s -H "Accept-Language: zh-CN" http://127.0.0.1:8080/ | grep -oE "data-locale=\"[^\"]+\"|欢迎来到 Tapestry 5" | head -2
实测回显:
data-locale="en"
data-locale="zh_CN"
欢迎来到 Tapestry 5
即请求按 Accept-Language 协商到 zh_CN,页面 data-locale 与问候语同步切换。
tapestry.exception-report-page / tapestry.exception-reports-dir:异常报告页默认 ExceptionReport(框架内置);生产态异常不展示诊断页但仍会落盘文本报告,目录可用该符号指定,便于事后收集。
tapestry.persistence-strategy:默认 session,页面 @Persist 字段缺省存储策略,可选 session/client。
tapestry.secure-enabled:默认随 production-mode,配合 @Secure 注解强制页面走 HTTPS。
5.4 安全类
tapestry.hmac-passphrase:用于对表单中 t:formdata 隐藏字段(客户端状态签名数据)做加密与 HMAC 签名。quickstart 生成的 AppModule 已给出随机口令示例;多实例部署时所有实例必须使用相同口令,否则 A 实例签发、B 实例提交的表单会因验签失败而丢失字段数据(表现为提交后字段为 null)。生产应从密钥管理系统注入固定强口令,不要使用示例中的 UUID.randomUUID()(每次重启变化,会话中的旧表单会失效)。
CORS 系列符号:tapestry.cors-enabled、tapestry.cors-allowed-origins、tapestry.cors-allowed-headers、tapestry.cors-allow-methods、tapestry.cors-allow-credentials、tapestry.cors-max-age 等,用于跨域响应头;默认关闭,仅在对外开放 API 时按需开启并收紧白名单。
5.5 IoC 与 JVM 参数
tapestry.service-reloading-enabled:见 5.1 节。
JVM 堆参数(-Xms/-Xmx):Tapestry 应用本体较轻(实测空应用 IoC Registry 构建 217 ms、整体启动 654 ms),小规格部署 256-512 MB 堆即可稳定运行。内嵌 Jetty 开发模式下通过 MAVEN_OPTS 注入:
export MAVEN_OPTS="-Xms256m -Xmx512m"
mvn -B jetty:run
进程级验证:
ps -ef | grep "[j]ava" | grep -oE "\-Xms256m -Xmx512m"
jps -v | grep Launcher | cut -c1-60
实测回显:
-Xms256m -Xmx512m
5314 Launcher -Xms256m -Xmx512m -Dclassworlds.conf=/opt/apache-mav
运行期堆水位可用 jstat 观察(实测空载状态):
jstat -gcutil 5314 | head -3
实测回显:
S0 S1 E O M CCS YGC YGCT FGC FGCT CGC CGCT GCT
0.00 85.66 58.55 50.73 99.14 97.24 12 0.085 0 0.000 4 0.009 0.093
独立部署(war 放入外部 Jetty/Tomcat)时,同等参数写入服务器的 JAVA_OPTS 或 setenv 脚本。
5.6 web.xml 与 TapestryFilter
org.apache.tapestry5.TapestryFilter 是应用的唯一入口 Filter,映射 /* 并配 REQUEST、ERROR 两个 dispatcher(ERROR dispatcher 保证 404 等错误页也走 Tapestry 渲染,配合 <error-page> 把 404 指到 /error404 页面)。filter-name 决定两件事:IoC 中应用模块类的查找名(filter-name 首字母大写 + Module,即 AppModule),以及启动日志中的应用名(实测横幅显示 Application 'app')。使用 -jakarta 构件时 web.xml 必须声明 5.0 描述符(jakarta 命名空间),否则部分服务器按旧规范解析。
5.7 log4j2 日志配置
quickstart 在 src/main/resources/log4j2.yml 提供日志模板(Console 输出,pattern %d{DEFAULT} [%-22thread] %-5level %60.60logger %msg%n)。值得保留的几个 logger:
org.apache.tapestry5.TapestryFilter:info 级,输出启动统计横幅(IoC Registry 构建耗时、服务清单);org.apache.tapestry5.modules.TapestryModule.ComponentClassResolver:info 级,启动时列出全部页面/组件/混入;com.example.services.AppModule.TimingFilter:示例服务日志,实测每个请求输出形如Request time: 8 ms的耗时行;- 开发期可临时开启
tapestry.transformer.*、tapestry.events.*、tapestry.render.*观察 class 转换、事件派发与渲染过程,生产应注释。
生产环境建议将 Console appender 换为 RollingFile appender 并按天滚动。
六、生产配置模板
以下为生产环境可落地的组合配置。
AppModule 生产化要点(在 quickstart 基础上调整):
public static void contributeApplicationDefaults(MappedConfiguration<String, Object> configuration) {
configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en,zh_CN");
// 从环境注入的固定口令,全部实例一致;不要在代码里写死
configuration.add(SymbolConstants.HMAC_PASSPHRASE, System.getenv("TAPESTRY_HMAC_PASSPHRASE"));
configuration.add(SymbolConstants.ENABLE_PAGELOADING_MASK, Boolean.FALSE);
configuration.add(SymbolConstants.ENABLE_HTML5_SUPPORT, Boolean.FALSE);
}
启动脚本(开发调试用内嵌 Jetty;生产打包 war 交外部 Jetty 11 / Tomcat 10+ 部署):
cat > /root/tapestry-demo/run-dev.sh << 'EOF'
#!/bin/bash
cd /root/tapestry-demo
export MAVEN_OPTS="-Xms256m -Xmx512m -Dtapestry.production-mode=true -Dtapestry.service-reloading-enabled=false"
exec mvn -B jetty:run > /root/jetty.log 2>&1
EOF
chmod +x /root/tapestry-demo/run-dev.sh
web.xml 生产化要点:保留 tapestry.app-package;移除 qa 模式 context-param(不再需要);保留 REQUEST/ERROR dispatcher;404 指向应用错误页。
log4j2.yml 生产化要点:root level 由 info 收敛为 warn;保留 TapestryFilter 的 info(启动横幅);关闭 com.example 的 debug。
验证生产配置生效的三个回显(见 3.6 节):页面无 data-debug-enabled、无 generator meta(配置 omit-generator-meta=true 时)、异常不再输出诊断页。
七、常见问题
Q1:在 AppModule 里改了 contributeApplicationDefaults,页面行为没变化?
先确认重新执行了 mvn -DskipTests package 并重启(内嵌 Jetty 的 10 秒扫描只针对已编译资源,AppModule 属于 class,通常需重启);再检查是否被更高优先级覆盖——JVM 启动参数里的同名 -D 会压过 AppModule。用 ps -ef | grep "[j]ava" 核对当前 JVM 实际携带的 -D 参数。
Q2:写了 app.properties 为什么完全不起作用? 5.9.1 不加载该文件(实测见 3.5 节,jar 内也无加载逻辑)。改用 -D、web.xml context-param 或 AppModule 三种方式之一。若要放中文文案,用页面消息目录(如 Index_zh_CN.properties),那是另一套机制且实测有效。
Q3:tapestry.production-mode=true 之后异常还是被写进 build/exceptions 目录? 落盘的是异常文本报告(EXCEPTION_REPORTS_DIR 控制),与"是否展示完整诊断页"是两件事:生产模式只是不再向前端输出诊断详情,报告仍会写盘供排查。要变更目录,配置 tapestry.exception-reports-dir 指向专用路径。
Q4:多实例部署后登录表单偶发提交失败、字段全空? 各实例的 tapestry.hmac-passphrase 不一致,跨实例的 t:formdata 验签失败导致字段数据被丢弃。统一口令后恢复;同时避免使用每次重启随机的示例口令。
Q5:中文页面乱码或 properties 里的中文读不出来?
保持 tapestry.charset=UTF-8(默认即 UTF-8),并确保 JVM 以 UTF-8 locale 运行(mvn -version 里 platform encoding 显示 ANSI_X3.4-1968 时说明系统 locale 未配置,处理方式见安装指南注意事项)。
八、参考链接
- Configuration(配置方式与符号权威说明):https://tapestry.apache.org/configuration.html
- Symbols(符号速查):https://tapestry.apache.org/symbols.html
- SymbolConstants Javadoc(常量清单):https://tapestry.apache.org/current/apidocs/org/apache/tapestry5/SymbolConstants.html
- Component Templates(空白压缩细节):https://tapestry.apache.org/component-templates.html
- Response Compression(GZIP 参数):https://tapestry.apache.org/response-compression.html
- HTTPS 与 Secure(secure-enabled):https://tapestry.apache.org/https.html
- Logging(日志框架说明):https://tapestry.apache.org/logging.html
- Tapestry IoC Configuration:https://tapestry.apache.org/ioc-cookbook.html
- 官网首页:https://tapestry.apache.org/