java - webapp 内的自定义类加载器、JSP 执行和资源检索

标签 java jsp classloader

由于项目需要,我需要创建一个 webapp,在执行时,将允许一些用户上传 zip 文件,这些文件类似于小型应用程序,将包含 .class 文件、资源(图像、css、js 等)甚至 lib 文件。该 zip 文件几乎就像一个 war 文件。

有什么简单的编码方法吗? AFAIK 我想我知道如何编写自定义 ClassLoader 以从 zip 文件 ( Java - Custom ClassLoader - trying to load a class using class file full path ) 中加载类,甚至在浏览器请求时编写资源检索代码,但不知道如何执行将在 zip 中的 JSP 文件文件或加载 zip 文件中的 jar lib 文件。

编辑:webapp 必须管理加载的应用程序,没有办法按照下面的回答来实现这个,因为 webapps 需要“主”webapp 才能生存。此外,“master”webapp 允许对应用程序进行版本控制。用户将能够上传新版本并升级到它,甚至可以在新版本开始失败时进行降级。

最佳答案

没有简单的方法可以做到这一点。这是很多工作。类加载器是非常挑剔的野兽。可以说,创建像 Tomcat 这样的东西的大部分工作都在争论类加载器,剩下的只是配置。即使过了这么多年,我们仍然有问题。

例如,Tomcat 在尝试卸载现有 Web 应用程序、使用 Java 类库的内部信息来尝试寻找类加载器泄漏的位置等方面非常积极。尽管他们做出了努力,但问题仍然存在。

最新版本的 Glassfish 具有(或将具有)对应用程序部署进行版本控制的能力。您可能会很幸运,只需破解 Tomcat 的内部路由和映射代码来管理版本控制。

如果您正在运行一个 EJB 容器,您可以将您的核心服务放在 EJB 中并让 WAR 与它们对话(您可以在通用 servlet 容器中使用 Web 服务来做到这一点,但是许多 EJB 容器可以转换远程语义进入调用同一容器的本地语义)。

你也可以看看OSGI。这是管理的另一个真正的痛苦,但它可能有足够的粒度甚至可以为您提供版本控制,但您的用户都不想使用它。我有没有提到管理起来真的很痛苦?我们这样做是为了动态加载 Web 内容和逻辑,但我们不对此进行版本控制。

如果您必须让一切都在一个 WAR 的控制之下,那么您最好的选择是使用 Java 而不是使用脚本语言。您倾向于对脚本环境的运行时有更多的控制,尤其是当您不让它们访问任意 Java 类时。

有了它,您可以上传任何您想要的有效负载,自行处理对静态资源和逻辑的所有分派(dispatch)(这意味着您可以处理版本控制方面)。为您的“JSP”页面使用诸如 Velocity 之类的东西,然后使用 Javascript 或其他任何东西来实现逻辑。

版本化环境可能很难实现。如果您不关心以原子方式执行此操作,那显然会更容易。如果您能承受“停机时间”(让 v1 脱机然后启动 v2),那就容易多了。如果您要上传每个版本的完整内容,那真的很容易。我的系统允许增量更改并具有写时复制语义,因此要困难得多。但我真的不想为每个版本上传几 Gb 的媒体。

基本要点是,在处理 Classloader 时,有龙——没有什么是容易的,并且有替代方案可以实际将代码投入生产,而不是制造伤疤和激怒龙。使用脚本语言可以极大地简化这一过程。剩下的就是分派(dispatch),这可以通过过滤器或 servlet 来完成。

执行此操作时,您将很高兴重新实现 HTTP 协议(protocol)的可靠 block ,这总是一种享受,因为 servlet 容器并没有真正向您公开该功能。也就是说,如果您想成为网络上的好公民,您会想要这样做。你总是可以不断地把内容推到客户端的喉咙里,缓存和代理都该死。

关于java - webapp 内的自定义类加载器、JSP 执行和资源检索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8026802/

相关文章:

java - 如何防止使用任意方法,例如 String.lastIndexOf()

java - 如何使用相同的字符串在 IDE 和 .jar 中加载资源

java - 在 Android 上使用 JFrame(或外部等效项)

java - 使用Javascript生成包含JSP的HTML

jsp - 在 JSP 中将枚举值作为标记属性传递

html - 通过 EL 显示多行文本

spring - 如何在 JBoss 6 中分离耳朵类加载器和系统类加载器?

java在一个类中继承,将变量部署到两个函数

java - 具有oneToMany关系的Spring boot rest api post方法

java - 从 JScrollPane 中的 Swing 滚动条中删除箭头