转载自:Java Web开发图片存储方案:独立目录 + 容器配置

背景

在个人博客系统中,图片上传是一个常见需求。但将图片保存在项目 webapp 目录下,每次重新部署都会丢失。本文将介绍如何将图片保存到独立目录,并配置 Tomcat 和 Jetty 使其正常访问。

一、统一存储目录

无论使用哪个容器,图片都保存到同一个独立目录:

C:/db/oilyblog/uploads/images/

二、Tomcat 配置

2.1 创建 context.xml

src/main/webapp/META-INF/context.xml 中配置:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/oily-blog">
    <Resources>
        <PreResources base="C:/db/oilyblog/uploads"
                      className="org.apache.catalina.webresources.DirResourceSet"
                      webAppMount="/uploads" />
    </Resources>
</Context>

2.2 配置说明

属性说明
path/oily-blog项目访问路径
baseC:/db/oilyblog/uploads外部图片目录
webAppMount/uploads虚拟访问路径

2.3 访问效果

http://localhost:8080/oily-blog/uploads/images/xxx.png

三、Jetty 配置

3.1 方式一:Maven 插件配置

pom.xml 中配置 jetty-maven-plugin

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <version>9.4.44.v20210927</version>
    <configuration>
        <webApp>
            <contextPath>/oily-blog</contextPath>
            <resourceBases>
                <resourceBase>${project.basedir}/src/main/webapp</resourceBase>
                <!--这里目录最后不加/uploads-->
                <resourceBase>C:/db/oilyblog</resourceBase>
            </resourceBases>
        </webApp>
        <httpConnector>
            <port>8080</port>
        </httpConnector>
        <scanIntervalSeconds>5</scanIntervalSeconds>
    </configuration>
</plugin>

启动方式,运行 mvn jetty:run

3.2 方式二:嵌入式 Jetty 配置

BlogStart.java 中配置:

public class BlogStart {
    
    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);
        
        // 1. 配置静态资源处理器(外部图片目录)
        ResourceHandler resourceHandler = new ResourceHandler();
        resourceHandler.setDirectoriesListed(false);
        resourceHandler.setResourceBase("C:/db/oilyblog/uploads");
        
        //如果上下文为oily-blog
        //new ContextHandler("/oily-blog/uploads");
        ContextHandler uploadsContext = new ContextHandler("/uploads");
        uploadsContext.setHandler(resourceHandler);
        
        // 2. 配置动态请求处理器(JFinal)
        WebAppContext webapp = new WebAppContext();
        //如果上下文为oily-blog
        //new ContextHandler("/oily-blog");
        webapp.setContextPath("/");

        webapp.setResourceBase("src/main/webapp");
        webapp.setInitParameter("scanIntervalSeconds", "5");
        
        // 3. 组合处理器
        HandlerList handlers = new HandlerList();
        handlers.addHandler(uploadsContext);  // 先处理静态资源
        handlers.addHandler(webapp);          // 后处理动态请求
        
        server.setHandler(handlers);
        server.start();
        server.join();
    }
}

3.3 访问效果

http://localhost:8080/uploads/images/xxx.png

或者有上下文oily-blog

http://localhost:8080/oily-blog/uploads/images/xxx.png

四、方案对比

容器配置方式复杂度推荐
Tomcatcontext.xml生产环境
Jetty (嵌入式)代码配置方便IDE调试
Jetty (Maven插件)pom.xml生产和调试环境

五、总结

  1. 图片保存到独立目录:避免部署丢失
  2. Tomcat 用 context.xml:配置简单,生产环境推荐
  3. Jetty 用嵌入式配置:开发调试方便
  4. 代码层面适配路径:兼容不同部署路径

这样配置后,图片独立于项目存储,重新部署也不会丢失,同时支持 Tomcat 和 Jetty 两种环境。
文章来源 奥利顶, http://www.oily.top, Oily

更多推荐