如何在Heroku用JavaSpark部署含静态文件的Web应用?静态文件无法访问
Hey there, let's tackle your problem step by step—your app works locally but breaks on Heroku when loading static files and connecting via WebSocket. Here's what's going wrong and how to fix it:
1. Static File Loading Failures: Root Causes & Fixes
The most common reason static files (HTML/CSS/JS) don't load on Heroku is either incorrect packaging of your resources or misconfigured file paths.
Check Your Project Structure & Packaging
- Make sure your
/publicdirectory lives in the classpath of your deployed app. For Maven/Gradle projects, this means placing it insidesrc/main/resources(both tools include this directory in the build by default). When you build your JAR/WAR, these files should be included in the root of the archive. - Verify the contents of your deployment package by running:
Look for entries likejar tf your-app.jar # For JAR files # Or for WAR files: unzip -l your-app.warpublic/index.htmlorpublic/css/style.css—if they're missing, double-check your build config isn't excluding these files (Maven'sresourcesplugin handles this by default, but it's worth confirming).
Adjust Static File Serving Configuration
If you're using Jetty (your code looks like Jetty's API), ensure the staticFileLocation points to the correct classpath path. If the shorthand isn't working, try explicitly configuring a resource handler:
port(getHerokuAssignedPort()); webSocketIdleTimeoutMillis(1000000000); // Explicitly set up static file handling ResourceHandler resourceHandler = new ResourceHandler(); resourceHandler.setResourceBase("classpath:/public/"); resourceHandler.setDirectoriesListed(false); // Optional: disable directory listing // Combine with WebSocket handler using a HandlerList HandlerList handlers = new HandlerList(); handlers.addHandler(resourceHandler); handlers.addHandler(new WebSocketHandler() { @Override public void configure(WebSocketServletFactory factory) { factory.register(WebSocketHandler.class); // Use your actual WebSocket endpoint class } }); server.setHandler(handlers); init();
2. WebSocket Connection Issues on Heroku
Heroku routes all traffic through a reverse proxy, so your client-side WebSocket code needs two key fixes:
Use the Correct Protocol & Port
- Heroku requires WebSocket connections to use
wss://(secure WebSocket) for HTTPS apps (the default for Heroku deployments). - Don't manually append the port—
location.hostautomatically includes the correct port if needed (Heroku uses standard ports 80 for HTTP and 443 for HTTPS).
Fix your websocketClient.js code to:
// Automatically switch between ws/wss based on the current page protocol const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; const webSocketUrl = `${wsProtocol}//${window.location.host}/em/`; const webSocket = new WebSocket(webSocketUrl); // Add debug logs to diagnose connection issues webSocket.onopen = () => console.log("WebSocket connected successfully!"); webSocket.onerror = (error) => console.error("WebSocket connection error:", error); webSocket.onclose = (event) => console.log("WebSocket closed:", event.code, event.reason);
3. Debug with Heroku Logs
If you're still stuck, check Heroku's logs for specific error messages. Run this command in your terminal:
heroku logs --tail
Look for lines like File not found (points to missing static files) or WebSocket upgrade failed (indicates proxy/configuration issues). These logs will give you precise clues to troubleshoot further.
Final Testing Steps
- Deploy your updated code to Heroku:
git push heroku main - Try accessing a static file directly (e.g.,
https://your-app-name.herokuapp.com/index.html) to confirm it loads. - Check your browser's developer console (Network tab) to verify static files return 200 OK and WebSocket connections establish successfully.
内容的提问来源于stack exchange,提问作者Amutheezan

