Tomcat Admin Tree -Jakarta Struts系列

本文介绍了Tomcat Admin的相关内容,包括其登陆设置、身份验证和权限管控。重点探讨了左方的控制树状选单,涉及TreeControlNode、TreeControl、TreeBuilder等的简介及实现。还介绍了TreeControlTag和tree - control - test.jsp。最后对比了不同的树状选单生成方法,给出适用场景建议。

Tomcat 是 jakarta 所提供的 JSP/Servlet Reference Implementation, 主要的开发者 Craig McClanahan 也是 Struts 的主要开发人员, 因此, 他利用了 struts 建立了 tomcat admin 这个项目, 作为管理 tomcat server 的环境, 当你安装完成 tomcat 的时候, 只需要 http://localhost:8080/admin , 就可以连结到 administrator 的页面, 它采用 Memory Realm 的身份验证模式, 会出现一登个登陆页面要求你登陆,

 

可以登陆的用户, 将根据你的 %CATALINA_HOME%/conf/ 之下的 tomcat-users.xml 所定义 admin 这个 role 的所有用户,

xml version='1.0' encoding='utf-8'?>
这个范例中, 具有 admin ROLE 的身份的只有 admin 这个用户,他的密码为空白,所以我们就可以采用, Username="admin", Password="", 来登陆这个系统. 那么,为何是采用 admin ROLE 呢, 而不是其他的 ROLE 呢 ? 就必须查看你的 %CATALINA_HOME%/server/webapps/admin/WEB-INF/web.xml,
  Tomcat Server Configuration Security Constraint Protected Area   *.jsp *.do *.html   admin   FORM Tomcat Server Configuration Form-Based Authentication Area /login.jsp /error.jsp   The role that is required to log in to the Administration Application admin
无论是 Authetication ( 身份验证 ) 还是 Authorization ( 权限管控 ) 都只有设置相关的 admin ROLE, 当你想要新增或修改相关的 AA, 就必须修改这一个文件, 来符合你的环境.


登陆完成之后, 就会出现一个管理员界面, 至于他的作用就是管理整个 tomcat 相关的设置文件,


而这次我们要探讨的不是怎么使用整个 tomcat admin 的操作, 而是左方的控制树状选单.


SECTION 02 TreeControlNode 简介

每一个树状节点都是一个 TreeControlNode, 主要可以设置

 


name: 这个节点的名称
icon: 这个节点的图片
label: 这个节点的说明
action: 是否具有连结
target: 点选后的目标位置 ( frame )
expanded: 是否展开
TreeBuilder , 就是产生 TreeControlNode 的集合, 我们可以查看产生 ROOT 的方法.
TreeControlNode root = new TreeControlNode("ROOT-NODE",null, rootnodeName,"setUpTree.do?select=ROOT-NODE","content", true, domain);
不难发现, 就是这么产生每一个树状节点.


SECTION 03 TreeControl 简介

org.apache.webapp.admin.SetUpTreeAction 是整个 Tree 初始化的重要 action, 第一次取得所有网页资料, 将在这里产生将所有的数据放入 session 之中, 你会看到 servlet.getServletConfig().getInitParameter("...") 将会去采用 web.xml 中的 init-parameter 设置值, 接下来的操作就比较重要, 牵扯也比较广泛, 我们会把 root 放到 TreeControl 之中,
TreeControl control = new TreeControl(root);
简单来说, 先建立一个 Root 的 TreeNode, 我们将根据这个 Root 去设置 TreeControl, 就是整个树状结构的根. 请注意, 最后我们放入 session 的是 treeControl 但是这时候, treeControl 只有 root 这个根节点.


接着, 我们将把整个树状结构放到 treeControl, 该怎么办, 怎么处理 ?


我们利用到 TreeBuilder ( Builder Pattern ) 你会看到一些复杂的代码, 没关系, 他将建立很多 tree 可以在 web.xml 的 treebuilders 之 init-param 中看到 -org.apache.webapp.admin.TomcatTreeBuilder, -org.apache.webapp.admin.resources.ResourcesTreeBuilder, -org.apache.webapp.admin.users.UsersTreeBuilder 这几个 TreeBuilder, 不过我只说明 UsersTreeBuilder 就足够让大家了解了. 基本上,我们将 org.apache.webapp.admin.users.UsersTreeBuilder newInstance() 产生对象,接着使用 buildTree() 就能够产生整个树状结构放到 treeControl 之中 ~


SECTION 04 TreeBuilder 简介

TreeBuilder 是一个 interface, 我们前端的程序就是调用 TreeBuilder 来产生 Tree 放入 Session 之中,
public interface TreeBuilder { public void buildTree(TreeControl treeControl, ApplicationServlet servlet, HttpServletRequest request); }
例如 org.apache.webapp.admin.users.UsersTreeBuilder 中,我们可以看到他实现 buildTree(), 最重要的是 addSubtree()中, 产生所有的子节点, 接着,由 root 开始 add 所有的节点, 此时, 所有的树状资料就是放在 treeControl 这个 session 之中.
protected void addSubtree(TreeControlNode root, MessageResources resources) { String databaseName = URLEncoder.encode ("Users:type=UserDatabase,database=UserDatabase"); TreeControlNode subtree = new TreeControlNode ("Global User and Group Administration", "folder_16_pad.gif", resources.getMessage("users.treeBuilder.subtreeNode"), null, "content", true); TreeControlNode groups = new TreeControlNode ("Global Administer Groups", "Groups.gif", resources.getMessage("users.treeBuilder.groupsNode"), "users/listGroups.do?databaseName=" + URLEncoder.encode(databaseName) + "&forward=" + URLEncoder.encode("Groups List Setup"), "content", false); TreeControlNode roles = new TreeControlNode ("Global Administer Roles", "Roles.gif", resources.getMessage("users.treeBuilder.rolesNode"), "users/listRoles.do?databaseName=" + URLEncoder.encode(databaseName) + "&forward=" + URLEncoder.encode("Roles List Setup"), "content", false); TreeControlNode users = new TreeControlNode ("Global Administer Users", "Users.gif", resources.getMessage("users.treeBuilder.usersNode"), "users/listUsers.do?databaseName=" + URLEncoder.encode(databaseName) + "&forward=" + URLEncoder.encode("Users List Setup"), "content", false); root.addChild(subtree); subtree.addChild(users); subtree.addChild(groups); subtree.addChild(roles); }
很明显的, 我们可以知道, 这个 UsersTreeBuilder 产生的就是 Tomcat Admin 的 User Definition. 下面具有 Users, Groups 以及 Roles 的子节点, 当你选择任何一个子节点的时候, 他将会有一个 action 的动作送到 server, 并且修改相关的树状设置产生应该显示的树状模块, 及管理画面.


SECTION 05 TreeControlTag 的简介

在 org.apache.webapp.admin.TreeControlTag 之中, 最重要的就是从 Session 取得 TreeControl 并且根据里面的內容产生相关的 HTML 代码.
// 取得 TreeControl protected TreeControl getTreeControl() throws JspException { ........ } // 产生 HTML 代码 protected void render(JspWriter out, TreeControlNode node, int level, int width, boolean last) throws IOException { ....... }
如果你对 tablib 熟悉的话, 可以看一下这个程序, 如果不熟悉, 你就当作是理所当然的代码.这个 taglib 也是整个树状结构的控制核心, 他会根据你的网页操作, 更改你的树状结构的展现方式, 如果必要的时候,例如增加 checkbox 的处理,可以修改这个程序的 render 部分, 让它具有勾选的功能.


SECTION 06 tree-control-test.jsp 的简介

你可以看到 SetUpTreeAction 最后就是 forward 到 Tree Control Test , 在 struts-config.xml 设置中 Tree Control Test 就是指到 tree-control-test.jsp 在这个 jsp 之中, 简单的 taglib 调用

就可以产生所有的树状结构了. 但是, 你可以看到每个 Node 的 action 就是 treeControlTest.do. 所以最后, 就是从 struts-config.xml 中检查 treeControlTest 是指 org.apache.webapp.admin.TreeControlTest 这个程序. 基本上你会传入 tree 这个参数, 如果你现在将 expand = true 修改设置为 false, 还可以传入 select 这个参数, 代表现在是这个 treeControlNode 被选择了.


SECTION 07 结论

在 BEA Workshop 8.1 的 netui:tree 组件, 也是采用同样的解决方式来产生 Tree. 这是属于动态的树状选单产生的方法. 和一次下载到 client 端的 javascript Tree 来相比, 每一次打开关上节点的动作都必须和 Server 端沟通, 是比较耗费资源的. 当 client 端的 browser 版本不确定的时候, 使用 DHTML ( html+javascript ) 有时候会产生错误, 有时候更会因为 javascript 数据量过大会导致 client 端的内存不足, 另外, Jdon 的 wys1978 提供了 http://webfx.eae.net/dhtml/xloadtree/xloadtree.html 一个 javascript Tree, 虽然属于 javascript, 但是不同的是, 每次动作都去调用 server 取得数据, 所以, 当你使用比较小型的系统可以采用 struts-menu 一次下载的方式就可以完成你的 tree 选单, 当数据量过大或变化频繁的时候, 我不建议一次下载所有的数据到 client 端, 所以, 不论是 taglib 解决方法还是 xloadtree 都是比较好的选择.

你遇到的问题: > ❌ `找不到依赖项 'org.apache.tomcat:tomcat-jakarta-servlet-jstl:11.0.11'` 这通常是因为 **Maven 无法从中央仓库下载该依赖**,但其实这个依赖是存在的。我们来一步步排查并解决。 --- ## ✅ 确认:`org.apache.tomcat:tomcat-jakarta-servlet-jstl:11.0.11` 是真实存在的! ### 🔗 官方地址: 👉 https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jakarta-servlet-jstl/11.0.11 你可以访问上面链接确认它确实存在于 Maven Central。 --- ## 🧩 为什么你的 Maven 找不到? 以下是常见原因及解决方案: --- ### ✅ 原因 1:网络问题或镜像源配置错误(最常见) 如果你使用了国内镜像(如阿里云),某些较新的 Tomcat 构件可能还未同步。 #### 🔍 检查你的 `settings.xml` 路径通常是: - Windows: `C:\Users\你的用户名\.m2\settings.xml` - macOS/Linux: `~/.m2/settings.xml` 如果内容中有类似: ```xml <mirror> <id>aliyun</id> <mirrorOf>central</mirrorOf> <name>Aliyun Maven</name> <url>https://maven.aliyun.com/repository/central</url> </mirror> ``` 那么问题来了:**阿里云镜像对 Jakarta 新构件的支持有延迟!** --- ### ✅ 解决方案 1:临时禁用镜像,直连 Maven Central 修改 `settings.xml`,**注释掉或删除镜像配置**,让 Maven 直接连接官方源: ```xml <!-- <mirror> <id>aliyun</id> <mirrorOf>central</mirrorOf> <url>https://maven.aliyun.com/repository/central</url> </mirror> --> ``` 然后刷新项目或执行: ```bash mvn clean compile -U ``` > `-U` 强制更新快照和缺失依赖 ✅ 很大概率就能下载成功! --- ### ✅ 解决方案 2:手动添加 `<repository>` 到 `pom.xml` 在你的 `pom.xml` 中显式声明 Maven Central 仓库(确保不被覆盖): ```xml <repositories> <repository> <id>central</id> <name>Maven Repository</name> <url>https://repo.maven.apache.org/maven2</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>central</id> <name>Maven Plugin Repository</name> <url>https://repo.maven.apache.org/maven2</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> ``` 这样即使有镜像也能强制走中央仓库拉取关键依赖。 --- ### ✅ 解决方案 3:手动下载 JAR 并安装到本地仓库(应急) 如果网络受限、公司内网不允许外联,可以手动安装。 #### 步骤 1:下载 JAR 文件 打开浏览器访问: 👉 https://repo.maven.apache.org/maven2/org/apache/tomcat/tomcat-jakarta-servlet-jstl/11.0.11/ 下载以下两个文件: - [`tomcat-jakarta-servlet-jstl-11.0.11.jar`](https://repo.maven.apache.org/maven2/org/apache/tomcat/tomcat-jakarta-servlet-jstl/11.0.11/tomcat-jakarta-servlet-jstl-11.0.11.jar) - [`tomcat-jakarta-servlet-jstl-11.0.11.pom`](https://repo.maven.apache.org/maven2/org/apache/tomcat/tomcat-jakarta-servlet-jstl/11.0.11/tomcat-jakarta-servlet-jstl-11.0.11.pom) #### 步骤 2:运行命令安装到本地 `.m2` 仓库 在你下载的目录下打开终端,执行: ```bash mvn install:install-file \ -Dfile=tomcat-jakarta-servlet-jstl-11.0.11.jar \ -DpomFile=tomcat-jakarta-servlet-jstl-11.0.11.pom ``` ✅ 成功后 Maven 就能识别这个依赖了! --- ### ✅ 解决方案 4:降级到已缓存的版本(临时过渡) 如果你暂时无法获取 `11.0.11`,可以用稍旧但广泛支持的版本: ```xml <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jakarta-servlet-jstl</artifactId> <version>10.1.19</version> <!-- 兼容 Tomcat 10 和部分 11 --> </dependency> ``` ⚠️ 注意:Tomcat 10+ 使用 `jakarta.*`,所以 `10.x` 版本也可以用于 Spring 6 + Jakarta 环境。 --- ## 🧪 验证是否成功加载 创建一个测试页面 `test.jsp`: ```jsp <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head><title>JSTL 测试</title></head> <body> <c:set var="msg" value="Hello JSTL!" /> <p>${msg}</p> <ul> <c:forEach items="${['A','B','C']}" var="ch"> <li>${ch}</li> </c:forEach> </ul> </body> </html> ``` 部署后访问,如果正常输出 → ✅ 成功! --- ## ✅ 总结:如何确保 `tomcat-jakarta-servlet-jstl` 可用? | 方法 | 说明 | |------|------| | ✅ 移除阿里云等镜像 | 最有效方式 | | ✅ 添加 `<repository>` 显式指向中央仓库 | 推荐做法 | | ✅ 使用 `-U` 强制更新 | `mvn clean compile -U` | | ✅ 手动安装 JAR | 应急方案 | | ✅ 改用 `10.1.19` 等旧版 | 过渡选择 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值