在servlet容器启动后立即调用对localhost的请求

时间:2016-11-17 16:58:17

标签: java spring spring-mvc tomcat servlets

我希望我的java Web应用程序在servlet容器(tomcat,jetty,...)开始接受请求后立即调用localhost URL。

我正在使用java spring框架,但我认为这是一个“副问题”,因为它确实是我需要注意的servlet容器的状态。

据我了解,spring首先使用其所有bean初始化应用程序上下文,然后映射URL并初始化DispatcherServlet以处理请求的处理/过滤。

当我可以安全地使用RestTemplate来调用服务器本身时,我正在寻找“时刻”。我尝试过的所有东西似乎都“太早了”,因为它导致了java.net.ConnectException: Connection refused - 除了我通过控制器端点从Web浏览器手动调用它 - 这成功了。

我尝试过使用:

  1. javax.servlet.ServletContextListener根据How to invoke a method on a servlet or controller after the web container has successfully started
  2. org.springframework.context.ApplicationListener<ContextRefreshedEvent>
  3. 一个hacky自定义servlet的init方法,在DispatcherServlet
  4. 之后有一个“load-on-startup”

    在某个时间点,servlet容器必须从spring的设置接管并“将开关翻转”到“on”。另外,我想以servlet容器“不可知”的方式执行此操作,以便我没有特定的tomcat / jetty代码。

    这是resttemplate异常。我在端口9090上运行应用程序,我的contextPath是'openid-connect-provider'。 'foo'是一个非常简单的GET端点,正如我所提到的,在servlet容器启动后调用时。

    org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:9090/openid-connect-provider/foo": Connection refused; nested exception is java.net.ConnectException: Connection refused
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:582)
    ...
    

    我唯一可以说的是,在Jetty告诉我它已经启动之前,这些错误发生在我的日志/控制台中:

    [INFO] Started ServerConnector@1bcba9c7{HTTP/1.1,[http/1.1]}{0.0.0.0:9090}
    [INFO] Started @13749ms
    [INFO] Started Jetty Server
    

    [更新] 多一点背景。我正在实施OAuth2授权服务器(AS)。我的用户凭据位于一个单独的数据库中,我需要通过单独的服务(oauth2资源服务器或RS)访问该数据库。我需要我的AS来呼叫RS来验证用户,但我想用我的AS授予的令牌来保护我的RS。所以,我需要将我的AS设置为自己的oauth2客户端,以便它可以安全地调用RS。为此,我想动态注册应用程序(自身)以获取client_id / client_secret凭据,以便它可以调用我的RS。理想情况下,我希望我的用户信息在同一服务中,而不是必须这样做,但这是一个为期6个月的临时步骤。

2 个答案:

答案 0 :(得分:1)

你可以在var = IO.popen("./hello") do |cmd| cmd.read end puts var #=> "Hello world!!!" 事件结束时尝试这个小技巧

ServletContextListener#contextStarted

您可以调整睡眠时间。

答案 1 :(得分:0)

这是我决定做的(现在)。等待第一个请求以保证servlet容器正在接受请求。然后执行一次调用并禁止它再次执行,直到下次启动。

public class PostStartInitilizationListener implements HttpSessionListener {

  private static volatile boolean isInitialized;

  @Override
  public void sessionCreated(HttpSessionEvent event) {
    if (!isInitialized) { // because we don't want to do this on every session creation
      synchronized(this) { // prevent other threads from making the request as well
        isInitialized = true; // to immediately prevent any other sessionCreated events from making the request
        // the request
        ResponseEntity<String> entity = new RestTemplate().getForEntity("http://localhost:9090/openid-connect-provider/foo", String.class);
      }
    }
  }
}