ZK Framework

repository·master·Indexed 19 days ago

https://github.com/zkoss/zk

A server-centric Java framework for building enterprise-grade web and mobile applications. ZK utilizes a 'Ajax without JavaScript' approach where UI elements are represented as POJO components on the server, and ZUML (ZK User Interface Markup Language) for declarative UI design. The framework supports MVVM patterns, data binding, and provides tools for TypeScript integration via zk-types, dependency management through zk-bom for Maven and Gradle, and various build and deployment utilities for Tomcat.

Tokens
18.6K
Snippets
53
Records
91
Agent score
67%

What's inside ZK

  1. What is ZK and when should you use it?

    master

    ZK is a Java framework designed for building enterprise web and mobile applications. It is particularly suited for:

    • Backend-heavy Java projects: Ideal when the development team has minimal frontend (JavaScript/HTML) expertise.
    • Enterprise applications: When long-term stability is a requirement.
    • Data-intensive UIs: For applications requiring complex user interactions and heavy data handling.
    • Rapid Prototyping: For quickly building internal tools.
  2. Overview of the zweb library

    master
    The zweb library provides fundamental utilities for developing web applications. It is designed to be highly portable and standard-compliant, assuming only standard Servlet, JSP, Portlet, JSF, and JSTL environments. Unlike other parts of the ZK ecosystem, zweb is not strictly framework-oriented and does not depend on i3pb, i3po, or i3lb, making its code easily adaptable to other projects with minimal modification.
  3. What is ZK and how does it work?

    master

    ZK is a Java framework designed for building enterprise web and mobile applications using a "Simply Java" approach. It follows an "Ajax without JavaScript" model where the complexity of asynchronous communication is handled transparently by the framework.

    Core Mental Model

    • Server-Side Component Model: User interface components rendered in the browser are represented on the server as Plain Old Java Objects (POJOs). When you modify these POJOs in your Java code, the changes are automatically reflected on the client.
    • Event Marshalling: User-triggered events in the browser are encapsulated and marshalled to event listeners running on the server.
    • Pitcher and Catcher Engine: The ZK client engine and update engine manage the Ajax communication, making the interaction between the client and server transparent to the developer.
    • Server+Client Fusion: While the framework is server-centric (providing robustness and security via Java), it allows developers to interact with jQuery-based widgets on the client side to enhance user experience and leverage client-side resources.
  4. Understanding ZK User Interface Markup Language (ZUML)

    master

    ZUML is a declarative language used to design rich user interfaces. It is a variant of XUL that inherits XML features.

    Key Features

    • Separation of Concerns: ZUML separates the UI definition from the runtime logic.
    • Declarative UI: Designing interfaces is as simple as authoring HTML-like markup.
    • Data Automation: ZUML supports automating CRUD operations between UI components and data sources using annotations, data binding, and the MVVM (Model-View-ViewModel) pattern.
  5. How ZK's 'Ajax without JavaScript' works

    master

    ZK uses a server-centric approach to Ajax, often described as "Ajax without JavaScript."

    Core Mechanism

    • Component Surrogates: Every UI element rendered in the browser is represented on the server as a Plain Old Java Object (POJO) component.
    • Event Marshalling: User events triggered in the browser are encapsulated and marshalled to event listeners running on the server.
    • Transparent Updates: When you modify a POJO component on the server, the changes are automatically reflected on the client via a client/update engine (acting as 'pitcher and catcher') without requiring the developer to write manual Ajax or JavaScript code.
    • Java Integration: Because logic executes on the server, you can directly leverage Java EE, Spring, and existing backend services.
  6. ZK Composer Lifecycle and Component Behavior

    master

    A ZK Composer is stored as an attribute on the component object it is applied to. Its lifecycle is tied to that component:

    ZK EventComposer Behavior
    Page first loadedNew Composer created and bound to the component
    AJAX request on same pageSame Composer reused (already on the component)
    Full page reload / navigationComponent destroyed $\rightarrow$ Composer garbage-collected
    Component re-created (via Executions.createComponents())New Composer created
    Component detached then re-attached (same object)Composer unchanged (it travels with the component object)
  7. Configure Spring Scope for ZK Composers

    master

    When using Spring beans as ZK Composers, you must use scope="prototype".

    ZK Composers are inherently component-scoped; they live and die with the ZK component they are attached to. If you use the default Spring Singleton scope, the same Composer instance will be shared across all users, all desktops, and all components. This leads to severe data races and security leaks where one user's state is visible to another.

    Recommendation Summary:

    • FQCN (apply="com.example.MyComposer"): Safe. Use when no Spring DI is needed.
    • Spring Prototype (apply="${myComposer}" with scope="prototype"): Safe. Use when Spring DI is required.
    • Spring Singleton (apply="${myComposer}" with default scope): NEVER USE.
  8. Use a Spring Bean as a ZK Composer

    master

    You can delegate a ZK Composer's instantiation to the Spring container by using the DelegatingVariableResolver. This allows Spring to manage the Composer's dependencies via Dependency Injection (DI).

    To implement this, first declare the DelegatingVariableResolver in your ZUL file, then use an EL expression in the apply attribute of a component to reference your Spring bean name.

    <?xml version="1.0"?>
    <zk>
        <?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
        <div apply="${myComposer}">
            <!-- Component content -->
        </div>
    </zk>
  9. Set up TypeScript declarations for the ZK Framework

    master

    To get type safety and autocompletion for the ZK Framework in a TypeScript project, install the zk-types package as a development dependency and configure your tsconfig.json to include it in the types array.

    1. Install dependencies: npm i -D typescript zk-types
    2. Initialize TypeScript (if not already done): npx tsc --init
    3. Update tsconfig.json to include zk-types in compilerOptions.types.
    npm i -D typescript zk-types
    npx tsc --init
  10. Configure ZK library distribution for Web applications

    master

    When packaging your Web application, you must decide how to distribute the ZK libraries based on your server configuration:

    1. Embedded Libraries: If you want to include all ZK libraries directly within your Web application (e.g., inside your .war file), copy war.libs.all to war.libs.
    2. Shared Server Libraries: If you have already installed the ZK libraries into the shared directory of your Web server, use the minimal set by copying war.libs.minimal to war.libs.
    # To embed ZK libraries into your Web application:
    cp war.libs.all war.libs
    
    # To use ZK libraries installed in the Web server's shared directory:
    cp war.libs.minimal war.libs
  11. Use zk-bom to manage ZK dependencies in Maven

    master

    To ensure version consistency across all ZK modules, add the zk-bom to your pom.xml within the <dependencyManagement> section. This allows you to omit version numbers when declaring individual ZK dependencies, as the BOM will provide the correct versions automatically. Replace x.y.z with the specific version of the BOM you wish to use.

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.zkoss.zk</groupId>
                <artifactId>zk-bom</artifactId>
                <version>x.y.z</version><!-- replace with the actual version -->
                <type>pom</type>
                <scope>import</scope>
            </dependency>   
        </dependencies>
    </dependencyManagement>