java Spring Boot 在 servlet 上下文之外获取应用程序基 url

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40401383/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 05:11:31  来源:igfitidea点击:

Spring boot get application base url outside of servlet context

javaspringservletsspring-bootthymeleaf

提问by Ben

The setup is following - I have a timed task that would send verification emails so users:

设置如下 - 我有一个定时任务,它会发送验证电子邮件,以便用户:

@Scheduled(cron = " 0 0-59/1 * * * * ")
public void sendVerificationEmails() {
    //...
}

And in those emails I need to include a link leading back to the same webapp. However I can not find any references of how to get app's base url without servlet context.

在这些电子邮件中,我需要包含一个指向同一个 web 应用程序的链接。但是,我找不到有关如何在没有 servlet 上下文的情况下获取应用程序基本 url 的任何参考资料。

BONUS

奖金

It would also help if I could set up thymeleaf template resolver here to work with those links, but for that I need a WebContextwhich requires an instance of HttpServletRequest.

如果我可以在这里设置 thymeleaf 模板解析器来处理这些链接,这也会有所帮助,但为此我需要一个WebContext需要HttpServletRequest.

采纳答案by eparvan

Suppose your app is using embedded tomcat server, then url to your app may be found as follows:

假设您的应用程序使用嵌入式 tomcat 服务器,那么您的应用程序的 url 可能如下所示:

@Inject
private EmbeddedWebApplicationContext appContext;

public String getBaseUrl() throws UnknownHostException {
    Connector connector = ((TomcatEmbeddedServletContainer) appContext.getEmbeddedServletContainer()).getTomcat().getConnector();
    String scheme = connector.getScheme();
    String ip = InetAddress.getLocalHost().getHostAddress();
    int port = connector.getPort();
    String contextPath = appContext.getServletContext().getContextPath();
    return scheme + "://" + ip + ":" + port + contextPath;
}

Here is an example for embedded jetty server:

以下是嵌入式码头服务器的示例:

public String getBaseUrl() throws UnknownHostException {
    ServerConnector connector = (ServerConnector) ((JettyEmbeddedServletContainer) appContext.getEmbeddedServletContainer()).getServer().getConnectors()[0];
    String scheme = connector.getDefaultProtocol().toLowerCase().contains("ssl") ? "https" : "http";
    String ip = InetAddress.getLocalHost().getHostAddress();
    int port = connector.getLocalPort();

    String contextPath = appContext.getServletContext().getContextPath();
    return scheme + "://" + ip + ":" + port + contextPath;
}

回答by Kristoffer

In my setup I have a @Configuration class setting up the context path (hardcoded) and @Value injecting the port number from application.properties. The context path could also be extracted to a properties file and injected the same way, you would use:

在我的设置中,我有一个 @Configuration 类设置上下文路径(硬编码)和 @Value 从 application.properties 注入端口号。上下文路径也可以提取到属性文件并以相同的方式注入,您可以使用:

@Value("${server.port}")
private String serverPort;
@Value("${server.contextPath}")
private String contextPath;

You can also implement ServletContextAware in your component in order to get a hook to the ServletContext which would also give you the context path.

您还可以在您的组件中实现 ServletContextAware 以获得到 ServletContext 的钩子,这也将为您提供上下文路径。

I am guessing you would like to ship a complete url (including the full server name) in your emails, but you can't really be sure that the e-mail receivers are accessing your application server directly by hostname, i.e. it could be behind a web server, a proxy etc. You could of course add a server name which you know can be accessed from outside as a property as well.

我猜你想在你的电子邮件中发送一个完整的 url(包括完整的服务器名称),但你不能确定电子邮件接收者是通过主机名直接访问你的应用程序服务器,即它可能在后面Web 服务器、代理等。您当然可以添加一个服务器名称,您知道该名称也可以作为属性从外部访问。