DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Develop Web Application With Spring Boot in 30 minutes
  • How to Enable HTTPS on a Spring Boot Application
  • Actuator Enhancements: Spring Framework 6.2 and Spring Boot 3.4
  • How Spring Boot Starters Integrate With Your Project

Trending

  • How to Merge HTML Documents in Java
  • Enhancing Business Decision-Making Through Advanced Data Visualization Techniques
  • Can You Run a MariaDB Cluster on a $150 Kubernetes Lab? I Gave It a Shot
  • Distributed Consensus: Paxos vs. Raft and Modern Implementations
  1. DZone
  2. Coding
  3. Frameworks
  4. Using ZK With Spring Boot

Using ZK With Spring Boot

Let's integrate ZK with Spring Boot!

By 
Robert Wenzel user avatar
Robert Wenzel
·
Updated Jan. 15, 21 · Tutorial
Likes (17)
Comment
Save
Tweet
Share
33.8K Views

Join the DZone community and get the full member experience.

Join For Free

In recent years, Spring Boot has become a more and more popular alternative to building and deploying web applications. Following that popularity, questions arose whether existing or new ZK applications can also integrate with Spring Boot instead of building a classical war file.

The answer has always been "yes." At the same time, the transition from web.xml configuration into Java configuration has proven to be inconvenient, error-prone, and full of questions. That's why we at ZK decided to provide the zkspringboot integration module containing default and adjustable autoconfig and a starter dependency.

This was done with the help and inspiration of our active community. Special thanks go to Dirk and his zk-spring-boot-starter project.

In this article, I assume you are mostly familiar with Spring and Spring Boot and/or ZK.

As an introduction, I'd suggest Spring Boot — First Steps or the ZK Documentation.

Quick Start

For the impatient, here is the command sequence to clone and run one of our zkspringboot-demos.

git clone --branch v1.0.4 https://github.com/zkoss/zkspringboot.git
cd zkspringboot/zkspringboot-demos/zkspringboot-minimal-jar
../mvnw spring-boot:run

Then, open http://localhost:8080/ in a browser.

Image title

Understanding the Project

Let's start with a look in to the project structure of zkspringboot-minimal-jar:

Shell
 




x


 
1
$ find . -type f
2
./build.gradle
3
./pom.xml
4
./src/main/java/org/zkoss/zkspringboot/demo/MinimalApplication.java
5
./src/main/resources/application.properties
6
./src/main/resources/web/zul/minimal.zul


Yes, that's all; only 5 files (I'll be ignoring build.gradle for this article — just assume it works similarly). In the following sections, I'll explain the purpose of all these and how to run the project.

pom.xml

The pom file contains a single dependency, zkspringboot-starter, referencing the default dependencies needed to get started easily (hence the name suffix "-starter"), which include zkspringboot-autoconfig , minimal ZK dependencies ( zkbind + dependencies), and a recent Spring Boot version 2.1.0 ( spring-boot-starter-web + dependencies).

In real life projects, you should pick your own project dependencies with newer ZK and Spring Boot versions by replacing the zkspringboot-starter dependency with zkspringboot-autoconfig alongside your hand-selected dependencies/versions. In contrast to the zkspringboot-starter, the autoconfig doesn't add any transitive dependencies and only contains the ZK-Spring Boot configuration classes.

The spring-boot-maven-plugin at the end of pom.xml file is a standard Spring Boot plugin to run and repackage the project into a runnable jar file during the build process (nothing ZK specific here).

MinimalApplication.java

A minimalistic spring configuration class startup class annotated with @SpringBootApplication.

Java
 




xxxxxxxxxx
1


 
1
@SpringBootApplication
2
public class MinimalApplication {
3
    public static void main(String[] args) {
4
        SpringApplication.run(MinimalApplication.class);
5
    }
6
}


The main method specifies the entry point for the application, which will come in handy when running the application inside an IDE.

You might ask, "How does the Spring Boot application know about ZK?"

The answer lies in the file spring.factories inside zkspringboot-autoconfig.jar dependency. By adding this jar to the classpath, Spring will discover this file (by convention) and initialize ZK automatically.

minimal.zul

A simple zul file just to check ZK is working. Since we chose jar packaging (default), there is no classic web-content-folder. No problem for ZK, it can load and display zul files also from the classpath directly. These so-called class-web-resources (in ZK terms) are located below the web package (which can also contain style, script, image...resources).

src/main/resources/web/zul/minimal.zul

I chose to place zul files into the zul folder (you can choose your own package folder(s) below web, as needed). One might think that's a new feature, but in fact, ZK uses this mechanism to provide internal resources from the various zk-jar files — it just wasn't necessary in a classical web application since you had the web-content folder, which is not available in a Spring Boot jar application.

That alone would be sufficient to run/deploy ZK on Spring Boot.

Using the maven plugin, we can start the application easily with a single command and get the familiar output.

Plain Text
 




xxxxxxxxxx
1
26


 
1
$ ../mvnw spring-boot:run
2
[INFO] Scanning for projects...
3
[INFO]
4
[INFO] ------------------------------------------------------------------------
5
[INFO] Building zkspringboot-minimal-jar 0.0.1-SNAPSHOT
6
[INFO] ------------------------------------------------------------------------
7
 
          
8
...
9
 
          
10
  .   ____          _            __ _ _
11
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
12
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
13
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
14
  '  |____| .__|_| |_|_| |_\__, | / / / /
15
 =========|_|==============|___/=/_/_/_/
16
 :: Spring Boot ::        (v2.1.0.RELEASE)
17
 
          
18
2019-01-16 16:38:16.753  INFO 21788 --- [           main] o.z.z.demo.MinimalApplication            : Starting MinimalApplication on Robert-NB with PID 21788 
19
...
20
2019-01-16 16:38:18.736  INFO 21788 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1917 ms
21
2019-01-16 16:38:18.996  INFO 21788 --- [           main] o.z.zkspringboot.ZkAutoConfiguration     : ZK-Springboot: ServletRegistrationBean for DHtmlUpdateServlet with path /zkau
22
...
23
2019-01-16 16:38:20.138  INFO 21788 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
24
2019-01-16 16:38:20.142  INFO 21788 --- [           main] o.z.z.demo.MinimalApplication            : 
25
   Started MinimalApplication in 3.816 seconds (JVM running for 7.618)
26
 
          



You can now access the zul file directly using ZK's ajax and resource servlet mapped to /zkau (this also works in your existing classic ZK application, provided the zul files requested are on the classpath inside the web package folder).

http://localhost:8080/zkau/web/zul/minimal.zul

Image title

Starting from here, you may decide to go "freestyle" — using your existing Spring MVC skills — and configure @Controller classes with @RequestMappings internal forwards and view resolvers. Or, you can read on to check what else is already provided.

application.properties

Obviously the URL above isn't nice, which we can change using the zk.homepage property inside application.properties (ideal for applications with a single entry point SPAs).

zk.homepage=zul/minimal

That's all you need to internally map from your application root —"http://localhost:8080/" — to the home page — "http://localhost:8080/zkau/web/zul/minimal.zul".

(If you need multiple entry points, simply create Spring MVC controller as demonstrated in another more complete demo. See: DemoApplication.java and application.properties).

For the interested folks, here's what happens internally:

The optional configuration class ZkHomepageConfiguration.java simply maps the request path "/" to the configured view name "zul/minimal".

The provided zul-view-resolver (enabled by default) then prepends the update-uri "/zkau" and the class-web-resource path "/web". Finally adds the suffix ".zul" to locate the resource. All this conveniently happens in ZkWebMvcConfiguration.java (part of zkspringboot-autoconfig), and if you need something else, you can just disable it ( zk.zul-view-resolver-enabled=false ) and implement your own ViewResolver.

Other ZK Config Files

Due to the lack of a WEB-INF folder, additional zk configuration files (such as zk.xml, lang-addon.xml, zk-label.properties) are placed into "src/main/resources/application/metainfo(/zk)".

Again, this is nothing new and just relies on the built-in mechanism traditionally used by ZK's own and addon jars.

Staying Independent

For maximum flexibility building/running, the Spring Boot jar application doesn't require an IDE and works from command line:

Shell
 




xxxxxxxxxx
1


 
1
../mvnw clean package
2
java -jar target/zkspringboot-minimal-jar-0.0.1-SNAPSHOT.jar
3
 
          


Naturally, IDEs supporting maven or gradle are able to import and run the application directly (no additional plugins needed, not even a Spring(-Boot)-Plugin). Often, it suffices to right click the main class MinimalApplication.java and choose something like "run/debug as ... Java Application".

Here a typical run configuration (just like any HelloWorld application):

Image title

Just by specifying a "Main class," Spring Boot will be able to do its job and start the embedded Tomcat server and application context including ZK's and your own application configuration.

Becoming Efficient

While the trivial minimal example has reasonably short startup times, those won't remain constant as your project gets larger and more complex. That's why it's vital to be able to change and reload resources without having to restart the application for each tiny change. Again, this might have never affected you from the ZK side as long as you had your zul and resource files in the web-content-folder. Now your resources are on the classpath, which behaves slightly different. By default, various resource caches prevent dynamic reloading of zul pages and other resources. Luckily, those can be disabled during development either inside a zk.xml or via Spring java config.

As a template, you can use the DevelopmentConfig.java (part of zkspringboot-demo-jar), which disables all kinds of caches. The configuration is only activated via the Spring configuration profile "dev." You can activate it in your run config using the VM option -Dspring.profiles.active=dev (there are multiple ways, please refer to the Spring documentation on profiles).

Java
 




x


 
1
@Configuration
2
@Profile("dev")
3
public class DevelopmentConfig {
4
    private static Logger logger = LoggerFactory.getLogger(DevelopmentConfig.class);
5
 
          
6
    @PostConstruct
7
    public void initDevelopmentProperties() throws Exception {
8
        logger.info("**************************************************************");
9
        logger.info("**** ZK-Springboot-Demo: development configuration active ****");
10
        logger.info("**************************************************************");
11
 
          
12
        //disable various caches to avoid server restarts
13
        Library.setProperty("org.zkoss.zk.ZUML.cache", "false");
14
        Library.setProperty("org.zkoss.zk.WPD.cache", "false");
15
        Library.setProperty("org.zkoss.zk.WCS.cache", "false");
16
        Library.setProperty("org.zkoss.web.classWebResource.cache", "false");
17
        Library.setProperty("org.zkoss.util.label.cache", "false");
18
 
          
19
        // enable non minified js
20
        WebApps.getCurrent().getConfiguration().setDebugJS(true);
21
 
          
22
        // enable for debugging MVVM commands and binding (very verbose)
23
        Library.setProperty("org.zkoss.bind.DebuggerFactory.enable", "false");
24
    }
25
}



This development configuration allows changing .zul files and other resources without having to restart the server when running in debug mode.

There's a tiny catch: You might be used to simply saving a file and then reload the browser. Since files are on the classpath, they need to be "built" by the IDE in order to be reloaded in the running application. Being just resource files building involves copying them into the runtime classpath folder. In IntelliJ, this means you have to "recompile" the file (CTRL-SHIFT-F9 on Windows), or in Eclipse, enable "auto-build" and save the file. (Maybe there's also a general function I missed in IntelliJ to auto-rebuild resources on auto-save).

Once that's done, refresh the browser once (make sure it doesn't cache as well, you might have to hard reload (CTRL-F5) to get rid of long term cached resources once).

If someone knows a pure command-line + any-texteditor variant of this, let me know in the comments.

Conclusion

Spring Boot and ZK are both nontrivial frameworks, each having their own conventions and built-in mechanisms. Integration is possible but not always without friction and requires insight into both frameworks.

I hope the "ZK - Spring Boot" module helps during this process and that the explanations above clarify and demystify common questions and misunderstandings. If I missed something critical, please let me know in the comments.

Spring Framework Spring Boot Web application

Opinions expressed by DZone contributors are their own.

Related

  • Develop Web Application With Spring Boot in 30 minutes
  • How to Enable HTTPS on a Spring Boot Application
  • Actuator Enhancements: Spring Framework 6.2 and Spring Boot 3.4
  • How Spring Boot Starters Integrate With Your Project

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!