从 Spring Web 应用程序中检索 servlet 上下文路径

Posted

技术标签:

【中文标题】从 Spring Web 应用程序中检索 servlet 上下文路径【英文标题】:Retrieving the servlet context path from a Spring web application 【发布时间】:2012-08-27 12:36:57 【问题描述】:

我希望能够动态从一个 服务spring bean。

这样做的原因是我想在将要发送给网站用户的电子邮件中使用此值。

虽然从 Spring MVC 控制器执行此操作很容易,但从 Service bean 执行此操作并不那么明显。

谁能给点建议?

编辑:附加要求:

我想知道是否有一种方法可以在应用程序启动时检索上下文路径并让我的所有服务始终可以检索它?

【问题讨论】:

也许是时候将问题标记为已解决了... 【参考方案1】:

如果服务是由控制器触发的,我假设它是您可以使用 HttpSerlvetRequest 从控制器中检索路径并将完整路径传递给服务。

如果它是 UI 流的一部分,您实际上可以在任何层中注入 HttpServletRequest,因为如果您注入 HttpServletRequest,Spring 实际上会注入一个代理,该代理委托给实际的 HttpServletRequest(通过保留一个ThreadLocal 中的引用)。

import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;

public class AServiceImpl implements AService

 @Autowired private HttpServletRequest httpServletRequest;


 public String getAttribute(String name) 
  return (String)this.httpServletRequest.getAttribute(name);
 

【讨论】:

您如何在HttpServletRequest 中使用@Autowire 提供服务?确定此时请求不可用? 是的,你是对的,这就是为什么我指出这必须是 UI 流程的一部分 - 从用户到控制器的一些请求到此服务触发电子邮件,如果不是是的,那么这将不起作用。然后我能想到的最好的方法是通过将您的服务声明为 ServletContextAware 来使用注入的 HttpServletContext 获取 webapp 的上下文路径,但 URL 必须基于配置文件【参考方案2】:

我会避免从您的服务层创建对 Web 层的依赖。让您的控制器使用request.getRequestURL() 解析路径并将其直接传递给服务:

String path = request.getRequestURL().toString();
myService.doSomethingIncludingEmail(..., path, ...);

【讨论】:

感谢里奇!我想知道是否没有办法在应用程序启动时检索上下文路径并让我的所有服务始终可以检索它? 您可以在服务的配置中设置路径。虽然我看不出如何从 servlet 配置中自动检索它。 是的。嗯...但是如何在应用程序启动时检索它? 不知道抱歉,我想只有 servlet 容器会知道这个值。 好的。我只是希望在任何用户 httprequest 完成之前可用此值。我会研究此事并在此处发布相应的内容。【参考方案3】:

如果您使用 ServletContainer >= 2.5,则可以使用以下代码获取 ContextPath:

import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component

@Component
public class SpringBean 

    @Autowired
    private ServletContext servletContext;

    @PostConstruct
    public void showIt() 
        System.out.println(servletContext.getContextPath());
    

【讨论】:

另请参阅相关问题的答案:***.com/a/2066883/545127【参考方案4】:

正如 Andreas 建议的那样,您可以使用 ServletContext。我像这样使用它来获取组件中的属性:

    @Value("#servletContext.contextPath")
    private String servletContextPath;

【讨论】:

你知道如何将这个值注入到我的 js 文件中吗? 不同的问题。我个人会使用 API。否则你需要预处理你的 JS 文件。 @Wilson Campusano - 要注入 js 文件,我在我的 JSP 页面 中执行。然后在我的 js 中我参考它作为 window.contextPath @VishnooRath 谢谢!我就是这么做的。【参考方案5】:

使用 Spring Boot,您可以在 application.properties 中配置上下文路径:

server.servlet.context-path=/api

然后您可以像这样从ServiceController 获取路径:

import org.springframework.beans.factory.annotation.Value;

@Value("$server.servlet.context-path")
private String contextPath;

【讨论】:

Afaict这仅适用于带有spring-boot的嵌入式tomcat。

以上是关于从 Spring Web 应用程序中检索 servlet 上下文路径的主要内容,如果未能解决你的问题,请参考以下文章

在 tomcat 9 上部署 Spring Boot Web 应用程序时,出现错误“无法检索系统属性'spring.xml.ignore'”

从其他实体检索ID时的Spring Boot JPA反序列化问题

带有 MVC 的 Spring Boot SOAP Web 服务

Spring Boot:从数据库中检索配置

Spring Keycloak 身份验证 - 为 Web 应用程序和 Web 服务提供服务

在thymeleaf spring框架中从本地目录插入图像(使用maven)