Java 在春季访问webapp文件夹中的文件/目录

Java 在春季访问webapp文件夹中的文件/目录,java,spring,spring-mvc,Java,Spring,Spring Mvc,我在Spring方面缺乏经验,现在我需要做的一切就是访问并获取对webapp文件夹中的文件和文件夹的引用。以下是我的相关项目层次结构: -src --main ---java (marked as source root) ----my -----package ------controller -------Home.java ---webapp ----images -----avatars Home.java中的我的代码: @Controller @RequestMapping("/")

我在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://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <display-name>Test</display-name>

    <servlet>
        <servlet-name>test</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>test</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <session-config>
        <session-timeout>10</session-timeout>
    </session-config>
</web-app>
对我来说,它看起来很脏,对于生产服务器来说这是个好主意吗?有更好的解决方案吗?

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

关于web资源的位置,存储在src/main/resources中的资源将部署在web-INF/classes文件夹中,因此这显然是不可能的。改为使用webapp

更新:现在我知道你来自哪里了。我看不出地图有什么问题,尽管它非常奇特。
DispatcherServlet
映射可能不包括
图像
文件夹(即它不是
/*

对于与文件打开相关的内容,
webapp
目录在类加载器中不可见,只有
WEB-INF
文件夹除外。因此,您需要调用
HttpServletRequest.getRealPath()
方法才能获得映像的实际路径


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

请参阅Spring参考资料一节中的使用
。我在JavaScript/CSS/图像中使用了这种方法,效果非常好——我只需在
应用程序context.xml
文件中添加一行代码。文件规定:

这提供了一种方便的方式,从 web应用程序根目录以外的位置,包括上的位置 类路径


这是我的代码,它是有效的 我没有得到零

我正在运行JDK1.7_02 Tomcat 7.0.25 春季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";
        }
    }
您可以尝试以下方法:

@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("/");
       //...
    }
}

您到底是如何部署应用程序的

ServletContext().getRealPath(“/”)
如果未按分解方式部署,则可能返回null。阅读下面的链接了解更多信息。但是,对于servlet容器,配置它的方法可能不同

更新

有人能告诉我,把战争部署成军事行动有什么区别吗 爆炸

当您以分解方式部署war文件时,servlet容器(例如Tomcat)将把war文件的内容提取到一个临时文件夹中,并从该文件夹运行所有内容,因此文件系统(硬盘)上实际上存在
{WEB\u ROOT]/\u images/avatars/[myid].jpg
。因此,您实际上可以获得真正的路径但是,如果您的servlet容器没有提取war文件,那么您要查找的文件夹位于war文件中,并且没有指向该文件的实际路径,因此它将返回
null

是否不建议在生产服务器上执行此操作? 优点/缺点

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

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

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


由于您将提供一个REST接口来调整图像大小,因此您可以创建一个控制器,该控制器从dynamic content文件夹中读取原始图像,进行调整大小,将其保存为临时文件,或者刷新
HttpResponse

考虑到文件的位置,您应该查看Spring,例如e这是:

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;
    }
}

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

谢谢您的回答。我现在将所有CSS/JS/images文件和文件夹移动到webapp文件夹中。现在images文件夹位于src/main/webapp/images,我如何从代码中引用它?它不在类路径中,对吗?您能透露多一点abo吗但是您到底想要完成什么?@AlessandroSantini Minor注意:
HttpServletRequest.getRealPath()
不推荐使用。
ServletContext.getRealPath()
应该使用。谢谢你们两位。不幸的是,request.getSession().getServletContext().getRealPath(“图像”)返回空对象。我尝试在前后添加斜杠“图像"还有……如果你能为其他用户的利益发布解决方案,那就太好了。我关心目录是否存在。你想如何处理这些文件,只需将它们返回到客户端,或处理其内容?我已经尝试了你的代码,它可以工作。你能告诉我们如何测试它吗?你是否与Maven生成一个war并将其放入Tomcat中,还是直接从Eclipse执行它?谢谢,这解决了问题。你能告诉我将战争部署为爆炸式的有什么区别吗?这是不建议在生产服务器上执行的吗?优点/缺点?谢谢,@gigadot。我在谷歌上搜索了你建议的解决方案,但找不到解决方案
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;
    }
}