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

📅 2026-05-19 📁 技术分享 👁 71 次阅读

背景

在个人博客系统中,图片上传是一个常见需求。但将图片保存在项目 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 项目访问路径
base C:/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

四、方案对比

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

五、总结

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

这样配置后,图片独立于项目存储,重新部署也不会丢失,同时支持 Tomcat 和 Jetty 两种环境。