Spring引导在servlet上下文之外获取应用程序基本URL

Ben*_*Ben 8 java spring servlets thymeleaf spring-boot

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

@Scheduled(cron = " 0 0-59/1 * * * * ")
public void sendVerificationEmails() {
    //...
}
Run Code Online (Sandbox Code Playgroud)

在那些电子邮件中,我需要包含一个返回同一webapp的链接.但是我找不到任何关于如何在没有servlet上下文的情况下获取应用程序基本URL的引用.

奖金

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

epa*_*van 7

假设您的应用程序使用的是嵌入式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;
}
Run Code Online (Sandbox Code Playgroud)

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

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;
}
Run Code Online (Sandbox Code Playgroud)


Kri*_*fer 6

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

@Value("${server.port}")
private String serverPort;
@Value("${server.contextPath}")
private String contextPath;
Run Code Online (Sandbox Code Playgroud)

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

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

  • 在 SpringBoot 的新版本中,它是 `@Value("${server.context-path}")`,但它是一个很好的解决方案,谢谢。 (3认同)