servlet 容器启动后立即调用对 localhost 的请求 [英] Invoke request to localhost immediately after servlet container startup

查看:26
本文介绍了servlet 容器启动后立即调用对 localhost 的请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望在 servlet 容器(无论是 tomcat、jetty 等)开始接受请求后立即在本地主机 URL 上调用自己的 Java Web 应用程序.

I'm looking to have my java web application call itself at a localhost URL immediately after the servlet container (be it tomcat, jetty, ...) begins accepting requests.

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

I'm using the java spring framework but I believe that's a "side issue" since it's really the servlet container's status that I need to be aware of.

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

As I understand it, spring initializes the application context with all its beans first, then maps the URLs and initializes the DispatcherServlet to handle the handling/filtering of requests.

我正在寻找可以安全地使用 RestTemplate 调用服务器本身的时刻".我尝试过的一切似乎都为时过早",因为它导致了 java.net.ConnectException: Connection denied——除非我通过控制器端点从 Web 浏览器手动调用它——- 成功了.

I'm looking to find the "moment" when I can safely use a RestTemplate to call the server itself. Everything I've tried seems to be "too early" as it has resulted in java.net.ConnectException: Connection refused--except for when I invoke it manually from a web browser via a controller endpoint--which succeeds.

我试过使用:

  1. javax.servlet.ServletContextListener 根据 如何在Web容器成功启动后调用servlet或控制器上的方法
  2. org.springframework.context.ApplicationListener
  3. DispatcherServlet
  4. 之后带有启动时加载"的 hacky 自定义 servlet init 方法
  1. javax.servlet.ServletContextListener as per How to invoke a method on a servlet or controller after the web container has successfully started
  2. org.springframework.context.ApplicationListener<ContextRefreshedEvent>
  3. a hacky custom servlet's init method with a "load-on-startup" after the DispatcherServlet

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

At some point in time, the servlet container must have to take over from spring's setup and "flip the switch" to "on". Also, I'd like to do this in a servlet container "agnostic" way so that I don't have specific tomcat/jetty code.

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

Here's the resttemplate exception. I'm running the app on port 9090 and my contextPath is 'openid-connect-provider'. 'foo' is a very simple GET endpoint that works, as I mentioned, when invoked after the servlet container is started.

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 告诉我它已启动之前:

The only other thing I can say is that these errors occur in my logs/console just before Jetty tells me that it's started:

[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 个月的临时步骤.

[update] A bit more background. I'm implementing an OAuth2 Authorization Server (AS). My user credentials are in a separate database that I need to access through a separate service (which is an oauth2 resource server or RS). I need my AS to call the RS to authenticate users but I want to protect my RS with tokens granted by my AS. So, i need to setup my AS as a oauth2 client of itself so that it can call the RS securely. To do that, I want to dynamically register the application (with itself) to get client_id/client_secret credentials generated so that it can call my RS. Ideally, I'd want my user info to be in the same service and not to have to do this but this is a 6-month interim step.

推荐答案

你能在 ServletContextListener#contextStarted 事件结束时试试这个小技巧吗

Can you try this little trick at the end of your ServletContextListener#contextStarted event

new Thread(() -> {
        try {
            Thread.currentThread().sleep(500);
            // Your client call.
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();

您可以调整睡眠时间.

这篇关于servlet 容器启动后立即调用对 localhost 的请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆