【问题标题】:How to invoke a Servlet (doGet) in a web application on startup?如何在启动时在 Web 应用程序中调用 Servlet (doGet)?
【发布时间】:2011-02-28 21:59:10
【问题描述】:

我需要在应用程序启动时调用一个 Servlet,因为它包含一些应用程序初始化逻辑。

我知道我可以设置启动时加载配置,但这只会调用 Servlet 的 init 方法。我需要调用一个 doGet 方法并将一些 Url 参数传递给它。 Servlet doGet 方法需要 ServletRequest 和 ServletResponse 对象。

另外,由于这是一个集群应用程序,我需要确切地知道我正在访问哪个节点(因为一个选项只是打开一个套接字并调用一个 Servlet)。

执行此操作的最佳选择是什么?

编辑:作为澄清,Servlet 已经存在并且无法修改。到目前为止,有人会从浏览器手动调用 Servlet。我需要自动化这个。

【问题讨论】:

  • 由于这似乎不是您自己的代码(“我无法修复它”),我强烈建议将这个巨大的缺陷报告给相关 servlet 的开发人员/维护人员。

标签: java web-applications servlets startup


【解决方案1】:

通常,使用ServletContextListener 实现引导初始化/关闭清理 - 您是否考虑过这个选项?

或者,作为一个丑陋的 hack,您可以实现一个带有初始化逻辑的 servlet 超类,它只会被调用一次。

【讨论】:

  • “您可以使用初始化逻辑实现一个 servlet 超类,并且只调用一次。”是什么意思?
  • 这种方法被用于许多 Web 框架(例如 Jersey)。所有的 servlet 都继承自 super-servlet,它包含通用逻辑和引导功能(在调用任何子 servlet 时以延迟加载的方式仅调用一次)。
【解决方案2】:

最好的选择是将doGet 方法中的所有逻辑重构为一个单独的方法,可以从initdoGet 调用。

如果你真的无法重构逻辑(这确实是唯一的好选择),你可以使用一些模拟库。谷歌表示Spring's mock objects 很受欢迎。

拥有HttpServletRequestHttpServletResponse 的可用实现,创建一个加载有load-on-startup 的servlet,并从其init 方法中,从当前ServletContext 中找到相关的servlet,然后调用doGet适当的请求和响应对象。 (是的,这是一个非常糟糕的组合,但你必须做这样的事情。)

编辑:如果您不想破解 WAR 文件,也许您应该检查您的 servlet 容器是否有可能在您重新/部署 Web 应用程序后运行某种钩子。

【讨论】:

  • +1:永远不要将应用程序逻辑与启动逻辑混为一谈。 A)第一次调用您的应用程序可能需要很长时间(如果您使用的是 Google App Engine,这有点无关紧要)。 B)这是一个可怕的组合。把你的 init 东西放在 Servlet::init()
  • 不幸的是,这不是我的选择。
  • 我不确定模拟对象是如何在这里发挥作用的?
  • 感谢 gustafc,我将尝试使用模拟选项。只要代码没有对这些对象做任何奇怪的事情,它就应该工作。
  • 为什么不直接使用 ServletContextListener 而不是所有这些带有模拟和部署挂钩的 hack?!
【解决方案3】:

这是一个词可怕,但你可以使用java.net.URL/java.net.URLConnection

new URL("http://localhost/yourservlet").openStream();

【讨论】:

  • 如何在不配置的情况下获取servlet URL?
【解决方案4】:

最好的方法是使用 java.lang.Runtime。它非常适合我。您可以覆盖必须调用 doGet 或 doPost 方法的 servlet(这里我的 servlet 名称是 BackEndServlet)的 init 方法。

@Override
    public void init(ServletConfig config) throws ServletException {

        super.init(config);
        String url = "http://localhost:8080"+config.getServletContext().getContextPath()+"/BackEndServlet"; 
        System.out.println(url);
        String os = System.getProperty("os.name").toLowerCase();
        Runtime rt = Runtime.getRuntime();

        try{

            if (os.indexOf( "win" ) >= 0) {

                // this doesn't support showing urls in the form of "page.html#nameLink" 
                rt.exec( "rundll32 url.dll,FileProtocolHandler " + url);

            } else if (os.indexOf( "mac" ) >= 0) {

                rt.exec( "open " + url);

            } else if (os.indexOf( "nix") >=0 || os.indexOf( "nux") >=0) {

                // Do a best guess on unix until we get a platform independent way
                // Build a list of browsers to try, in this order.
                String[] browsers = {"epiphany", "firefox", "mozilla", "konqueror",
                                     "netscape","opera","links","lynx"};

                // Build a command string which looks like "browser1 "url" || browser2 "url" ||..."
                StringBuffer cmd = new StringBuffer();
                for (int i=0; i<browsers.length; i++)
                    cmd.append( (i==0  ? "" : " || " ) + browsers[i] +" \"" + url + "\" ");

                rt.exec(new String[] { "sh", "-c", cmd.toString() });

            } else {
                    return;
            }
           }catch (Exception e){
            return;
           }
          return;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    相关资源
    最近更新 更多