I debug CUSTOMER object with List<Object> inside:
CUSTOMER
List<Object>
首页 > 解决方案 > 错误的反序列化列表 with gson I debug CUSTOMER object with List<Object> inside: java - 错误的反序列化列表 with gson I debug CUSTOMER object with List<Object> inside: 问题描述 I debug CUSTOMER object with List<Object> inside: This is CUSTOMER.class: public class CUSTOMER { @XmlElements({ @XmlElement(name = "ADDRESS", type = ADDRESS.class), @XmlElement(name = "ZIP", type = ZIP.class), @XmlElement(name = "CITY", type = CITY.class), @XmlElement(name = "COUNTRY", type = COUNTRY.class), }) protected List<Object> addressAndZIPAndCITY; // other fields } But when I deserialize and create json from it, it contains only: { "addressAndZIPAndCITY": [ { "value": "some value", "type": "some type" }, { "value": "some value 2", "type": "some type 2" }] } The ADRESS, ZIP, CITY and COUNTRY objects titles are missing. So it's bad deserialized. I can't change List<Object> declaration. Is there option to deserialize it as json with ADRESS, ZIP, CITY etc.? Like this: { "addressAndZIPAndCITY": [{ "ADDRESS": { "value": "some value", "type": "some type" } }, { "ZIP": { "value": "some value 2", "type": "some type 2" } } ] } EDIT: I mean it looks like GSON doesn't know which object is there, but may be you know how to add some annotations or something else to the model to recognize it? Running Query through multiple Dynamic Controls c# WinForms I have created a tool which loops around all listed databases and executes a SQL Query one at a time. I've dynamically created the same controls in a new tab when you click on the New Query button, to allow me to run different queries at the same time. I have an execute button which will execute the selected script. My problem is that it means my query variable will change depending if I execute another Script. This is how I find my controls private void findControls() { tp = metroTabControl1.SelectedTab; s = ((SplitContainer)tp.Controls["SplitContainer" + tp.Name.ToString()]); tc = ((MetroTabControl)s.Panel2.Controls["AllResults" + tp.Name.ToString()]); tpResults = ((TabPage)tc.TabPages["Results" + tp.Name.ToString()]); tpMessages = ((TabPage)tc.TabPages["Messages" + tp.Name.ToString()]); dgvResults = ((DataGridView)tpResults.Controls["dgv" + tp.Name.ToString()]); tbMessages = ((MetroTextBox)tpMessages.Controls["Messages" + tp.Name.ToString()]); labCount = ((MetroLabel)s.Panel2.Controls["Progress" + tp.Name.ToString()]); tbQuery = ((MetroTextBox)s.Panel1.Controls["SQLQueryText" + tp.Name.ToString()]); } On the Execution, I create the BackgroundWorker and I set the Query BackgroundWorker bgwExec = new BackgroundWorker(); bgwExec.WorkerReportsProgress = true; bgwExec.WorkerSupportsCancellation = true; bgwExec.DoWork += BgwExec_DoWork; bgwExec.ProgressChanged += BgwExec_ProgressChanged; bgwExec.RunWorkerCompleted += BgwExec_RunWorkerCompleted; findControls(); query = tbQuery.Text; In the For loop, it'll run the query over all the databases, the issue though is that if I execute another query, then the BackgroundWorker will start running a different query. for (int i = 0; i < dtDBList.Rows.Count; i++) { if (bgwExec.CancellationPending == true) { e.Cancel = true; return; } try { string server = dtDBList.Rows[i]["server"].ToString(); string database = dtDBList.Rows[i]["db"].ToString(); dtResults = eq.SelectStatementResults(query, server, database, iuser, ipass, dtResults); ds.Tables.Add(dtResults); progress += 1; bgwExec.ReportProgress(progress); sb = eq.sb; log.Info("Executed Script on " + database); log.Info(query); } catch (Exception err) { log.Error("Failed to execute script " + err.Message); progress += 1; errorCount += 1; bgwExec.ReportProgress(progress); } } Do you know of any way I can get around this? I've tried using a dictionary, but then I still don't know how I would pull the correct value from the dictionary... Thanks in advance 标签: javajson 解决方案 我认为您要么必须为 CUSTOMER 编写自定义序列化程序,要么创建另一个从中进行序列化的类: public class GsonCustomer { private List<Map<String, Object>> addressAndZipAndCity = new ArrayList<>(); // other fields public GsonCustomer(CUSTOMER customer) { for (Object o: customer.getAddressAndZipAndCity()) { Map<String, Object> map = new HashMap<>(); map.put(o.getClass().getSimpleName(), o); addressAndZipAndCity.add(map); } // copy other fields } } // so you can do: gson.toJson(new GsonCustomer(customer)) 或如前所述: public class CustomerAdapter implements JsonSerializer<CUSTOMER> { @Override public JsonElement serialize(CUSTOMER customer, Type type, JsonSerializationContext jsonSerializationContext) { // TODO } } // Gson gson = new GsonBuilder().registerTypeAdapter(CustomerAdapter.class, new CustomerAdapter()).create(); 推荐阅读 ios - 按下 UIAlertViewController 行时更改背景颜色python - 为什么我的装饰器按这个顺序执行代码?c# - 如何从 c# windows 应用程序向 PHP 服务器发送包含对象数组的 POST 请求?c# - POST 带有 URL 参数但正文为空时如何使用 ServiceStack 的 ProxyFeature?c# - Visual Studio 2019 中的 Visual Inheritance 似乎有问题java - 无法从 REST API 获取 JSON 作为字符串c# - ASP.NET CORE 2.0 项目中的 LinkedIn 登录集成python-3.x - ModuleNotFoundError:没有名为“py4j”的模块python-3.x - 河内塔最多允许 100 个c# - 遮蔽元素名称更改 ID
This is CUSTOMER.class:
public class CUSTOMER { @XmlElements({ @XmlElement(name = "ADDRESS", type = ADDRESS.class), @XmlElement(name = "ZIP", type = ZIP.class), @XmlElement(name = "CITY", type = CITY.class), @XmlElement(name = "COUNTRY", type = COUNTRY.class), }) protected List<Object> addressAndZIPAndCITY; // other fields }
But when I deserialize and create json from it, it contains only:
{ "addressAndZIPAndCITY": [ { "value": "some value", "type": "some type" }, { "value": "some value 2", "type": "some type 2" }] }
The ADRESS, ZIP, CITY and COUNTRY objects titles are missing. So it's bad deserialized.
I can't change List<Object> declaration. Is there option to deserialize it as json with ADRESS, ZIP, CITY etc.? Like this:
{ "addressAndZIPAndCITY": [{ "ADDRESS": { "value": "some value", "type": "some type" } }, { "ZIP": { "value": "some value 2", "type": "some type 2" } } ] }
EDIT: I mean it looks like GSON doesn't know which object is there, but may be you know how to add some annotations or something else to the model to recognize it?
I have created a tool which loops around all listed databases and executes a SQL Query one at a time. I've dynamically created the same controls in a new tab when you click on the New Query button, to allow me to run different queries at the same time.
I have an execute button which will execute the selected script. My problem is that it means my query variable will change depending if I execute another Script.
This is how I find my controls
private void findControls() { tp = metroTabControl1.SelectedTab; s = ((SplitContainer)tp.Controls["SplitContainer" + tp.Name.ToString()]); tc = ((MetroTabControl)s.Panel2.Controls["AllResults" + tp.Name.ToString()]); tpResults = ((TabPage)tc.TabPages["Results" + tp.Name.ToString()]); tpMessages = ((TabPage)tc.TabPages["Messages" + tp.Name.ToString()]); dgvResults = ((DataGridView)tpResults.Controls["dgv" + tp.Name.ToString()]); tbMessages = ((MetroTextBox)tpMessages.Controls["Messages" + tp.Name.ToString()]); labCount = ((MetroLabel)s.Panel2.Controls["Progress" + tp.Name.ToString()]); tbQuery = ((MetroTextBox)s.Panel1.Controls["SQLQueryText" + tp.Name.ToString()]); }
On the Execution, I create the BackgroundWorker and I set the Query
BackgroundWorker
BackgroundWorker bgwExec = new BackgroundWorker(); bgwExec.WorkerReportsProgress = true; bgwExec.WorkerSupportsCancellation = true; bgwExec.DoWork += BgwExec_DoWork; bgwExec.ProgressChanged += BgwExec_ProgressChanged; bgwExec.RunWorkerCompleted += BgwExec_RunWorkerCompleted; findControls(); query = tbQuery.Text;
In the For loop, it'll run the query over all the databases, the issue though is that if I execute another query, then the BackgroundWorker will start running a different query.
for (int i = 0; i < dtDBList.Rows.Count; i++) { if (bgwExec.CancellationPending == true) { e.Cancel = true; return; } try { string server = dtDBList.Rows[i]["server"].ToString(); string database = dtDBList.Rows[i]["db"].ToString(); dtResults = eq.SelectStatementResults(query, server, database, iuser, ipass, dtResults); ds.Tables.Add(dtResults); progress += 1; bgwExec.ReportProgress(progress); sb = eq.sb; log.Info("Executed Script on " + database); log.Info(query); } catch (Exception err) { log.Error("Failed to execute script " + err.Message); progress += 1; errorCount += 1; bgwExec.ReportProgress(progress); } }
Do you know of any way I can get around this?
I've tried using a dictionary, but then I still don't know how I would pull the correct value from the dictionary...
Thanks in advance
标签: javajson
我认为您要么必须为 CUSTOMER 编写自定义序列化程序,要么创建另一个从中进行序列化的类:
public class GsonCustomer { private List<Map<String, Object>> addressAndZipAndCity = new ArrayList<>(); // other fields public GsonCustomer(CUSTOMER customer) { for (Object o: customer.getAddressAndZipAndCity()) { Map<String, Object> map = new HashMap<>(); map.put(o.getClass().getSimpleName(), o); addressAndZipAndCity.add(map); } // copy other fields } } // so you can do: gson.toJson(new GsonCustomer(customer))
或如前所述:
public class CustomerAdapter implements JsonSerializer<CUSTOMER> { @Override public JsonElement serialize(CUSTOMER customer, Type type, JsonSerializationContext jsonSerializationContext) { // TODO } } // Gson gson = new GsonBuilder().registerTypeAdapter(CustomerAdapter.class, new CustomerAdapter()).create();