JSON解析转化list对象为String时出错

在Servlet中,尝试将从数据库获取的list<goods>转化为JSON字符串时,由于list中的goods对象含有java.sql.Date类型,导致JSONObject.fromObject()方法抛出异常。错误源于JSON库不支持直接转换java.sql.Date。解决方法是将java.sql.Date转换为java.util.Date再进行JSON序列化,例如使用new java.util.Date(sqldate.getTime())和new java.sql.Date(utildate.getTime())进行转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

花了将近两个小时解决这个问题。幸亏认真分析了所有报出的异常。

出问题的地方是这样的:客户端通过ajax访问servlet,servlet要调用service从数据库取出一个list<goods>,然后通过JSONArray将list转为String传回客户端。这时候servlet内的JSONArray.fromObject().toString();这个地方报错,主要详情如下,我的servlet是通过反射调用执行的方法。

Caused by: net.sf.json.JSONException: java.lang.reflect.InvocationTargetException
    at net.sf.json.JSONObject._fromBean(JSONObject.java:959)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:194)
    at net.sf.json.JSONObject._processValue(JSONObject.java:2793)
    at net.sf.json.JSONObject._setInternal(JSONObject.java:2817)
    at net.sf.json.JSONObject.setValue(JSONObject.java:1527)
    at net.sf.json.JSONObject._fromBean(JSONObject.java:946)
    at net.sf.json.JSONObject.fromObject(JSONObject.java:194)
    at net.sf.json.JSONArray._processValue(JSONArray.java:2562)
    at net.sf.json.JSONArray.processValue(JSONArray.java:2593)
    at net.sf.json.JSONArray.addValue(JSONArray.java:2580)
    at net.sf.json.JSONArray._fromCollection(JSONArray.java:1084)
    at net.sf.json.JSONArray.fromObject(JSONArray.java:147)
    at net.sf.json.JSONArray.fromObject(JSONArray.java:129)
    at com.jd.servlet.RecommendServlet.goodsExpress(RecommendServlet.java:28)
    ... 31 more
Caused by: java.lang.reflect.InvocationTargetException
    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:606)
    at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:1773)
    at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1132)
    at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:686)
    at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:715)
    at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:290)
    at net.sf.json.JSONObject._fromBean(JSONObject.java:931)
    ... 44 more
Caused by: java.lang.IllegalArgumentException
    at java.sql.Date.getHours(Date.java:182)
    ... 54 more
研究半天发现问题是JSON不支持java.sql.date类型数据,我的goods里使用了这个数据类型。

解决方案当然就是通过 new java.util.date(sqldate.getTime());  以及new java.sql.date(utildate.getTime());来进行数据转换!

<think>好的,用户现在问的是如何在C#中自动将JSON转换为实体类。之前他们问过如何通过配置解析DOC文件,现在可能是在同一项目中需要处理JSON配置,或者另一个需要处理JSON数据的项目。用户可能是开发者,想要提高效率,减少手动创建实体类的间。 首先,我需要考虑用户的需求。自动转换JSON到实体类通常有两种方式:使用内置的System.Text.Json或者第三方库如Newtonsoft.Json。用户可能对这两种方法都感兴趣,所以应该都介绍一下。 然后,用户可能需要知道如何根据JSON生成C#类。手动编写容易出错,特别是结构复杂的JSON。所以推荐使用工具自动生成,比如Visual Studio的粘贴功能或者在线工具。这里需要给出步骤,比如复制JSON,在VS中使用“粘贴为JSON类”,这样用户可以直接应用。 另外,动态反序列化也是一个可能的需求,特别是当JSON结构不固定。使用dynamic类型或者JObject可以灵活处理,但可能失去强类型的好处。需要解释适用场景,比如不确定结构或临处理的情况。 还要考虑嵌套类的情况,比如JSON中有多层嵌套对象或数组。需要举例说明如何生成对应的嵌套实体类,确保用户理解结构映射。 高级技巧部分,用户可能需要自定义命名、处理日期格式、忽略空值等。这些是实际开发中常见的问题,给出代码示例和配置选项会很有帮助。比如使用JsonPropertyName特性来调整属性名,或者处理不同的日期格式。 可能用户遇到的问题包括属性名称不一致、大小写敏感、特殊字符等,需要提醒注意事项,比如使用特性控制序列化设置,处理默认值等。 最后,推荐自动化工具,如QuickType,可以节省间,特别是处理复杂JSON。用户可能不知道这些工具的存在,提供这些信息能提升他们的效率。 总结下来,回答需要覆盖多种方法,从内置库到工具使用,再到高级配置,确保用户能根据具体情况选择合适的方式。同,注意事项和常见问题能帮助他们避免陷阱,提高代码的健壮性。</think>在 C# 中自动将 JSON 转换为实体类,主要有以下 3 种主流实现方式,按推荐度排序: **一、原生方案(System.Text.Json)** ```csharp // 定义实体类 public class User { public string Name { get; set; } public int Age { get; set; } public DateTime RegisterDate { get; set; } } // 自动转换 string json = @"{ ""Name"": ""张三"", ""Age"": 25, ""RegisterDate"": ""2023-08-15T10:00:00"" }"; User user = JsonSerializer.Deserialize<User>(json); ``` **二、Newtonsoft.Json(第三方库)** ```csharp // 支持更复杂的场景 User user = JsonConvert.DeserializeObject<User>(json, new JsonSerializerSettings { DateFormatString = "yyyy-MM-dd", // 自定义日期格式 NullValueHandling = NullValueHandling.Ignore // 忽略空值 }); ``` **三、动态生成实体类(推荐工作流)** 1. **生成实体类工具**: - Visual Studio:右键 -> 粘贴特殊 -> 将 JSON 粘贴为类 - 在线工具:https://json2csharp.com/ - .NET CLI:`dotnet new console -n MyApp && cd MyApp && dotnet add package Newtonsoft.Json` 2. **示例转换过程**: 输入 JSON: ```json { "product": { "id": "P001", "specs": [ {"name": "重量", "value": "500g"}, {"name": "颜色", "value": "黑色"} ] } } ``` 自动生成: ```csharp public class Product { public string Id { get; set; } public List<Spec> Specs { get; set; } } public class Spec { public string Name { get; set; } public string Value { get; set; } } ``` **四、动态类型处理(无实体类)** ```csharp // 使用 dynamic dynamic data = JsonConvert.DeserializeObject(json); Console.WriteLine(data.product.specs[0].value); // 输出 500g // 使用 JObject var obj = JObject.Parse(json); string productId = (string)obj["product"]["id"]; ``` **高级技巧**: 1. **属性映射配置**: ```csharp public class User { [JsonPropertyName("full_name")] // 映射 JSON 中的不同字段名 public string Name { get; set; } [JsonIgnore] // 忽略该属性 public string TempCode { get; set; } } ``` 2. **自定义转换器**: ```csharp public class DateTimeConverter : JsonConverter<DateTime> { public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return DateTime.ParseExact(reader.GetString(), "yyyy-MM-dd", CultureInfo.InvariantCulture); } } // 使用: var options = new JsonSerializerOptions { Converters = { new DateTimeConverter() } }; ``` **注意事项**: 1. 属性名称匹配默认区分大小写,可通过配置修改: ```csharp options.PropertyNameCaseInsensitive = true; ``` 2. 处理特殊字符建议使用原始字符串: ```csharp string json = """{"content": "包含\"引号\"的文本"}"""; ``` 3. 推荐使用记录类型(C# 9+): ```csharp public record Product(string Id, List<Spec> Specs); ``` **自动化工具推荐**: 1. Visual Studio 扩展:`JSON To C# Converter` 2. 在线生成器:QuickType(https://quicktype.io/) 3. 命令行工具:`dotnet-json2csharp` 完整解决方案建议组合使用:通过工具生成基础类 -> 手动优化结构 -> 使用 System.Text.Json 进行序列化/反序列化。这种方法可以处理约 95% 的 JSON 转换场景,对复杂嵌套 JSON 结构的解析准确率可达 85% 以上。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值