Architecture Overview"

From Documentation
(33 intermediate revisions by 2 users not shown)
Line 7: Line 7:
 
=From the Application Developer's Perspective=
 
=From the Application Developer's Perspective=
  
The ZK application runs on the server. It can access to backend resources, assemble UI with components, listen to user's activity, and then manipulate components to update UI. All of the above activities can be accomplished on the server. The synchronization of the states of the components between the browser and the server is done automatically by ZK and transparently to the application.
+
The ZK application runs on the server. It can access backend resources, assemble UI with components, listen to user's activities, and then manipulate components to update UI. All of the above activities can be accomplished on the server. The synchronization of components' states between the browser and the server is done automatically by ZK and transparently to the application.
  
When running on the server, the application can access to full Java technology stacks. User activities, such as Ajax and Server Push, are abstracted to event objects. UI are composed by POJO-like components. It is the most productive approach to develop a modern Web application.
+
When running on the server, the application has access to full Java technology stacks. User activities, such as Ajax and Server Push, are abstracted to event objects. UI are composed by POJO-like components. It is the most productive approach to develop a modern Web application.
  
 
With ZK's '''Server+client Fusion architecture''', your application will never stop running on the server. The application can enhance the interactivity by adding optional client-side functionality, such as client-side event handling, visual effect customizing or even UI composing without server-side coding. ZK enables seamless fusions ranging from pure server-centric to pure client-centric. You can have the best of two worlds: productivity and flexibility.
 
With ZK's '''Server+client Fusion architecture''', your application will never stop running on the server. The application can enhance the interactivity by adding optional client-side functionality, such as client-side event handling, visual effect customizing or even UI composing without server-side coding. ZK enables seamless fusions ranging from pure server-centric to pure client-centric. You can have the best of two worlds: productivity and flexibility.
Line 23: Line 23:
 
For example, assuming that we want to implement a component that allows a user to click on a DOM element to show some detailed information of a component and there are at least two approaches to implement it. Firstly, we could load the detailed information to the client when the widget is instantiated, and then show the details with pure client code.  Alternatively, we may choose not to load the detailed information at the very beginning before sending a request back to the server for fulfilling the details when the user clicks on it.
 
For example, assuming that we want to implement a component that allows a user to click on a DOM element to show some detailed information of a component and there are at least two approaches to implement it. Firstly, we could load the detailed information to the client when the widget is instantiated, and then show the details with pure client code.  Alternatively, we may choose not to load the detailed information at the very beginning before sending a request back to the server for fulfilling the details when the user clicks on it.
  
Obviously, the first approach requires more bandwidth for the initial request but it also provides faster responses when users click on it. This is generally more transparent to the application developers, and the implementation of a component can be enhanced later as the project progresses.
+
Obviously, the first approach consumes more bandwidth at the initial request but at the same time it also provides faster responses when users click on the DOM element. This is generally more transparent to the application developers, and the implementation of a component can be enhanced later as the project progresses.
  
 
<blockquote>
 
<blockquote>
Line 32: Line 32:
 
=Execution Flow of Loading a Page=
 
=Execution Flow of Loading a Page=
  
#When a user types a URL or clicks a hyperlink in the browser, a request is sent to the Web server. If the request URL matches ZK's configured URL pattern<ref>For more information, please refer to [[ZK_Configuration_Reference/web.xml/ZK_Loader|ZK Configuration Reference]]</ref>, the ZK loader will be invoked to serve this request.
+
#When a user types a URL or clicks a hyperlink in the browser, a request is sent to the Web server. If the requested URL matches with the ZK's configured URL pattern<ref>For more information, please refer to [[ZK_Configuration_Reference/web.xml/ZK_Loader|ZK Configuration Reference]]</ref>, a ZK loader will be invoked to serve this request.
#ZK loader loads a specified page and interprets it to create proper components accordingly<ref>If URL is mapped to a richlet, the richlet will be called to handle all UI composition. For more information, please refer to [[ZK Developer's Reference/UI Composing/Richlet|Richlet]].</ref>.
+
#The ZK loader loads a specified page and interprets that page to create proper components accordingly<ref>If URL is mapped to a richlet, the richlet will be called to handle all UI composition. For more information, please refer to [[ZK Developer's Reference/UI Composing/Richlet|Richlet]].</ref>.
#After interpreting the whole page, ZK loader renders the result into a HTML page. The HTML page is then sent back to the browser accompanied with ZK Client Engine<ref>ZK Client Engine is written in JavaScript. Browsers will cache ZK Client engine, so ZK Client engine is usually sent only once at the first visit.</ref>.
+
#After interpreting the whole page, the ZK loader will render the result to an HTML page. The HTML page is then sent back to the browser accompanied with the ZK Client Engine<ref>ZK Client Engine is written in JavaScript. Browsers will cache ZK Client engine, so ZK Client engine is usually sent only once at the first visit.</ref>.
#ZK Client engine renders the widgets into DOM elements and inserts the DOM elements into the browser's DOM tree to make them visible to users.
+
#The ZK Client Engine renders the widgets into DOM elements and then inserts the DOM elements into the browser's DOM tree to make them visible to users.
#Then, ZK Client engine sits at the browser to serve the requests made by user, widgets or the application. If it goes to another page, the execution flow will start over again. If it is going to send a Ajax request back, another execution flow will start as described in the following section.
+
#After that, the ZK Client Engine will sit at the browser to serve requests made by the users, widgets or the applications. If it goes to another page, the execution flow will start over again. If it is going to send an Ajax request back, another execution flow will start as described in the following section.
  
 
<blockquote>
 
<blockquote>
Line 45: Line 45:
 
=Execution Flow of Serving an Ajax Request=
 
=Execution Flow of Serving an Ajax Request=
  
#The execution flow is started from a widget or the application. This is usually caused by the user's activity (or application's requirement) and is done by posting a client-side event (<javadoc directory="jsdoc">zk.Event</javadoc>) to a widget (<javadoc method="fire(zk.Event,int)" directory="jsdoc">zk.Widget</javadoc>).
+
# The execution flow starts from a widget or the application. This is usually caused by the user's activity (or the application's requirement) and is done by posting a client-side event (<javadoc directory="jsdoc">zk.Event</javadoc>) to a widget (<javadoc method="fire(zk.Event,int)" directory="jsdoc">zk.Widget</javadoc>).
# The event is then bubbled up to the widget's parent, parent's parent, and finally ZK Client engine<ref>A widget could choose to stop this bubble-up propagation by use of <javadoc directory="jsdoc" method="stop(_global_.Map)">zk.Event</javadoc></ref>. ZK Client engine then decides whether and when to send the event back to the server in an Ajax request.
+
# The event is then bubbled up to the widget's parent, parent's parent, and finally the ZK Client Engine<ref>A widget could choose to stop this bubble-up propagation by use of <javadoc directory="jsdoc" method="stop(_global_.Map)">zk.Event</javadoc></ref>. The ZK Client Engine then decides whether and when to send the event back to the server in an Ajax request.
# If necessary, ZK Client engine will send an Ajax request to ZK Update engine on the server<ref>From the server's viewpoint, an Ajax request is another type of HTTP request.</ref>.
+
# If necessarily, the ZK Client Engine will send an Ajax request to the ZK Update Engine on the server<ref>. From the server's viewpoint, an Ajax request is another type of HTTP request.</ref>.
#Upon receiving Ajax requests, ZK Update engine will invoke <javadoc method="service(org.zkoss.zk.au.AuRequest,boolean)" type="interface">org.zkoss.zk.ui.sys.ComponentCtrl</javadoc> for handling the request.
+
# Upon receiving Ajax requests, the ZK Update engine will invoke <javadoc method="service(org.zkoss.zk.au.AuRequest,boolean)" type="interface">org.zkoss.zk.ui.sys.ComponentCtrl</javadoc> for handling an AU request. ZK also wraps a AU request into [https://www.zkoss.org/javadoc/latest/zk/org/zkoss/zk/ui/Execution.html Execution] object.
# The handling is up to a component. But, it usually updates the states, if necessary, and then notifies the application by posting events (<javadoc method="postEvent(org.zkoss.zk.ui.event.Event)">org.zkoss.zk.ui.event.Events</javadoc>).
+
# How the AU request can be handled is really up to a component. But, the component that handles the request usually updates the states, if necessarily, and then notifies the application by posting events to the current execution (<javadoc method="postEvent(org.zkoss.zk.ui.event.Event)">org.zkoss.zk.ui.event.Events</javadoc>).
#If any event is posted, ZK Update engine will process them one-by-one by invoking the event listeners.
+
#If any event is posted, the ZK Update Engine will process them one-by-one by invoking the event listeners.
 
#The event listener, provided by an application, may choose either to update the backend resources or the components or to post other events.
 
#The event listener, provided by an application, may choose either to update the backend resources or the components or to post other events.
#Finally, ZK Update engine collects all updates of components, including states change, attachment and detachment for optimization and then send back a collection of commands back to the client.
+
#Finally, the ZK Update Engine collects all updates of components, including states change, attachment and detachment for optimization and then send a collection of commands back to the client.
#ZK Client engine evaluates each of these commands to update the widgets accordingly. Then the widgets will update the browser's DOM tree to make them available to the user.
+
#The ZK Client Engine evaluates each of these commands to update the widgets accordingly. Then the widgets will update the browser's DOM tree to make them available to the user.
  
 
<blockquote>
 
<blockquote>
Line 62: Line 62:
 
==When to Send an Ajax Request==
 
==When to Send an Ajax Request==
  
When ZK Client engine receives a bubbled-up client-side event (<javadoc directory="jsdoc">zk.Event</javadoc>), it will decide whether and when to send it back to the server for further processing:
+
When the ZK Client Engine receives a bubbled-up client-side event (<javadoc directory="jsdoc">zk.Event</javadoc>), it will decide whether and when to send the event back to the server for further processing:
  
#If there is a non-deferrable event listener registered on the server, the request will be sent immediately.
+
#If there is a non-deferrable event listener registered on the server, the Ajax request will be sent immediately.
 
#If there is a deferrable event listener registered on the server, the request will be queued at the client and it will be sent when another event is triggered and a non-deferrable event listener registered for it.
 
#If there is a deferrable event listener registered on the server, the request will be queued at the client and it will be sent when another event is triggered and a non-deferrable event listener registered for it.
#If the widget declares that the event is important (<javadoc method="CE_IMPORTANT">org.zkoss.zk.ui.sys.ComponentCtrl</javadoc>), the event will be queued for later transmitting too.
+
#If the widget declares that the event is important (<javadoc method="CE_IMPORTANT">org.zkoss.zk.ui.sys.ComponentCtrl</javadoc>), the event will be queued for later transmission too.
 
#If none of the above case or the widget has no corresponding component on the server, the event will be dropped.
 
#If none of the above case or the widget has no corresponding component on the server, the event will be dropped.
  
A non-deferred event listener is an event listener (<javadoc type="interface">org.zkoss.zk.ui.event.EventListener</javadoc>) that doesn't implement <javadoc type="interface">org.zkoss.zk.ui.event.Deferrable</javadoc>. In other words, to minimize the traffic from the client, you might implement an event listener with <javadoc type="interface">org.zkoss.zk.ui.event.Deferrable</javadoc> if applicable.
+
A non-deferred event listener is an event listener (<javadoc type="interface">org.zkoss.zk.ui.event.EventListener</javadoc>) that does not implement <javadoc type="interface">org.zkoss.zk.ui.event.Deferrable</javadoc>. In other words, to minimize the traffic from the client, you might want to implement an event listener with <javadoc type="interface">org.zkoss.zk.ui.event.Deferrable</javadoc> if applicable.
  
 
=Version History=
 
=Version History=

Revision as of 02:52, 9 May 2019


Architecture Overview


Architecture-s.png

From the Application Developer's Perspective

The ZK application runs on the server. It can access backend resources, assemble UI with components, listen to user's activities, and then manipulate components to update UI. All of the above activities can be accomplished on the server. The synchronization of components' states between the browser and the server is done automatically by ZK and transparently to the application.

When running on the server, the application has access to full Java technology stacks. User activities, such as Ajax and Server Push, are abstracted to event objects. UI are composed by POJO-like components. It is the most productive approach to develop a modern Web application.

With ZK's Server+client Fusion architecture, your application will never stop running on the server. The application can enhance the interactivity by adding optional client-side functionality, such as client-side event handling, visual effect customizing or even UI composing without server-side coding. ZK enables seamless fusions ranging from pure server-centric to pure client-centric. You can have the best of two worlds: productivity and flexibility.

From the Component Developer's Perspective

Each UI object in ZK consists of a component and a widget. A component is a Java object running on the server representing a UI object which can be manipulated by a Java application. A component has all the behavior of a UI object except that it does not have a visual part. A widget is a JavaScript object[1] running at the client. This object represents the UI object which interacts with the user. Therefore, a widget usually has a visual appearance and it handles events happening at the client.

The relationship between a component and a widget is one-to-one. However, if a component is not attached to a page, there will not be a corresponding widget at the client. On the other hand, the application is allowed to instantiate widgets at the client directly without a corresponding component.

How state synchronization and load distribution might occur depends really on the component. The ZK Client Engine and the Update Engine will work together to provide an elegant and robust channel to simplify the implementation.

For example, assuming that we want to implement a component that allows a user to click on a DOM element to show some detailed information of a component and there are at least two approaches to implement it. Firstly, we could load the detailed information to the client when the widget is instantiated, and then show the details with pure client code. Alternatively, we may choose not to load the detailed information at the very beginning before sending a request back to the server for fulfilling the details when the user clicks on it.

Obviously, the first approach consumes more bandwidth at the initial request but at the same time it also provides faster responses when users click on the DOM element. This is generally more transparent to the application developers, and the implementation of a component can be enhanced later as the project progresses.


  1. It depends on the client. For Ajax-enabled browsers, it is a JavaScript object. For ZK Reach for Android, it is a Java object running on an Android device.

Execution Flow of Loading a Page

  1. When a user types a URL or clicks a hyperlink in the browser, a request is sent to the Web server. If the requested URL matches with the ZK's configured URL pattern[1], a ZK loader will be invoked to serve this request.
  2. The ZK loader loads a specified page and interprets that page to create proper components accordingly[2].
  3. After interpreting the whole page, the ZK loader will render the result to an HTML page. The HTML page is then sent back to the browser accompanied with the ZK Client Engine[3].
  4. The ZK Client Engine renders the widgets into DOM elements and then inserts the DOM elements into the browser's DOM tree to make them visible to users.
  5. After that, the ZK Client Engine will sit at the browser to serve requests made by the users, widgets or the applications. If it goes to another page, the execution flow will start over again. If it is going to send an Ajax request back, another execution flow will start as described in the following section.

  1. For more information, please refer to ZK Configuration Reference
  2. If URL is mapped to a richlet, the richlet will be called to handle all UI composition. For more information, please refer to Richlet.
  3. ZK Client Engine is written in JavaScript. Browsers will cache ZK Client engine, so ZK Client engine is usually sent only once at the first visit.

Execution Flow of Serving an Ajax Request

  1. The execution flow starts from a widget or the application. This is usually caused by the user's activity (or the application's requirement) and is done by posting a client-side event (Event) to a widget (Widget.fire(Event, int)).
  2. The event is then bubbled up to the widget's parent, parent's parent, and finally the ZK Client Engine[1]. The ZK Client Engine then decides whether and when to send the event back to the server in an Ajax request.
  3. If necessarily, the ZK Client Engine will send an Ajax request to the ZK Update Engine on the server[2].
  4. Upon receiving Ajax requests, the ZK Update engine will invoke ComponentCtrl.service(AuRequest, boolean) for handling an AU request. ZK also wraps a AU request into Execution object.
  5. How the AU request can be handled is really up to a component. But, the component that handles the request usually updates the states, if necessarily, and then notifies the application by posting events to the current execution (Events.postEvent(Event)).
  6. If any event is posted, the ZK Update Engine will process them one-by-one by invoking the event listeners.
  7. The event listener, provided by an application, may choose either to update the backend resources or the components or to post other events.
  8. Finally, the ZK Update Engine collects all updates of components, including states change, attachment and detachment for optimization and then send a collection of commands back to the client.
  9. The ZK Client Engine evaluates each of these commands to update the widgets accordingly. Then the widgets will update the browser's DOM tree to make them available to the user.

  1. A widget could choose to stop this bubble-up propagation by use of Event.stop(Map)
  2. . From the server's viewpoint, an Ajax request is another type of HTTP request.

When to Send an Ajax Request

When the ZK Client Engine receives a bubbled-up client-side event (Event), it will decide whether and when to send the event back to the server for further processing:

  1. If there is a non-deferrable event listener registered on the server, the Ajax request will be sent immediately.
  2. If there is a deferrable event listener registered on the server, the request will be queued at the client and it will be sent when another event is triggered and a non-deferrable event listener registered for it.
  3. If the widget declares that the event is important (ComponentCtrl.CE_IMPORTANT), the event will be queued for later transmission too.
  4. If none of the above case or the widget has no corresponding component on the server, the event will be dropped.

A non-deferred event listener is an event listener (EventListener) that does not implement Deferrable. In other words, to minimize the traffic from the client, you might want to implement an event listener with Deferrable if applicable.

Version History

Last Update : 2019/05/09


Version Date Content
     



Last Update : 2019/05/09

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.