我有一个Web应用程序,它包含一个配置xml文件,用于我的一个作为spring bean公开的应用程序服务。 此外,我在同一个工作区中有一个独立的java应用程序(它从pom.xml引用我的web应用程序项目),它使用Spring TestContext框架运行测试,其中一个测试检查该XML文件的配置。
但是我从独立应用程序访问此xml文件时遇到问题:
在设置测试之前,在我以前的配置中,该文件是通过ServletContext访问的,位于 WEB-INF / 文件夹中。但是,为了使其可以从测试项目访问,我必须将其移动到 source / 文件夹并使用getClassLoader()。getResourceAsStream()方法加载它而不是ServletContext。但它使编辑文件变得很麻烦,因为每次都必须重新部署应用程序。
是否可以将文件保存在 WEB-INF / 文件夹中,但是在测试运行期间从引用项目中加载它?
P.S。目前,它是一个带有Tomcat服务器的STS项目。
答案 0 :(得分: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()方法。
答案 1 :(得分:2)
我最终使用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
注入@Autowired
而不是弄乱ServletContextAware
,提供相应类型的bean(实际上是一个MockServletContext
实例)。
可能以后,测试类中 MockServletContext
的直接支持将添加到Spring,请参阅SPR-5399和SPR-5243。
更新春季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 {
请参阅the article
中的详细信息答案 2 :(得分:2)
在Maven项目中我遇到了同样的问题。我没有servletContext,也无法访问静态文件 WEB-INF目录。 我通过在pom.xml中添加条目来访问该目录,从而找到了解决方案。它实际上包含了这个到类路径的路径。
PS:我使用的是Tomcat容器
<project>
<build>
<resources>
<resource>
<directory>src/main/webapp/WEB-INF</directory>
</resource>
</resources>
</project>
答案 3 :(得分:1)
这是一个类路径资源,所以把它放在类路径上:$ webapp / WEB-INF / classes
在打包webapp时,Maven项目会将$ module / src / main / resources中的内容复制到此位置。 (前者是一个源路径,后者 - WEB-INF / classes - 总是按照规范由servlet容器放在类路径上。)