71638

Hosting a single page application with spring boot

Question:

So I am trying to host a Single Page Application alongside a normal REST API with spring.

What this means is that all requests that goes to the normal /api/ endpoints should be handled by the respective controller and all other requests should be directed to the resources in the folder /static/built

I have gotten this to work by catching all NoHandlerFoundExceptions and redirecting to either the js file or the html file. And then used a WebMvcConfigurer to map the static content.

But this all seems like a hack to me, so is there a less hacky way of doing it?

Answer1:

The easiest way I get my SPAs to work with a Spring backend API is to have 2 different controllers: one for the root index page of the SPA and the other controller is used to manage various RESTful API endpoints:

Here are my two controllers:

MainController.java

@Controller public class MainController { @RequestMapping(value = "/") public String index() { return "index"; } }

MonitoringController.java

@RestController @RequestMapping(value = "api") public class MonitoringEndpoints { @GetMapping(path = "/health", produces = "application/hal+json") public ResponseEntity<?> checkHealth() throws Exception { HealthBean healthBean = new HealthBean(); healthBean.setStatus("UP"); return ResponseEntity.ok(healthBean); } }

Notice how the API endpoint controller utilizes the '@RestConroller' annotation while the main controller utilizes the '@Conroller' annotation. This is because of how Thymeleaf utilizes it's ViewResolver. See:

<a href="https://stackoverflow.com/questions/40765007/spring-boot-mvc-not-returning-my-view/40765327#40765327" rel="nofollow">Spring Boot MVC, not returning my view</a>

Now go ahead and place your index.html page at src/main/resources/templates/index.html because Spring by default looks for your html pages within this location.

My index.html pages looks like this:

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head lang="en"> <meta charset="UTF-8"/> <title>EDP Monitoring Tool</title> </head> <body> <!-- Entry point to our ReactJS single page web application --> <div id="root"></div> <script type="text/javascript" src="built/bundle.js"></script> </body> </html>

Not sure how you're wiring up your frontend, whether that is a ReactJS app or something but I believe this information would be helpful for you. Let me know if I can answer additional questions for you.

In addition, if you're using Webpack, you can set up the entry point of your JS files via the webpack.config.js file under the entry key so like so:

entry: ['./src/main/js/index.js']

Answer2:

I think you're looking for the term URL Rewrite.

E.g. <a href="https://getpostcookie.com/blog/url-rewriting-for-beginners/" rel="nofollow">https://getpostcookie.com/blog/url-rewriting-for-beginners/</a>

Recommend

  • how to pass data after pop view controller in swift
  • How can I change the feign URL during the runtime?
  • Hosting a single page application with spring boot
  • JavaScript speechSynthesis.speak() without user activation is no longer allowed since M71
  • Is there an official MRSS xsd?
  • How do you add !important to a CSS-in-JS (JSS) class property?
  • How to use Tesseract.js in a React app
  • Capybara server & browser error with no trace on server
  • MySQLDataReader retrieving Null value problem in c#
  • Wordpress legatus theme slow loading
  • how to rename the images taken from camera through our app?
  • GWT Simple Drag and Drop for custom widgets
  • IOS - Facebook SDK fbDidLogin not called — initialize view controllers.
  • PHP: Need to close STDIN in order to read STDOUT?
  • Arraylist of strings into one comma separated string
  • Spotify cocoalibspotify offline status set to 1 but all tracks stuck at waiting
  • Pandas vs matplotlib datetime
  • How do I use libcurl to printf a remote FTP directory listing?
  • Multiplying polynomials/simplifying like terms
  • How to define something in JavaScript [closed]
  • Floating parent div grows to hypothetical width of floating child div
  • Neo4j…how to get a visual representation of my data?
  • Will this work on all screen sizes?
  • Send array to next viewcontroller iOs xcode [duplicate]
  • Bitrate JWplayer
  • Codeigniniter insert data through models and controller
  • Accessing Arguments, Workflow Variables from custom activities
  • PHP Permalinks.. how to change?
  • Spring Boot not autowiring @Repository
  • What does the “id” field in an Android “Google Play Music” broadcast intent correspond to?
  • ARKit code issue {unknown error -1=ffffffffffffffff error: Task failed with exit 1}