部署Spring Boot 2 + React项目至Heroku时遭遇404错误及Rest Controller失效问题求助
Let’s dig into why your custom Spring Boot + React app is throwing 404s on Heroku, especially since the tutorial projects work fine. The key here is that local development (separate React and Spring Boot servers) behaves differently than production (Spring Boot serving React’s static files)—so the problem is almost certainly in your deployment configuration.
1. First: Verify React’s Build Output Is Being Packaged with Spring Boot
When you deploy to Heroku, Spring Boot needs to serve React’s static files (HTML, CSS, JS) directly. If these files aren’t in the right place in your final war/jar, you’ll get a 404 for the root path.
- Check your
pom.xml’s frontend plugin: Make sure thefrontend-maven-plugin(or whatever plugin you’re using) is configured to runyarn build(ornpm run build) during the Mavenpackagephase, and copy the resultingbuilddirectory into Spring Boot’s static resource folder (usuallytarget/classes/static).- Look for configuration like this in your pom.xml:
<plugin> <groupId>com.github.eirslett</groupId> <artifactId>frontend-maven-plugin</artifactId> <!-- ... other config ... --> <executions> <execution> <id>install node and yarn</id> <goals><goal>install-node-and-yarn</goal></goals> </execution> <execution> <id>yarn install</id> <goals><goal>yarn</goal></goals> </execution> <execution> <id>yarn build</id> <goals><goal>yarn</goal></goals> <configuration> <arguments>build</arguments> </configuration> </execution> <execution> <id>copy react build to static</id> <phase>process-resources</phase> <goals><goal>copy-resources</goal></goals> <configuration> <outputDirectory>${project.build.outputDirectory}/static</outputDirectory> <resources> <resource> <directory>${project.basedir}/frontend/build</directory> <filtering>false</filtering> </resource> </resources> </configuration> </execution> </executions> </plugin>
- Look for configuration like this in your pom.xml:
- Check Heroku’s build logs: Look for lines indicating
yarn buildran successfully, and that the build files were copied to the static folder. If you don’t see these steps, your Maven build isn’t triggering the React build—fix that first.
2. Validate Your Procfile Configuration
Your Procfile tells Heroku how to start your app. A common mistake here is pointing to the wrong package file:
- Confirm your
pom.xmlsets the packaging type correctly (<packaging>war</packaging>or<packaging>jar</packaging>). If you’re building a jar, your Procfile should reference the jar file, not war. - Double-check the filename in your Procfile matches the actual output in the
targetdirectory. For example, if your pom usesshmot-0.0.1-SNAPSHOTas the artifact ID/version, make sure that exact war/jar exists after building. - Pro tip: If you’re using Spring Boot, you can actually omit the Procfile entirely—Heroku’s buildpack will automatically detect and run the jar/war. Try removing it to rule out Procfile typos.
3. Fix Client-Side Routing Conflicts (If You’re Using React Router)
If your React app uses BrowserRouter, direct requests to routes like /dashboard will trigger a 404 on Heroku because Spring Boot tries to find a matching Controller instead of serving React’s index.html.
Add a fallback Controller to your Spring Boot app to handle all non-API requests:
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; @Controller public class ReactFallbackController { // Match all paths that don't end with a file extension (e.g., .js, .css) @GetMapping(value = "/**/{path:[^.]*}") public String forwardToReact() { return "forward:/index.html"; } }
This ensures any request that isn’t an API endpoint gets forwarded to React’s entry point, fixing 404s on route refreshes.
4. Test the Production Build Locally First
Before deploying to Heroku, simulate the production environment locally to catch issues early:
- Run
mvn clean packageto build the full war/jar. - Start the app with
java -jar target/<your-package-file>.war(or jar). - Visit
http://localhost:8080in your browser.- If you get a 404 here, the problem is in your build configuration (not Heroku). Check if the
staticfolder in the war/jar contains React’s build files. - Test your Rest Controllers directly (e.g., with Postman or curl) to confirm they’re reachable. If they work locally but not on Heroku, check Heroku’s app logs for errors like port conflicts or missing environment variables.
- If you get a 404 here, the problem is in your build configuration (not Heroku). Check if the
5. Dig Into Heroku’s App Logs
Heroku’s logs will tell you exactly what’s failing:
- Run
heroku logs --tailin your terminal to stream real-time logs. - Look for:
- Spring Boot startup errors (e.g., "Failed to start application context").
- 404 error details (which paths are failing? Root path? API paths?).
- Missing file errors (e.g., "Could not find static resource /index.html").
Final Checklist
- React’s
buildfolder is copied totarget/classes/staticduring Maven packaging. - Procfile points to the correct war/jar file (or is omitted for Spring Boot auto-detection).
- Fallback Controller is added if using React Router.
- Local production build works correctly before deploying to Heroku.
内容的提问来源于stack exchange,提问作者Igor Khilkevich

