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

时间:2016-11-03 12:22:21

标签: java spring servlets spring-boot thymeleaf

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

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

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

奖金

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

2 个答案:

答案 0 :(得分:7)

假设您的应用使用的是嵌入式tomcat服务器,那么您的应用的网址可能会发现如下:

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

以下是嵌入式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;
}

答案 1 :(得分:3)

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

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

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

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