在Spring中访问webapp文件夹中的文件/目录

我在Spring方面缺乏经验,现在我需要做的就是访问并获取webapp文件夹中文件和文件夹的引用。 这是我的相关项目层次结构:

-src --main ---java (marked as source root) ----my -----package ------controller -------Home.java ---webapp ----images -----avatars 

我在Home.java中的代码:

 @Controller @RequestMapping("/") public class Home { @RequestMapping(method = RequestMethod.GET) public String index(Model model, HttpServletRequest request) throws Exception { String test1 = request.getSession().getServletContext().getRealPath(""); String test2 = request.getSession().getServletContext().getRealPath("/"); String test3 = request.getRealPath(""); String test4 = request.getRealPath("/"); String test5 = request.getSession().getServletContext().getRealPath(request.getServletPath()); return "index"; } } 

所有5个请求都返回null。 难道我做错了什么?

web.xml中:

 <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://sofzh.miximages.com/java/index.html文件夹。 是否建议将图片上传到webapp文件夹? 或者有更好的解决方案吗? 我希望能够在访问URL /images/[width]x[height]/[userid].jpg时返回图像的缩放实例。 

在展开部署WAR并实现ResourceLoaderAware (感谢@KevinSchmidt),我可以使用它来使其工作:

 resourceLoader.getResource("file:" + request.getSession().getServletContext().getRealPath("/") + "_images/avatars/"); 

对我来说它看起来很脏,对生产服务器来说是个好主意吗? 有更好的解决方案吗?

您是如何部署应用程序的?

ServletContext().getRealPath("/")如果未部署为已爆炸,则可能返回null。 请阅读以下链接以获取更多信息。 但是,配置它的方法可能与servlet容器不同。

http://ananthkannan.blogspot.com/2009/12/servletcontextgetrealpath-returns-null.html

更新

有人能告诉我部署WAR的区别是什么?

当您将war文件部署为展开时,servlet容器(例如Tomcat)会将war文件的内容提取到临时文件夹中并运行该文件夹中的所有内容,因此{WEB_ROOT]/_images/avatars/[myid].jpg实际上是存在于文件系统(硬盘)上。 因此,您实际上可以获得真实路径(正如它已经在方法的名称中所述)。 但是,如果您的servlet容器没有提取war文件,那么您要查找的文件夹位于war文件中,并且没有真正的路径,因此它将返回null

是不是建议在生产服务器上做什么? 优点缺点?

您不应将动态内容存储在源文件夹或webroot文件夹(webapp)下,因为servlet容器将临时使用它并删除它或在重新部署Web应用程序时更改为新文件夹。 您可能会丢失放入这些文件夹的动态数据。 Web根文件夹通常用于存储静态内容,这意味着您不想更改的内容 – 例如,Web组件的图形图像,如背景图像,CSS等。

存储用户数据的常用方法是以某种方式在用户空间中创建一个文件夹并将动态数据放在那里。 但是,您将无法提供webroot外部文件夹的内容。 在请求数据时,您需要编写自己的静态servlet来管道数据。 这对初学者来说非常复杂。

实现自己的静态servlet以提供动态内容的最简单方法是扩展servlet容器的静态servlet。 但是,您的代码将高度依赖于要部署到的servlet容器。

由于您要提供用于调整图像大小的REST接口,因此您可以创建一个控制器,该控制器从动态内容文件夹中读取原始图像,进行大小调整,将其另存为临时文件或刷新HttpResponse的内容。

考虑到文件的位置,您应该查看Spring ResourceLoader ,如下所示:

 public class ArbitraryResourceLoader implements ResourceLoaderAware { private ResourceLoader resourceLoader; public void test() { Resource resource = resourceLoader.getResource("file:webapp/images/avatars/avatar.jpg"); } @Override public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } } 

请注意,您的容器需要具有访问该文件的权限。

这是我的代码,它的工作原理我没有得到null。

我正在运行JDK 1.7_02 Tomcat 7.0.25 Spring 3.1.1

而且我没有得到空值

  @Controller public class IndexController { @RequestMapping("/index") public String go(HttpServletRequest request, HttpServletResponse response) { HttpSession session = request.getSession(); ServletContext sc = session.getServletContext(); String x = sc.getRealPath("/"); System.out.println(x); return "index"; } } 

ClassPathResource可能会有所帮助。 如果完全错误的话,你在类路径中访问资源的方式。

对于Web资源的位置而言,存储在src / main / resources中的那些资源将部署在WEB-INF / classes文件夹中,因此显然不行。 用户webapp而不是。

更新:现在我看到你来自哪里。 我没有看到映射有什么问题,虽然极具异国情调。 有可能DispatcherServlet映射不包含images文件夹(即它不是/* )。

对于File打开的问题, webapp目录在类加载器中是不可见的,除了WEB-INF文件夹。 因此,您需要调用HttpServletRequest.getRealPath()方法以获取图像的真实路径。

请注意,虽然不太可能是您的情况,但是强化的Java JVM(即具有安全策略的JVM)可能需要额外的授权才能让servlet从任意位置打开文件。

请参阅Spring参考中的 ,第16.14.5节“ 配置资源服务” 。 我将此方法用于我的JavaScript / CSS /图像,它工作得很好 – 我只需要在application-context.xml文件中添加一行。 文件说明:

这提供了一种方便的方法来从Web应用程序根目录以外的位置提供静态资源,包括类路径上的位置。

你可以试试这个:

 @Controller @RequestMapping("/") public class Home implements ServletContextAware { private ServletContext servletContext; public void setServletContext(ServletContext servletCtx){ this.servletContext=servletCtx; } @RequestMapping(method=RequestMethod.GET) public String index(Model model,HttpServletRequest) throws Exception{ String rootPath = servletContext.getRealPath("/"); //... } }