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 |
项目访问路径 |
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 |
低 | 生产和调试环境 |
五、总结
- 图片保存到独立目录:避免部署丢失
- Tomcat 用 context.xml:配置简单,生产环境推荐
- Jetty 用嵌入式配置:开发调试方便
- 代码层面适配路径:兼容不同部署路径
这样配置后,图片独立于项目存储,重新部署也不会丢失,同时支持 Tomcat 和 Jetty 两种环境。