This sample repository demonstrates the server-side rendering of an java spring application using the corresponding adaptor.
npm install # Install js dependencies
./mvnw spring-boot:run # Start serverThe application should now be running on localhost:8080.
This sample project is based on Spring Initializr.
The interesting parts is the views in src/jsx and the
SampleController class,
the controller that renders the views in response to HTTP requests.
The Spring controller resolves JSX views from a bundeled javascript file under
the path templates/complate/bundle.js.
The request handler returns the view and model at once as a ModelAndView
object.
@GetMapping("/")
public ModelAndView index() {
return new ModelAndView("Person")
.addObject("age", 99)
.addObject("name", "John Doe");
}The Spring framework takes care of rendering the JSX views using the
configured
ComplateViewResolver, imported from the
spring complate adaptor.
This sample project specifies two mapping functions with their corresponding
views, a "person view" corresponding to / and a "bootstrap view"
corresponding to /bootstrap.
The JSX views themselves exist in src/jsx and is bundled together by
faucet using npm run compile. The faucet
example configuration in this project shows how to configure
faucet to generate a javascript file compatible with the Nashorn Scripting
Engine, which the ComplateViewResolver uses internally.
The entry level file for faucet is index.js and the only relevant function to
the backend is render. This endpoint requires three arguments: stream which
is a writable stream corresponding to response of the spring application, tag
which is the name of the view to render (the viewName argument) in the
ModelAndView constructor, and params which is the view parameters (the
model argument in the Modelandview constructor.
export default function render(view, params, stream) {
renderer.renderView(view, params, stream);
}The render function uses a renderer from the
complate-stream library, the
component that actually renders the HTML. In order for this to work, the defined
views have first to be registred using the same renderer.
import Renderer from "complate-stream";
import Person from "./person";
import BootstrapSample from "./bootstrap-sample";
let renderer = new Renderer("<!DOCTYPE html>");
[Person, BootstrapSample].forEach(view => {
renderer.registerView(view);
});