Spring Boot Jar包部署下如何写入resources/static目录并支持浏览器访问
Oh, I totally get this pain point—switching from WAR to JAR deployments throws a lot of folks off when it comes to writing files that need to be browser-accessible. Let me walk you through why your old method isn't working anymore, and the straightforward fix.
Why Your Old getRealPath() Trick Fails for JARs
When you deployed a WAR, the webapp directory got unpacked into a real, writable folder on your server's filesystem. That's why request.getServletContext().getRealPath("cost.xlsx") worked—it pointed to an actual file you could write to.
But with a JAR? Everything in src/main/resources (including your static folder) is packed inside the JAR archive itself. JARs are read-only at runtime—you can't modify or write files to the archive while the app is running. Any attempt to write to that resources/static path will either throw an error or silently fail, because it doesn't exist as a physical directory.
The Proper Solution: Use an External Directory
The standard approach here is to store your writable static files in a physical folder outside the JAR, then configure your app to serve files from that folder as static resources. Here's how to do it step-by-step:
1. Pick an External Directory
Choose a path on your server where your app has read/write permissions. Examples:
- Linux:
/opt/my-app/static-files - Windows:
C:\my-app\static-files - Portable relative path (uses the folder where you run the JAR):
System.getProperty("user.dir") + "/static-files"
2. Configure Static Resource Mapping
If you're using Spring Boot (the most common way to deploy JARs), you have two easy options:
Option A: Use application.properties
Add this line to your config file to tell Spring to serve files from both your built-in read-only static folder and the external directory:
spring.web.resources.static-locations=classpath:/static/,file:/opt/my-app/static-files/
Option B: Code-Based Configuration
Create a config class to map a URL path to your external folder:
@Configuration public class StaticResourceConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // Map the URL path /static/** to our external directory registry.addResourceHandler("/static/**") .addResourceLocations("file:/opt/my-app/static-files/") // Optional: Set cache time for static files (in seconds) .setCachePeriod(3600); } }
3. Write Files to the External Directory
Instead of relying on getRealPath(), write directly to your external folder. For example:
// Define the path to our external static files folder String externalStaticDir = "/opt/my-app/static-files/"; File excelFile = new File(externalStaticDir + "cost.xlsx"); // Write your Excel content to excelFile here (using Apache POI, etc.)
4. Access the File via Browser
Once the file is written, you can access it at http://your-server-url/static/cost.xlsx (matching the URL path you set in the resource handler).
Key Notes to Avoid Headaches
- Permissions: Make sure the user running your JAR has read/write access to the external directory. On Linux, you might need to run
chown your-user:your-group /opt/my-app/static-filesto set this up. - Portability: If you use the relative
user.dirpath, the folder will be created wherever you run the JAR—just keep that in mind for different environments (dev vs prod). - Never Write to the JAR: Modifying files inside the JAR at runtime isn't supported, and any changes will be lost when you redeploy or restart the app. Stick to external directories for writable content.
内容的提问来源于stack exchange,提问作者小铭牌

