如何从引用java项目访问静态资源(WEB-INF)文件夹中的文件?

时间:2012-05-17 15:31:25

标签: java spring java-ee maven pom.xml

我有一个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项目。

4 个答案:

答案 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-5399SPR-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容器放在类路径上。)

相关问题