简体   繁体   English

如何在启动时调用Web应用程序中的Servlet(doGet)?

[英]How to invoke a Servlet (doGet) in a web application on startup?

I need to invoke a Servlet on application startup since it contains some application initialization logic. 我需要在应用程序启动时调用Servlet,因为它包含一些应用程序初始化逻辑。

I know I can set load-on-startup configuration, but this will only invoke Servlet's init method. 我知道我可以设置load-on-startup配置,但这只会调用Servlet的init方法。 I need to invoke a doGet method and pass some Url parameters to it. 我需要调用一个doGet方法并将一些Url参数传递给它。 Servlet doGet method expects ServletRequest and ServletResponse objects. Servlet doGet方法需要ServletRequest和ServletResponse对象。

Also, since this is clustered application, I need to know exactly what node I am accessing (since one option is just to open a socket and invoke a Servlet). 此外,由于这是集群应用程序,我需要确切地知道我正在访问哪个节点(因为一个选项只是打开一个套接字并调用一个Servlet)。

What is the best option to perform this? 执行此操作的最佳选择是什么?

EDIT: As a clarification, Servlet already exist and can not be modified. 编辑:作为澄清,Servlet已经存在,无法修改。 Until now, someone would manually invoke the Servlet from the browser. 到现在为止,有人会从浏览器手动调用Servlet。 I need to automatize this. 我需要自动化这个。

Normally, bootstrup initialization / shutdown cleanup is achieved with ServletContextListener - did you consider this option? 通常,使用ServletContextListener实现bootstrup初始化/关闭清理 - 您是否考虑过此选项?

Alternatively, as an ugly hack, you can implement a servlet superclass with the initializtion logics, that will be called just once. 或者,作为一个丑陋的黑客,你可以用初始化逻辑实现一个servlet超类,它只会被调用一次。

The best option is to refactor whatever logic you have in the doGet method into a separate method that can be invoked both from init and doGet . 最好的选择是将doGet方法中的任何逻辑重构为可以从initdoGet调用的单独方法。

If you really can't refactor the logic (which really is the only good option), you can use some mock library. 如果你真的无法重构逻辑(这确实是唯一的好选择),你可以使用一些模拟库。 Google says Spring's mock objects are popular. 谷歌称Spring的模拟对象很受欢迎。

Having a usable implementation of HttpServletRequest and HttpServletResponse , make a servlet loaded with load-on-startup , and from its init method, locate the relevant servlet from the current ServletContext , and invoke doGet with the appropriate request and response objects. 有一个可用的HttpServletRequestHttpServletResponse ,使servlet加载load-on-startup ,并从其init方法,从当前的ServletContext找到相关的servlet,并使用适当的请求和响应对象调用doGet (Yes, it's a pretty bad kludge, but you'll have to do something like this.) (是的,这是一个非常糟糕的kludge,但你必须做这样的事情。)

Edit: If you don't want to hack the WAR file, maybe you should check if your servlet container has the possibility to run some kind of hooks after you re/deploy a web app. 编辑:如果您不想破解WAR文件,也许您应该在重新/部署Web应用程序后检查您的servlet容器是否可以运行某种挂钩。

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

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

The best way to do this by using java.lang.Runtime. 使用java.lang.Runtime执行此操作的最佳方法。 Its worked for me perfectly. 它完美地为我工作。 You can override init method in which servlet(here my servlet name is BackEndServlet) you have to call either doGet or doPost method. 你可以覆盖init方法,其中servlet(这里我的servlet名称是BackEndServlet)你必须调用doGet或doPost方法。

@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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM