【问题标题】:Using a Servlet for a non-servlet application将 Servlet 用于非 Servlet 应用程序
【发布时间】:2011-04-21 20:26:51
【问题描述】:

我知道“普通”Java,但对 servlet、容器等领域很陌生。因此,我不确定哪种方法最明智。

情况:我创建了一个 Servlet,它接收信息并将其存储在数据库中。该数据库被其他应用程序读取。

现在我需要一个应用程序,它接收完全相同的信息并将其存储在同一个数据库中。然而,这个新应用程序需要从另一台服务器(我将为此使用 httpClient)提取此信息,而不是将其推送到它。两个应用程序将共存。

对于这个新应用程序,我看到以下两个选项:

  1. 制作一个独立的应用程序。为此,我可以复制粘贴大量现有的后端代码,但我需要进行一些修改(servlet 容器提供上下文、简单的数据库连接池等)。此外,我可能需要使用一些包装器,这样可以像一个适当的守护进程一样工作,我可以启动它,但也可以优雅地停止/重启等。

  2. 使新应用程序成为 Servlet 的一部分。也就是说:只需在将运行新应用程序的 servlet 的 init() 中启动一个新线程。这将允许我重用我已经拥有的所有后端代码,而无需重写任何代码。我只需要编写向另一台服务器发出 HTTP-GET 请求的代码。使用这种方法,启动和停止服务也会更容易,因为我可以使用 Servlet 容器。

关于项目的一些信息:解析数据并将数据写入数据库的后端代码有几个线程,但不是很复杂。为原始 servlet 编写代码大约需要一周的时间。使用现有的代码库,我觉得这个新应用程序最多可能需要 1、2 天的工作时间。

我认为选项 2 更容易。但感觉有点像我会“滥用”servlet。 所以我的问题是:不是应该处理请求的应用程序的servlet,而不是发出请求的应用程序吗?有一些我在这里看不到的巨大缺点吗?哪个选项最有意义?

tl;dr:我可以编写一个不将请求作为 Servlet 提供服务的应用程序吗?

【问题讨论】:

    标签: java servlets


    【解决方案1】:

    Servlet 容器是线程管理的环境。一般来说,不要在 servlet 中启动自己的线程,否则可能会发生坏事……例如,启动和停止应用程序上下文 - 应用服务器不知道您可能已经启动的线程,因此不会停止它们与您的应用程序...(this SO question 中的更多详细信息)

    我会尝试将我需要的逻辑从 servlet 提取到不依赖于 Servlet API 的类中,并重新设计 servlet 以使用这些类。 (重构)。正如您所注意到的,servlet API 是关于接收请求和发送响应的。

    我可以在我喜欢的任何地方重复使用新的非 servlet 类中的逻辑,包括轮询提取该信息的应用程序的非 servlet 部分。

    【讨论】:

    • 跟进问题:我不应该开始自己的线程,否则会发生不好的事情。你能详细说明一下吗?现在现有的 servlet 使用两个后台线程将数据写入两个数据库。这些线程使用 BlockingQueue 连接到 servlet。我在不同的线程中有这个的原因是因为写入数据库是时间密集型的(因为数据库中有很多触发器)并且数据可能会爆发。所以这不是一个建议的设计?这会带来什么样的麻烦?
    • 对不起,我正在更新你的评论。
    • @Brabster 可能指的是大多数 web/app 服务器更喜欢在 servlet 容器中管理线程的事实,理论上你自己启动的线程是不安全的,因为容器可以处理它们。 ...
    • 如果你需要运行你自己的线程,它们应该在一个 ServletContextListener 中启动和停止,这样你就可以在上下文启动时得到回调,关键是在它停止时,这样你就可以整理无论你在做什么 - 所以有办法,但你必须非常小心。
    • @brasilt 在stackoverflow.com/questions/3873158/thread-running-in-web-page/… 上查看我的回答以获取其他解释
    【解决方案2】:

    如果您想重用代码,请将此代码作为“服务”或“业务逻辑”层的一部分,供您的 servlet 和非 servlet 应用程序使用。

    将代码打包为 jar 并在两个应用程序中使用。

    【讨论】:

      【解决方案3】:

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

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

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

      通过这种方式,您无需复制/粘贴,并且可以重复使用您的代码(甚至可以有第三种方式来调用执行繁重工作的类

      【讨论】:

        【解决方案4】:

        不要复制粘贴代码。

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-01
          • 2020-06-24
          • 2012-09-17
          • 2011-02-16
          • 1970-01-01
          • 1970-01-01
          • 2010-09-09
          • 1970-01-01
          相关资源
          最近更新 更多