Java  

Using WebForms Core in Java (Spring Boot)

Introduction

WebForms Core is a modern server-driven web technology that allows developers to control client-side behavior directly from the server without relying on heavy front-end frameworks such as React, Angular, or Vue. Instead of writing complex JavaScript logic, developers define UI behavior using server-side commands that are executed in the browser by a lightweight JavaScript executor.

After the release of WebForms Core version 2 for multiple programming languages, Java developers can now use this technology seamlessly with Spring Boot (or other back-end frameworks in Java), benefiting from strong typing, clean architecture, and server-side control over the DOM.

In this article, we will explore how to use WebForms Core v2 with Java (Spring Boot) by demonstrating:

  • Dynamic HTML template loading

  • Server-side DOM injection

  • Placeholder replacement

  • Fetch-based content manipulation

  • Event-driven UI updates without page reloads

Prerequisites

This article is written and tested using the latest stable versions of the following tools:

  • JDK 21 (or latest LTS)

  • Spring Boot 3.x

  • Maven or Gradle

  • WebForms Core v2 (Java Commander)

  • WebFormsJS (Executor)

The provided code is fully compatible with the latest Java and Spring Boot releases.

Before starting, make sure you have:

  • A working Spring Boot project

  • Static file support enabled

  • The WebForms Core Java classes added to your project

  • The WebFormsJS script available to the client

WebForms Core Architecture Overview

WebForms Core is based on the Commander–Executor pattern:

Commander (Server Side – Java)

The "WebForms" Java class acts as the Commander , responsible for:

  • Generating commands

  • Managing DOM updates

  • Handling events

  • Loading external HTML or JavaScript resources

Download the WebForms class according to your desired programming language from the following link:

https://github.com/webforms-core/Web_forms_classes

Executor (Client Side – JavaScript)

The Executor is a JavaScript module called WebFormsJS whose only responsibility is to:

  • Read WebForms commands

  • Execute them in the browser

  • Apply DOM changes and event bindings

This separation allows Java developers to control UI behavior entirely from the server.

Download WebFormsJS from the following link:

https://github.com/webforms-core/Web_forms

Project Structure Overview

src/
 ├─ main/
 │   ├─ java/
 │   │   ├─ com.example.demo/
 │   │   │   ├─ DemoApplication.java
 │   │   │   └─ MyController.java
 │   │   └─ WebFormsCore/
 │   │       ├─ WebForms.java
 │   │       ├─ Fetch.java
 │   │       ├─ HtmlEvent.java
 │   │       ├─ HtmlEventListener.java
 │   │       ├─ InputPlace.java
 │   │       ├─ OutputPlace.java
 │   │       ├─ ExtensionWebFormsMethods.java
 │   │       ├─ Security.java
 │   │       └─ WasmLanguage.java
 │   ├─ resources/
 │   │   ├─ templates/
 │   │   │   └─ default.html
 │   │   └─ static/
 │   │       ├─ script/
 │   │       │   └─ web-forms.js
 │   │       └─ api/
 │   │           └─ template.html

The WebForms class in Java (due to the limitations and structure of the Java language) is provided separately from the auxiliary classes, unlike other WebForms classes in other programming languages; therefore, the WebFormsCore folder and its classes must be added to the "src/main/java" path.

HTML Templates (Reusable UI Blocks)

"/api/template.html"

This file contains reusable HTML templates defined using the "<template>" tag

<!DOCTYPE html>
<template id="Article">
    <section>
        <h2>@ArticleTitle</h2>
        <p>@ArticleText</p>
    </section>
</template>

<template id="Video">
    <section>
        <h2>@VideoTitle</h2>
        <video controls>
            <source data-src="@VideoPath" type="video/mp4">
            @VideoFallbackText
        </video>
    </section>
</template>

<template id="Link">
    <section>
        <h2>@LinksTitle</h2>
        <a href="@Link1Url">@Link1Text</a>
    </section>
</template>

Each template contains placeholders (e.g. "@VideoTitle") that will later be replaced dynamically by WebForms Core.

Main View (default.html)

<!DOCTYPE html>
<html>
<head>
  <title>Using WebForms Core</title>
  <script type="module" src="/script/web-forms.js"></script>
</head>
<body>
    <h1>Video Template Example</h1>
    <button>Click to show video</button>
</body>
</html>

<p th:utext="${WebForms}"></p>

The "th:utext" placeholder injects the WebForms command block generated by the server.

As is clear, in the head section, the script tag has been added with the path to the WebFormsJS module.

Controller: Initial Page Load

@GetMapping("/")
public String PageLoad(Model model) {

    WebForms form = new WebForms();

    form.setGetEvent("<button>", HtmlEvent.OnClick, "/set-video");

    model.addAttribute("WebForms", form.exportToHtmlComment());

    return "default";
}

What happens here?

  • A click event is attached to the "<button>"

  • Clicking the button sends a GET request to "/set-video"

  • No JavaScript code is written manually

  • The event logic is fully server-defined

Dynamic Template Injection (LoadHtml)

form.addText("<body>", Fetch.loadHtml("/api/template.html", "Video"));

Concept: Fetch.loadHtml

The "Fetch.loadHtml" command does not load the HTML file on the server . Instead, it generates a WebForms instruction that will be executed by the client in the browser.

Here’s what happens:

1- The server adds a command like:

[web-forms]
at<body>=@lh/api/template.html,0,Video
gt<body>|<section>-1=r|$[at];VideoTitle|My video|0|1
gt-=r|$[at];VideoPath|https://media.w3.org/2010/05/sintel/trailer.mp4|0|1
gt-=r|$[at];VideoFallbackText|Your browser doesn't support HTML5 video.|0|1
gt-=r|data-src|src|0|1

2. When the HTML page is loaded, WebFormsJS in the browser reads these commands.

3. WebFormsJS fetches "/api/template.html" from the static folder.

4. It extracts the "<template>" with ID Video and injects it into the "<body>" dynamically.

5. Placeholders such as "@VideoTitle", "@VideoPath", and "@VideoFallbackText" are replaced by the client according to the instructions.

This enables component-based UI composition entirely on the client side, while the server only generates the instructions. There is no server-side HTML fetching ; all fetching and DOM manipulation occur in the browser.

Placeholder Replacement (Replace)

form.replace("<body>|<section>-1", "@VideoTitle", "My video", false, true);
form.replace("-", "@VideoPath", "https://media.w3.org/2010/05/sintel/trailer.mp4", false, true);
form.replace("-", "@VideoFallbackText", "Your browser doesn't support HTML5 video.", false, true);

The replace method in WebForms Core instructs the client to replace placeholders in the DOM after the template is injected.

For example:

  • @VideoTitle → the video title

  • @VideoPath → the video source URL

  • @VideoFallbackText → fallback message

All replacements occur on the client side , dynamically updating the DOM without reloading the page .

The image below shows the output of the HTML page. The part highlighted in red is created after clicking the button.

video_template_example

Attribute Manipulation (Advanced replace)

WebForms Core allows dynamic attribute replacement on the client. For example:

form.replace("-", "data-src", "src", false, true);

This converts:

<source data-src="...">

into:

<source src="...">

Why this is useful:

  • Lazy loading – the resource is loaded only when needed

  • Deferred attribute activation – you can control the exact timing of loading

  • Dynamic attribute control – change attributes without triggering immediate browser requests

Note: Using "data-src" prevents the browser from immediately fetching the resource before WebFormsJS executes all template injections and placeholder replacements, improving performance and reducing unnecessary network requests.

Full Server Response (set-video)

@GetMapping("/set-video")
public ResponseEntity<String> PageLoad() {

    WebForms form = new WebForms();

    form.addText("<body>", Fetch.loadHtml("/api/template.html", "Video"));

    form.replace("<body>|<section>-1", "@VideoTitle", "My video", false, true);
    form.replace("-", "@VideoPath", "https://media.w3.org/2010/05/sintel/trailer.mp4", false, true);
    form.replace("-", "@VideoFallbackText", "Your browser doesn't support HTML5 video.", false, true);
    form.replace("-", "data-src", "src", false, true);

    return ResponseEntity.ok(form.response());
}

Only WebForms commands are sent to the client — not the entire HTML page .

Result

The page loads instantly.

Clicking the button sends WebForms instructions to the client , which dynamically inject a video section.

No custom JavaScript logic is written by the developer ; WebFormsJS handles execution.

No page reload occurs .

The UI is fully controlled via WebForms instructions from Java , but all DOM manipulation happens in the browser .

Conclusion

WebForms Core v2 for Java provides a structured way to define client-side UI behavior entirely through server-generated instructions. By combining concepts such as HTML template instructions ("Fetch.loadHtml"), client-side placeholder replacement ("replace"), and command-based events, developers can build interactive web applications without writing any manual JavaScript.

Features like "Fetch.loadHtml", "replace", and server-driven events keep Spring Boot applications clean, maintainable, and focused on business logic, while allowing the client to handle all DOM updates efficiently. This approach is especially suitable for form-based systems, dashboards, and applications where UI behavior is tightly coupled with server-side rules.

WebForms Core is designed as an alternative to modern front-end frameworks, allowing developers to efficiently control and update client-side behavior from a stateless server, while still providing a stateful-like and enjoyable experience for developers.