2

我有一个 Web 应用程序,其中包含我的一个应用程序服务的配置 xml 文件,该文件作为 spring bean 公开。此外,我在同一个工作区中有一个独立的 java 应用程序(它从 pom.xml 引用我的 web 应用程序项目),它使用 Spring TestContext 框架运行测试,其中一个测试检查该 XML 文件的配置。

但是,我从独立应用程序访问此 xml 文件时遇到问题:

在设置测试之前,在我之前的配置中,该文件是通过 ServletContext 访问的,并且位于WEB-INF/文件夹中。但是,为了使它可以从测试项目中访问,我必须将它移动到源/文件夹并使用 getClassLoader().getResourceAsStream() 方法而不是 ServletContext 方法加载它。但它使编辑文件变得很麻烦,因为每次都必须重新部署应用程序。

是否可以将文件保存在WEB-INF/文件夹中,但在测试运行期间从引用项目中加载它?

PS 目前它是一个带有 Tomcat 服务器的 STS 项目。

4

4 回答 4

5

绝对将文件保存在 WEB-INF/ 文件夹下,如果那是它应该存在的地方。

对于从命令行执行的测试类。您可以在您知道位于类路径根目录中的文件(例如 application.properties 文件)上使用 getClassLoader().getResource()。从那里你知道你的项目的结构以及在哪里可以找到相对于属性文件的 WEB-INF/。由于它返回一个 URL,因此您可以使用它来找出您正在寻找的 XML 文件的路径。

URL url = this.getClass().getClassLoader().getResource("application.properties");
System.out.println(url.getPath());

File file = new File(url.getFile());
System.out.println(file);

// now use the Files' path to obtain references to your WEB-INF folder

希望你觉得这很有用。我不得不对您的测试类的运行方式等做出假设。

看一下File Class,它的 getPath()、getAbsolutePath() 和 getParent() 方法可能对您有用。

于 2012-05-17T16:32:27.523 回答
3

在测试运行之前,我最终使用了 Spring MockServletContext类并将其直接注入到我的服务 bean 中,因为我的服务已实现ServletContextAware

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/test-ctx.xml" } ) 
public class SomeServiceTest {

@Autowired
private MyServletContextAwareService myService;

@Before
public void before(){
            //notice that I had to use relative path because the file is not available in the test project
    MockServletContext mockServletContext = new MockServletContext("file:../<my web project name>/src/main/webapp"); 

    myService.setServletContext(mockServletContext);        
}

如果我有几个使用 Servlet Context 的类,那么更好的解决方案是使用WebApplicationContext而不是默认的(当前由 DelegatingSmartContextLoader 提供),但它需要实现自定义ContextLoader类并将其类名传递给@ContextConfiguration注释。

后来我想到的另一种更清洁的解决方案ServletContext是重构服务并注入 via@Autowired而不是弄乱ServletContextAware,并提供相应类型的 bean(实际上是一个MockServletContext实例)。

MockServletContext将来可能会在 Spring 中添加对来自测试类的直接支持,请参阅SPR-5399SPR-5243

SPRING 3.2 的更新 在 Spring 3.2 中,servlet 上下文的初始化变得像添加一个@WebAppConfiguration注释一样简单:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration("file:../<my web project name>/src/main/webapp")
@ContextConfiguration(locations = { "/test-ctx.xml" } ) 
public class SomeServiceTest {

详见文章

于 2012-05-18T08:53:35.867 回答
3

在一个 Maven 项目中,我遇到了同样的问题。我没有 servletContext,无法访问 WEB-INF 目录中的静态文件。我通过向 pom.xml 添加条目来找到解决方案,这使我可以访问该目录。它实际上包括这个类路径的路径。

PS:我使用的是Tomcat容器

<project>
    <build>
    <resources>
        <resource>
            <directory>src/main/webapp/WEB-INF</directory>
        </resource>
    </resources>
</project>
于 2014-07-22T09:33:38.073 回答
1

这是一个类路径资源,所以把它放在类路径上:$webapp/WEB-INF/classes

Maven 项目在打包 webapp 时会将 $module/src/main/resources 中的内容复制到此位置。(前者是一个源路径,后者 - WEB-INF/classes - 总是由 servlet 容器放在类路径中,根据规范。)

于 2012-05-18T23:37:20.553 回答