使用Servlet实现非Servlet应用程序

3
我知道普通的Java,但对于servlets、containers等领域还很陌生。因此我不确定哪种方法最合适。
情况如下:我创建了一个Servlet,用于接收信息并将其存储到数据库中。其他应用程序会读取这个数据库。
现在我需要一个应用程序,它可以接收完全相同的信息并将其存储到同一个数据库中。但是,这个新应用程序需要从另一台服务器上获取这些信息(我将使用httpClient完成这个任务),而不是让信息推送给它。这两个应用程序将共存。
对于这个新应用程序,我看到以下两个选项:
1. 创建一个独立的应用程序。对于此选项,我可以复制和粘贴大量现有的后端代码,但我需要进行一些修改(servlet容器提供上下文、简单的数据库连接池等)。此外,我可能需要使用一些包装器,以便它可以像一个合适的守护进程一样工作,我可以启动、优雅地停止/重启等。
2. 将新应用程序作为Servlet的一部分。也就是说,在init()中启动一个新线程来运行新应用程序。这将允许我重用已经拥有的所有后端代码,而无需重写任何代码。我只需要编写执行HTTP-GET请求的代码即可。使用这种方法,启动和停止服务也会更容易,因为我可以使用Servlet容器来完成。
关于项目的一些信息:解析并将数据写入数据库的后端代码有几个线程,但不是非常复杂。编写原始servlet的代码大约需要一周的时间。基于现有的代码库,我认为这个新应用程序最多只需要1到2天的工作量。
在我看来,选项2更容易。但这感觉有点像我要“滥用”servlets。所以我的问题是:servlets不是用于处理请求的应用程序,而不是用于发出请求的应用程序吗?我没有看到任何巨大的缺点吗?哪种选项最合理?
简而言之,我能不能将一个不提供请求服务的应用程序编写成Servlet?
4个回答

6

不要复制粘贴代码。

编写一个可重用的类/模块,处理将信息存储到数据库中,该类/模块可被1)servlet和2)从HttpClient检索信息的独立代码使用。

这样,同一段代码处理相同的逻辑 - 如何将信息存储到数据库中 - 无论所讨论的信息是被推送到servlet还是从远程URL获取的。


3
Servlet容器是线程管理的环境。一般来说,在servlet中不要启动自己的线程,否则可能会出现问题......例如开始和停止应用程序上下文 - 应用服务器不知道您可能已经启动的线程,因此不会随着您的应用程序停止它们...(有关更多详细信息,请参见此 SO 问题
我会尝试从servlet中提取所需的逻辑到不依赖于Servlet API的类中,并重新设计servlet以利用这些类进行重构。正如您所指出的,servlet API 全部都是关于接收请求和发送响应的。
我可以在任何地方重复使用我的新的非servlet类中的逻辑,包括轮询拉取该信息的非servlet应用程序部分。

跟进问题:如果我启动自己的线程,会发生不好的事情。你能详细解释一下吗?现在,现有的servlet使用两个后台线程将数据写入两个数据库。这些线程通过BlockingQueue连接到servlet。我之所以将其放在不同的线程中,是因为向数据库写入需要时间(因为数据库中有很多触发器),而且数据可能会突然涌入。 那么这不是一个建议的设计吗?这可能会带来什么麻烦? - brasilt
抱歉,我正在更新,你刚才评论了。 - brabster
@Brabster 可能指的是大多数 Web/App 服务器更喜欢在 Servlet 容器中管理线程,在理论上,你自己启动的线程并不安全,因为容器可能会对它们进行干扰... - Martijn Verburg
1
如果您需要运行自己的线程,它们应该在 ServletContextListener 中启动和停止,这样当上下文启动并且关键时刻停止时,您就会得到回调,以便您可以清理正在进行的任何操作 - 所以有方法,但您必须非常小心。 - brabster
@brasilt 请查看我的回答,网址为http://stackoverflow.com/questions/3873158/thread-running-in-web-page/3873200#3873200,以获得另一种解释。 - matt b
感谢您的回答和有趣的链接。 我在servlet destroy()方法中清理了所有线程,但我不确定是否足够? - brasilt

0

你可以使用,但不应该,这是非常糟糕的设计。

如果您有两种不同的方式访问应用程序(一种通过servlet,另一种作为独立应用程序),则应创建至少三个类:

  • 一个类负责处理与数据库等相关的所有工作。
  • 一个servlet调用第一个类
  • 一个独立的类(或其他)调用第一个类

这样,您就不需要复制/粘贴,并且可以重用代码(甚至可以有第三种调用执行重要工作的类的方式)。


0
如果您想要重用代码,请将该代码作为“服务”或“业务逻辑”层的一部分,这样它就可以被您的Servlet和非Servlet应用程序使用。
将代码打包成jar文件,并在两个应用程序中使用它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接