Details
Description
Steps to Reproduce
- Simple ZK MVVM application with a "dropupload" component (Button) to upload a file.
- ZK application must be configured to serialize session externally. For our example we are serializing to Redis using Spring Session Data Redis.
- use "org.zkoss.zk.ui.http.SerializableUiFactory" in for "ui-factory-class" in zk.xml file
- use workaround described here to flush session serialization on each Execution cleanup
- use "spring.session.store-type=redis" application property to activate session serialization to Redis
- add these dependencies to serialize session to Redis, versions from Spring Session BOM:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
- Start Redis standalone server with all the defaults
- Launch ZK application and click the button to upload a file
Current Result
Exception:
org.zkoss.zk.ui.UiException: Upload content not found: tZGE0t0.0 at org.zkoss.zk.ui.event.UploadEvent.getLatestUploadEvent(UploadEvent.java:81) at org.zkoss.zul.Button.service(Button.java:319) at org.zkoss.zk.ui.impl.DesktopImpl.service(DesktopImpl.java:843) at org.zkoss.zk.ui.impl.UiEngineImpl.execUpdate(UiEngineImpl.java:1312) at org.zkoss.zk.au.http.DHtmlUpdateServlet.process(DHtmlUpdateServlet.java:571) at org.zkoss.zk.au.http.DHtmlUpdateServlet.doGet(DHtmlUpdateServlet.java:451) at org.zkoss.zk.au.http.DHtmlUpdateServlet.doPost(DHtmlUpdateServlet.java:459) at javax.servlet.http.HttpServlet.service(HttpServlet.java:696) at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
Expected Result
File is successfully uploaded
Debug Information
In "org.zkoss.zk.au.http.AuDropUploader", method "processItems", upload info key is recorded as an Desktop attribute. This attribute is lost shortly after. We suppose it is du to the fact that the instance of the Desktop is deserialized sometime before UploadEvent is processed in "org.zkoss.zk.ui.event.UploadEvent", method "getLatestUploadEvent" overriding the attributes.
Workaround
Following the insight from the forum post given above we can force session serialization by executing this statement right after the call to "processItems" in "AuDropUploader":
// right after call to processItems()
sess.setAttribute(org.zkoss.zk.ui.sys.Attributes.ZK_SESSION, sess.getAttribute(org.zkoss.zk.ui.sys.Attributes.ZK_SESSION));
This apparently serializes the session (with all desktop attributes) right away so that upload info key attribute is present upon any successive deserialization.
Please note that we are well aware of the helpful message in JavaDoc for "org.zkoss.zk.ui.impl.DesktopImpl" which sheds light to the potential issues related to serialization of Desktop.