คำถาม
มีวิธีใดบ้างในการดีซีเรียลไลซ์ JSON โดยใช้เฟรมเวิร์ก AutoBean เพื่อให้ bean ผลลัพธ์มีพารามิเตอร์ประเภทที่ส่งผลต่อประเภทของสมาชิกตั้งแต่หนึ่งตัวขึ้นไป
พื้นหลัง
RPC พร้อมผลลัพธ์ JSON
ฉันใช้ GWT (RequestBuilder
) เพื่อดำเนินการคำขอ RPC เพย์โหลด JSON ที่ส่งคืนมีรูปแบบต่อไปนี้:
{
"resultSet": [{...}, {...}, ...], // items requested; say, items 150-160
"totalCount": 15330 // total matching items in DB
}
วัตถุใน resultSet
มีประเภทแตกต่างกันไปขึ้นอยู่กับ RPC เฉพาะที่ฉันกำลังเรียก
อินเตอร์เฟซออโต้บีน
ฉันต้องการดีซีเรียลไลซ์ JSON นี้โดยใช้ AutoBean ฉันพยายามเป็นตัวแทนของวัตถุนี้ดังนี้:
interface RpcResults<T> {
List<T> getResultSet();
void setResultSet(List<T> resultSet);
int getTotalCount();
void setTotalCount(int totalCount);
}
ฉันยังสร้างอินเทอร์เฟซที่เหมาะสมซึ่งแสดงถึงออบเจ็กต์แต่ละประเภทที่อาจมีอยู่ภายใน resultSet
ในที่สุด ฉันตั้งค่าการโทรที่เหมาะสมเป็น AutoBeanCodex.decode
กำลังรันโค้ด
ความพยายามที่จะเรียกใช้รหัสนี้ในโหมดการพัฒนาทำให้การติดตามสแต็กต่อไปนี้ปรากฏในคอนโซล:
19:44:23.791 [ERROR] [xcbackend] Uncaught exception escaped
java.lang.IllegalArgumentException: The AutoBeanFactory cannot create a java.lang.Object
at com.google.gwt.autobean.shared.AutoBeanCodex$Decoder.push(AutoBeanCodex.java:240)
at com.google.gwt.autobean.shared.AutoBeanCodex$Decoder.decode(AutoBeanCodex.java:50)
at com.google.gwt.autobean.shared.AutoBeanCodex$Decoder.visitCollectionProperty(AutoBeanCodex.java:83)
at com.citrix.xenclient.backend.client.json.RpcResultsAutoBean.traverseProperties(RpcResultsAutoBean.java:100)
at com.google.gwt.autobean.shared.impl.AbstractAutoBean.traverse(AbstractAutoBean.java:153)
at com.google.gwt.autobean.shared.impl.AbstractAutoBean.accept(AbstractAutoBean.java:112)
at com.google.gwt.autobean.shared.AutoBeanCodex$Decoder.decode(AutoBeanCodex.java:51)
at com.google.gwt.autobean.shared.AutoBeanCodex.decode(AutoBeanCodex.java:505)
at com.google.gwt.autobean.shared.AutoBeanCodex.decode(AutoBeanCodex.java:521)
at com.citrix.xenclient.backend.client.services.JSONResponseResultSetHandler.onResponseReceived(JSONResponseResultSetHandler.java:51)
at com.google.gwt.http.client.Request.fireOnResponseReceived(Request.java:287)
at com.google.gwt.http.client.RequestBuilder$1.onReadyStateChange(RequestBuilder.java:395)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:157)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:326)
at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:207)
at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:126)
at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:269)
at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:214)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:157)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:281)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:531)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:352)
at java.lang.Thread.run(Thread.java:636)
จากการติดตามสแต็กนี้ ลางสังหรณ์ของฉันมีดังนี้:
- การลบประเภททำให้ดูเหมือนว่า
RpcResults.getResultSet()
กำลังส่งกลับค่า rawList
- โปรแกรมดีซีเรียลไลเซอร์ AutoBean พยายามสร้างอินสแตนซ์
Object
สำหรับแต่ละรายการในresultSet
- ความล้มเหลว
คำถามอีกครั้ง
ฉันขาดอะไรบางอย่างใน AutoBean API ที่จะทำให้ฉันทำสิ่งนี้ได้อย่างง่ายดายหรือไม่ ถ้าไม่ มีจุดโจมตีที่ชัดเจนที่ฉันควรพิจารณาหรือไม่ มีทางเลือกอื่นที่สมเหตุสมผลกว่าสำหรับสิ่งที่ฉันทำอยู่ (นอกเหนือจาก JSONParser และ JavaScriptObject ที่ฉันใช้อยู่แล้ว) หรือไม่