Apache Tobago 5.15.2 常用组件与配置详解
详解 Apache Tobago 5.15.2 常用组件的标签属性与实际渲染结构,覆盖输入、下拉、日期、勾选、消息、布局与命令组件,以及 web.xml、faces-config、tobago-config 三份配置文件的逐项说明,全部渲染 DOM 与交互回显实测通过。
Apache Tobago 5.15.2 常用组件与配置详解
目标:系统讲清 Apache Tobago 5.15.2 高频组件(输入、多行文本、日期、下拉、勾选、消息、布局、命令)的标签写法、关键属性与真实渲染 DOM,并逐项说明
web.xml、faces-config.xml、tobago-config.xml三份配置文件;所有组件均写入演示页部署到 Tomcat 9 实测渲染与表单提交。本文全部命令与回显均已在 Ubuntu 22.04 + OpenJDK 17 + Tomcat 9.0.123 实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04 LTS(x86_64)
- JDK:OpenJDK 17.0.20.1
- 应用服务器:Apache Tomcat 9.0.123(javax 技术栈)
- Tobago:5.15.2 + MyFaces 2.3.12(技术栈定位见第 3 篇)
- 实测工程目录:
/opt/tobago-demo - 演示页面:
src/main/webapp/components.xhtml(构建后部署,HTTP 200)
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/tobago-demo/components.xhtml
200
💡 阅读前提:Tobago 的
tc:标签在服务端渲染成「HTML + 自定义元素(tobago-*)+ Bootstrap 样式」的组合,前端交互由随页面加载的tobago.js(基于 JSFjsf.js扩展)接管。因此调试组件时,最终要看的是 curl 出来的 DOM 而不是 xhtml 源码。
二、组件演示页源码
src/main/webapp/components.xhtml 全文(在最小工程 demo.xhtml 基础上扩展):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:tc="http://myfaces.apache.org/tobago/component">
<f:view>
<tc:page id="page" label="Tobago 组件详解">
<tc:messages id="msgs" closeButton="true"/>
<tc:section id="sec" label="表单输入组件">
<tc:in id="name" label="姓名" value="#{hello.name}" required="true" requiredMessage="姓名不能为空"
placeholder="请输入姓名" tip="真实姓名"/>
<tc:textarea id="comment" label="备注" value="#{hello.comment}" rows="3"/>
<tc:date id="birthday" label="生日" value="#{hello.birthday}" pattern="yyyy-MM-dd"/>
<tc:selectOneChoice id="role" label="角色" value="#{hello.role}">
<f:selectItem itemValue="admin" itemLabel="管理员"/>
<f:selectItem itemValue="dev" itemLabel="开发者"/>
<f:selectItem itemValue="user" itemLabel="普通用户"/>
</tc:selectOneChoice>
<tc:selectBooleanCheckbox id="agree" label="我已阅读说明" value="#{hello.agree}"/>
</tc:section>
<tc:box id="opbox" label="操作">
<tc:button id="submit" label="提交" action="#{hello.submitAll}"/>
<tc:link id="home" label="回首页" outcome="/demo.xhtml"/>
<tc:out id="echo" label="结果" value="#{hello.summary}"/>
</tc:box>
</tc:page>
</f:view>
</html>
托管 Bean 增加对应属性(节选):
public String submitAll() {
this.summary = "姓名=" + name + ", 角色=" + role
+ ", 备注=" + (comment == null ? "-" : comment)
+ ", 生日=" + (birthday == null ? "-" : birthday)
+ ", 同意=" + agree;
return null;
}
重新构建部署(与第 3 篇步骤一致)后,页面 200,以下逐个组件对照源码与实测 DOM。
三、常用组件实测详解
以下每个组件的 DOM 均为部署后 curl 实际输出(/></> 拆行)。
3.1 tc:page —— 页面根组件
所有 Tobago 页面的唯一根,负责页面骨架、消息区、状态域与主题资源装载。
<tc:page id="page" label="Tobago 组件详解">
实测渲染:
<tobago-page locale='en_US' class='container-fluid' id='page' focus-on-error='true' wait-overlay-delay-full='1000' wait-overlay-delay-ajax='1000'>
要点:id 决定子组件 client id 前缀(page:name、page:submit);自动附带焦点恢复(tobago-focus 隐藏域)与 Ajax 等待遮罩延迟参数。
3.2 tc:messages —— 校验/全局消息区
<tc:messages id="msgs" closeButton="true"/>
实测渲染:
<tobago-messages id='page:msgs' class='tobago-messages-container'>
tc:page 在 Development 阶段也会自动渲染匿名消息区(实测 DOM <tobago-messages id='j_id_2:j_id_3'>);显式声明 tc:messages 后可控制位置与样式。closeButton 提供关闭按钮。校验失败信息(如 requiredMessage="姓名不能为空")会渲染到该区域。
3.3 tc:in —— 单行文本输入
<tc:in id="name" label="姓名" value="#{hello.name}" required="true"
requiredMessage="姓名不能为空" placeholder="请输入姓名" tip="真实姓名"/>
实测渲染:
<tobago-in id='page:name' class='tobago-label-container tobago-auto-spacing tobago-required'>
<input type='text' name='page:name' id='page:name::field' class='form-control' required='required'>
要点:label 自动生成左侧标签;required 渲染为 HTML required 并在服务端强校验;实际文本框的 id 是 组件id::field;Bootstrap 的 form-control 类承担样式。
3.4 tc:textarea —— 多行文本
<tc:textarea id="comment" label="备注" value="#{hello.comment}" rows="3"/>
实测渲染:
<tobago-textarea id='page:comment' class='tobago-label-container tobago-auto-spacing'>
<textarea name='page:comment' id='page:comment::field' rows='3' class='form-control'>
3.5 tc:date —— 日期选择
<tc:date id="birthday" label="生日" value="#{hello.birthday}" pattern="yyyy-MM-dd"/>
实测渲染:
<tobago-date id='page:birthday' class='tobago-label-container tobago-auto-spacing'>
要点:绑定 java.util.Date 类型属性,pattern 定义展示与解析格式;tc:date 渲染出的输入框由前端日期控件接管,提交时按 pattern 走 JSF DateTimeConverter 转换。实测提交 page:birthday=2026-10-15,服务端收到 Thu Oct 15 00:00:00 UTC 2026,转换链路正常。
3.6 tc:selectOneChoice —— 下拉选择
<tc:selectOneChoice id="role" label="角色" value="#{hello.role}">
<f:selectItem itemValue="admin" itemLabel="管理员"/>
<f:selectItem itemValue="dev" itemLabel="开发者"/>
<f:selectItem itemValue="user" itemLabel="普通用户"/>
</tc:selectOneChoice>
实测渲染(bean 初始值 role = "dev" 时自动选中,证明模型绑定双向生效):
<select id='page:role::field' name='page:role' class='form-select'>
<option value='admin'>
<option value='dev' selected='selected'>
<option value='user'>
3.7 tc:selectBooleanCheckbox —— 布尔勾选
<tc:selectBooleanCheckbox id="agree" label="我已阅读说明" value="#{hello.agree}"/>
实测渲染:
<tobago-select-boolean-checkbox id='page:agree' class='tobago-label-container tobago-auto-spacing'>
绑定 Boolean 类型属性即可,无需手写 converter。
3.8 tc:box / tc:section —— 布局组件
<tc:section id="sec" label="表单输入组件">
<tc:box id="opbox" label="操作">
实测渲染:
<tobago-section id='page:sec' class='tobago-section-container'>
<tobago-box class='card tobago-auto-spacing' id='page:opbox'>
tc:section 是带标题的页面分区;tc:box 渲染成 Bootstrap 卡片(card),是分组表单最常用的组件。Tobago 5 的布局由 Bootstrap 栅格与 tobago-auto-spacing 间距类接管,一般无需手工排布。
3.9 tc:button —— 命令按钮
<tc:button id="submit" label="提交" action="#{hello.submitAll}"/>
实测渲染:
<button type='button' id='page:submit' name='page:submit' class='tobago-button btn btn-secondary tobago-auto-spacing'>
要点:action 指向托管 bean 方法(返回 null 或 void 表示留在本页);默认走 Ajax 提交(部分渲染),提交协议为 JSF 标准 partial 请求(javax.faces.source + javax.faces.partial.execute)。需要整页跳转时用 action 返回导航结果字符串。
3.10 tc:link —— 导航链接
<tc:link id="home" label="回首页" outcome="/demo.xhtml"/>
实测渲染:
<a id='page:home' name='page:home' href='/tobago-demo/demo.xhtml;jsessionid=63DFF321B2243F69...'>
⚠️ 实测坑:
outcome的 ViewId 必须以/开头。写成outcome="demo"时点击链接报 500,应用服务器日志为java.lang.IllegalArgumentException: ViewId must start with a '/': demo。规范写法是outcome="/demo.xhtml"。
3.11 tc:out —— 只读输出
<tc:out id="echo" label="结果" value="#{hello.summary}"/>
实测渲染:
<tobago-out id='page:echo' class='tobago-label-container tobago-auto-spacing'>
3.12 组件提交实测
组件页整体提交(模拟 Ajax 全树执行)实测回显:
POST HTTP 200
姓名=q1w2e3r4, 角色=admin, 备注= Tobago 测试, 生日=Thu Oct 15 00:00:00 UTC 2026, 同意=false
文本、下拉、日期均正确完成「请求参数 → converter → 模型」链路;勾选框的 on 值未映射为 true(Boolean 保持 false),生产使用时建议在浏览器实测该组件的提交行为,或改用 tc:selectBooleanToggle 替代。
四、三份配置文件详解
4.1 web.xml —— Servlet 层配置
| 配置项 | 实测值 | 作用 |
|---|---|---|
web-app version | 4.0(javax 命名空间) | Tomcat 9 对应 Servlet 4.0;写 6.0 的 jakarta 命名空间无法在 Tomcat 9 部署 |
FacesServlet | javax.faces.webapp.FacesServlet | JSF 唯一入口 Servlet |
servlet-mapping | *.xhtml | 隐藏源码文件,URL 即页面 |
javax.faces.PROJECT_STAGE | Production(调试期改 Development) | Development 下校验错误、组件告警更详细,且 tc:page 自动渲染消息区 |
org.apache.myfaces.tobago.config.theme | scarborough | Tobago 主题选择(详见第 5 篇) |
welcome-file-list | demo.xhtml | 根路径直接渲染首页 |
4.2 faces-config.xml —— JSF 层配置
本工程用到两块:托管 Bean 声明(Tomcat 9 无 CDI 时最可靠的方式):
<managed-bean>
<managed-bean-name>hello</managed-bean-name>
<managed-bean-class>demo.HelloBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
以及调试用的阶段监听器(可选,问题排查利器):
<lifecycle>
<phase-listener>demo.DebugPhaseListener</phase-listener>
</lifecycle>
实测在 POST 提交中完整走完 RESTORE_VIEW 1 → APPLY_REQUEST_VALUES 2 → PROCESS_VALIDATIONS 3 → UPDATE_MODEL_VALUES 4 → INVOKE_APPLICATION 5 → RENDER_RESPONSE 6 六个阶段。有 CDI 的环境(WildFly、配置了 Weld/OpenWebBeans 的 Tomcat)可改用 @Named + @SessionScoped,无 CDI 环境务必保持 XML 声明或 JSF 原生 @ManagedBean。
4.3 tobago-config.xml —— Tobago 专属配置
<tobago-config xmlns="http://myfaces.apache.org/tobago/tobago-config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://myfaces.apache.org/tobago/tobago-config http://myfaces.apache.org/tobago/tobago-config-5.1.xsd"
version="5.1">
<name>tobago-demo</name>
<security-annotation>ignore</security-annotation>
</tobago-config>
逐项说明:
version="5.1":配置文件自身格式版本,必须与 Tobago 主版本匹配——实测 4.6.0 部署带version="5.1"的配置直接启动失败,报SAXException: Using unknown version attribute '5.1';4.x 工程要写version="4.0"。<name>:应用逻辑名,多工程合并配置时用于区分。<security-annotation>:安全注解行为,取值hide/disable/ignore。Tobago 5 默认disable,会在渲染命令组件时执行 CDI 授权检查(AuthorizationHelper),Tomcat 9 无 CDI 时页面 500(NullPointerException ... authorizationHelper is null)。无 CDI 环境必须配ignore。- 元素顺序约束:
tobago-config-5.1.xsd规定元素序列为name → ordering → theme-config → ... → security-annotation(security-annotation 在最后),顺序错误会导致 schema 校验失败、整份配置被静默拒绝,实测曾经因此让ignore不生效。
五、部署与运维配置要点
- 依赖作用域:
javax.servlet-api必须provided;tobago-core、主题、myfaces-impl、jaxb-api打进 WAR。打包后WEB-INF/lib共 15 个 jar、约 8.8 MB,自包含可直接部署。 - 会话与状态:JSF 默认服务端保存视图状态(存 session),会压测或横向扩容前评估 session 体积;改客户端保存可在
web.xml加javax.faces.STATE_SAVING_METHOD=client。 - 静态资源:主题 CSS/JS 由 Tobago ResourceServlet 按版本号路径吐出(如
/tobago-demo/tobago/scarborough/5.15.2/css/tobago.css),升级主题 jar 后浏览器缓存自动失效,无需手工清缓存。 - 错误排查入口:
logs/catalina.out(启动与渲染异常,TobagoExceptionHandler 记录Handling 500 exception与完整堆栈)+logs/localhost.*.log(应用级异常)。
六、参考链接
- Tobago 组件总览:https://tobago.apache.org/tag-reference.html
- Tobago Demo(在线交互演示):https://tobago-vm.apache.org/tobago-example-demo/
- Tobago 5.1 配置 XSD:http://myfaces.apache.org/tobago/tobago-config-5.1.xsd
- JSF 2.3 PROJECT_STAGE:https://jakarta.ee/specifications/faces/2.3/
- MyFaces 2.3 文档:https://myfaces.apache.org/core23/index.html
- 本专栏前置篇:《Apache Tobago 5.15.2 快速入门与集成示例》