如果您对c#–使用带有JSON.Net的自定义反序列化器反序列化JSON和c#json反序列化null值处理感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解c#–使用带有JSON.Net的自定义
如果您对c# – 使用带有JSON.Net的自定义反序列化器反序列化JSON和c# json反序列化null值处理感兴趣,那么这篇文章一定是您不可错过的。我们将详细讲解c# – 使用带有JSON.Net的自定义反序列化器反序列化JSON的各种细节,并对c# json反序列化null值处理进行深入的分析,此外还有关于.NET 4是否具有内置的JSON序列化器/反序列化器?、.Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程、@JsonCreator 自定义反序列化函数 - JSON 框架 Jackson 精解第 5 篇、c# – 用Json.Net反序列化,将子对象反序列化为字符串/类似的持有json?的实用技巧。
本文目录一览:- c# – 使用带有JSON.Net的自定义反序列化器反序列化JSON(c# json反序列化null值处理)
- .NET 4是否具有内置的JSON序列化器/反序列化器?
- .Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程
- @JsonCreator 自定义反序列化函数 - JSON 框架 Jackson 精解第 5 篇
- c# – 用Json.Net反序列化,将子对象反序列化为字符串/类似的持有json?
c# – 使用带有JSON.Net的自定义反序列化器反序列化JSON(c# json反序列化null值处理)
{ "MobileSiteContents": { "au/en": [ "http://www.url1.com","http://www.url2.com",],"cn/zh": [ "http://www.url2643.com",] } }
我正在尝试将其反序列化为IEnumerable类,如下所示:
public class MobileSiteContentsContentSectionItem : ContentSectionItem { public string[] Urls { get; set; } } public abstract class ContentSectionItem { public string Culture { get; set; } }
那可能吗?
我意识到我可能需要为此使用Custom JsonConverter,但找不到任何示例.
我开始编写一个使用JObject.Parse进行转换的方法,但不确定这是否是正确/最有效的路径:
public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json) { var jobject = JObject.Parse(json); var result = new List<MobileSiteContentsContentSectionItem>(); foreach (var item in jobject.Children()) { var culture = item.Path; string[] urls = new[] { "" }; //= this is the part I'm having troble with here... result.Add(new MobileSiteContentsContentSectionItem { Culture = culture,Urls = urls }); } return result; }
解决方法
>您正在迭代顶层对象的子节点,期望获得实际位于对象中的数据更低一级.您需要导航到MobileSiteContents属性的值并迭代它的子项.
>当您使用JObject的Children()时,使用允许您将它们转换为JProperty对象的重载;这将使您更容易提取所需的数据.
>从JProperty项目的名称中获取文化
>要获取网址,请获取JProperty项的值,并使用ToObject< string []>()将其转换为字符串数组.
这是更正后的代码:
public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json) { var jObject = JObject.Parse(json); var result = new List<MobileSiteContentsContentSectionItem>(); foreach (var item in jObject["MobileSiteContents"].Children<JProperty>()) { var culture = item.Name; string[] urls = item.Value.ToObject<string[]>(); result.Add(new MobileSiteContentsContentSectionItem { Culture = culture,Urls = urls }); } return result; }
如果您喜欢简洁的代码,可以将其减少为“单行”:
public IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json) { return JObject.Parse(json)["MobileSiteContents"] .Children<JProperty>() .Select(prop => new MobileSiteContentsContentSectionItem { Culture = prop.Name,Urls = prop.Value.ToObject<string[]>() }) .ToList(); }
演示:
class Program { static void Main(string[] args) { string json = @" { ""MobileSiteContents"": { ""au/en"": [ ""http://www.url1.com"",""http://www.url2.com"",""cn/zh"": [ ""http://www.url2643.com"",] } }"; foreach (MobileSiteContentsContentSectionItem item in Parse(json)) { Console.WriteLine(item.Culture); foreach (string url in item.Urls) { Console.WriteLine(" " + url); } } } public static IEnumerable<MobileSiteContentsContentSectionItem> Parse(string json) { return JObject.Parse(json)["MobileSiteContents"] .Children<JProperty>() .Select(prop => new MobileSiteContentsContentSectionItem() { Culture = prop.Name,Urls = prop.Value.ToObject<string[]>() }) .ToList(); } public class MobileSiteContentsContentSectionItem : ContentSectionItem { public string[] Urls { get; set; } } public abstract class ContentSectionItem { public string Culture { get; set; } } }
输出:
au/en http://www.url1.com http://www.url2.com cn/zh http://www.url2643.com
.NET 4是否具有内置的JSON序列化器/反序列化器?
.NET 4是否附带任何可对JSON数据进行序列化/反序列化的类?
我知道有第三方库,例如JSON.NET,但是我正在寻找内置在.NET中的东西。
我在MSDN上找到了数据合同,但是它是用于WCF的,而不是Winforms或WPF的。
答案1
小编典典您可以在任何需要的地方使用DataContractJsonSerializer类,它只是一个.net类,不仅限于WCF。有关如何在此处和此处使用它的更多信息。
.Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程
JSON作为一种轻量级的数据交换格式,简单灵活,被很多系统用来数据交互,作为一名.NET开发人员,JSON.NET无疑是最好的序列化框架,支持XML和JSON序列化,高性能,免费开源,支持LINQ查询。目前已被微软集成于webapi框架之中,因此,熟练掌握JSON.NET相当重要,这篇文章是零度参考官网整理的示例,通过这些示例,可以全面了解JSON.NET提供的功能。
Newtonsoft.Json的地址:
官网:http://json.codeplex.com/
源码地址:https://github.com/JamesNK/Newtonsoft.Json
Newtonsoft.Json.dll下载:https://github.com/JamesNK/Newtonsoft.Json/releases
1、使用Newtonsoft.Json(JSON.NET)序列化对象,通过Newtonsoft.Json.Formatting将json格式化输出。
Account account = new Account { Email = "1930906722@qq.com",Active = true,CreatedDate =DateTime.Now,Roles = new List<string> { "User","Admin" } }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(account,Newtonsoft.Json.Formatting.Indented); Console.WriteLine(json);
public class Account { public string Name { get; set; } public string Email { get; set; } public bool Active { get; set; } public DateTime CreatedDate { get; set; } public IList<string> Roles { get; set; } }
执行结果:
2、使用Newtonsoft.Json(JSON.NET)序列化List集合:
List<string> videogames = new List<string> { "HTML5","JavaScript",".net","c#",".net core" }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(videogames); Console.WriteLine(json);
执行结果:
3、使用Newtonsoft.Json(JSON.NET)序列化dictionary字典
System.Collections.Generic.Dictionary<string,string> dic = new System.Collections.Generic.Dictionary<string,string> { { "Name","张三" },{ "Age","20" },{ "Email","193090622@qq.com" } }; string json1 = Newtonsoft.Json.JsonConvert.SerializeObject(dic,Newtonsoft.Json.Formatting.Indented); Console.WriteLine(json1); Console.WriteLine(""); Console.WriteLine("未格式化的json:"); string json2 = Newtonsoft.Json.JsonConvert.SerializeObject(dic,Newtonsoft.Json.Formatting.None); Console.WriteLine(json2);
执行结果:
4、Newtonsoft.Json(JSON.NET)将序列化结果保存到指定的文件:
User movie = new User { Name = "张三",Age = 1993 }; using (System.IO.StreamWriter file = System.IO.File.CreateText(@"F:\UserInfo.txt")) { Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer(); serializer.Serialize(file,movie); }
public class User { public string Name { set; get; } public int Age { set; get; } }
执行后保存到文件的结果:
5、Newtonsoft.Json(JSON.NET)基于枚举类型的JsonConverters转换器
List<JosnEnum> list = new List<JosnEnum> { JosnEnum.NotStartus,JosnEnum.Startus }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(list); Console.WriteLine(json); Console.WriteLine(""); System.Collections.Generic.Dictionary<string,int> dic = new System.Collections.Generic.Dictionary<string,int> { {((JosnEnum)(int)JosnEnum.NotStartus).ToString(),(int)JosnEnum.NotStartus},{((JosnEnum)(int)JosnEnum.Startus).ToString(),(int)JosnEnum.Startus} }; string dicJson = Newtonsoft.Json.JsonConvert.SerializeObject(dic); Console.WriteLine(dicJson); Console.WriteLine(""); List<JosnEnum> list2 = new List<JosnEnum> { JosnEnum.NotStartus,JosnEnum.Startus }; string json3 = Newtonsoft.Json.JsonConvert.SerializeObject(list2,new Newtonsoft.Json.Converters.StringEnumConverter()); Console.WriteLine(json3); Console.WriteLine(""); List<JosnEnum> result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<JosnEnum>>(json3,new Newtonsoft.Json.Converters.StringEnumConverter()); Console.WriteLine(string.Join(",",result.Select(c => c.ToString())));
public enum JosnEnum { NotStartus = 0,Startus = 1 }
执行结果:
6、Newtonsoft.Json(JSON.NET)通过JRaw将JS函数序列化到JSON中
JavaScriptSettings settings = new JavaScriptSettings { OnLoadFunction = new Newtonsoft.Json.Linq.JRaw("OnLoad"),OnSucceedFunction = new Newtonsoft.Json.Linq.JRaw("function(e) { alert(e); }") }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(settings,Newtonsoft.Json.Formatting.Indented); Console.WriteLine(json);
public class JavaScriptSettings { public Newtonsoft.Json.Linq.JRaw OnLoadFunction { get; set; } public Newtonsoft.Json.Linq.JRaw OnSucceedFunction { get; set; } }
7、使用Newtonsoft.Json(JSON.NET)将json反序列化对象
string json = @"{ 'Email': '1930906722@qq.com','Active': true,'CreatedDate': '2016-11-26 20:39','Roles': [ 'User','Admin' ] }"; Account account = Newtonsoft.Json.JsonConvert.DeserializeObject<Account>(json); Console.WriteLine(account.Email);
public class Account { public string Name { get; set; } public string Email { get; set; } public bool Active { get; set; } public DateTime CreatedDate { get; set; } public IList<string> Roles { get; set; } }
执行结果:
8、使用Newtonsoft.Json(JSON.NET)反序列化List集合:
string json = @"['Html5','C#','.Net','.Net Core']"; List<string> videogames = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(json); Console.WriteLine(string.Join(",videogames));
执行结果:
9、使用Newtonsoft.Json(JSON.NET)反序列化dictionary字典
string json = @"{'Name': '张三','Age': '23'}"; var htmlAttributes = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string,string>>(json); Console.WriteLine(htmlAttributes["Name"]); Console.WriteLine(htmlAttributes["Age"]);
执行结果:
10、使用Newtonsoft.Json(JSON.NET)序列化var匿名类型,有时候,我们并不需要先定义一个类,然后new一个对象后再进行序列化,JSON.NET支持匿名类型的序列化和反序列化。
var test1 = new { Name = "李四",Age = 26 }; var json = Newtonsoft.Json.JsonConvert.SerializeObject(test1); Console.WriteLine(json); Console.WriteLine(""); var test2 = new { Name = "",Age = 0 }; string json1 = @"{'Name':'张三','Age':'25'}"; var result = Newtonsoft.Json.JsonConvert.DeserializeAnonymousType(json1,test2); Console.WriteLine(result.Name);
执行结果:
11、Newtonsoft.Json(JSON.NET)用新JSON字符串填充指定对象的属性值
Account account = new Account { Email = "1930906722@qq.com",CreatedDate = DateTime.Now,"Admin" } }; string json = @"{'Active': false,'Roles': ['Expired']}"; Newtonsoft.Json.JsonConvert.PopulateObject(json,account); Console.WriteLine(account.Active); Console.WriteLine(account.Email);
public class Account { public string Name { get; set; } public string Email { get; set; } public bool Active { get; set; } public DateTime CreatedDate { get; set; } public IList<string> Roles { get; set; } }
执行结果:
12、使用Newtonsoft.Json(JSON.NET)反序列化时可指定构造函数:
首先我们定义如下的类型,我们希望JSON.NET反序列化对象时使用第2个构造函数,我们将第一个默认构造函数屏蔽,标记为私有private修饰符。第2个构造函数需要指定一个website对象作为参数,如果提供的参数为null则抛出异常:
public class Website { public string Url { get; set; } private Website() { } public Website(Website website) { if (website == null) throw new ArgumentNullException("website"); Url = website.Url; } }
现在使用一般的方式反序列化一个JSON字符串。执行出现的结果:
我们发现该序列化方法抛出了异常,并没有按照我们预想的方式进行反序列化,JSON.NET提供如下的方式指定公有构造函数。
string json = @"{'Url':'http://www.cnblogs.com/linJie1930906722/'}"; Website website = Newtonsoft.Json.JsonConvert.DeserializeObject<Website>(json,new Newtonsoft.Json.JsonSerializerSettings { ConstructorHandling = Newtonsoft.Json.ConstructorHandling.AllowNonPublicDefaultConstructor }); Console.WriteLine(website.Url);
执行结果:
另外,JSON.NET提供了指定任何构造函数的JsonConstructorAttribute特性,只需要在构造函数上标记,即可指定构造函数。
public class Users { public string UserName { get; private set; } public bool Enabled { get; private set; } public Users() { } [Newtonsoft.Json.JsonConstructor] public Users(string userName,bool enabled) { UserName = userName; Enabled = enabled; } }
string json = @"{""UserName"": ""希特勒"",""Enabled"": true}"; Users user = Newtonsoft.Json.JsonConvert.DeserializeObject<Users>(json); Console.WriteLine(user.UserName);
执行结果:
13、当对象的属性为默认值(0或null)时不序列化该属性
public class Person { public string Name { get; set; } public int Age { get; set; } public Person Partner { get; set; } public decimal? Salary { get; set; } }
Person person1 = new Person(); string json1 = Newtonsoft.Json.JsonConvert.SerializeObject(person1,Newtonsoft.Json.Formatting.Indented,new Newtonsoft.Json.JsonSerializerSettings { DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore }); Console.WriteLine(json1); Console.WriteLine(""); Person person2 = new Person(){Name = "奥巴马"}; string json2 = Newtonsoft.Json.JsonConvert.SerializeObject(person2,new Newtonsoft.Json.JsonSerializerSettings { DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore }); Console.WriteLine(json2);
执行结果:
14、Newtonsoft.Json(JSON.NET)中忽略null值得处理器
public class Person { public string Name { get; set; } public int Age { get; set; } public Person Partner { get; set; } public decimal? Salary { get; set; } }
Person person = new Person { Name = "张三",Age = 46 }; string jsonIncludeNullValues = Newtonsoft.Json.JsonConvert.SerializeObject(person,Newtonsoft.Json.Formatting.Indented); Console.WriteLine(jsonIncludeNullValues); Console.WriteLine(""); string json = Newtonsoft.Json.JsonConvert.SerializeObject(person,new Newtonsoft.Json.JsonSerializerSettings { NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore }); Console.WriteLine(json);
执行结果:
15、JSON.NET中循环引用的处理方法
Employee employee1 = new Employee { Name = "张三" }; Employee employee2 = new Employee { Name = "李四" }; employee1.Manager = employee2; employee2.Manager = employee2; string json = Newtonsoft.Json.JsonConvert.SerializeObject(employee1,new Newtonsoft.Json.JsonSerializerSettings { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore }); Console.WriteLine(json);
public class Employee { public string Name { get; set; } public Employee Manager { get; set; } }
执行结果:
16、通过ContractResolver指定属性名首字母小写,通常,在.NET中属性采用PascalCase规则(首字母大写),在JavaScript中属性名使用CamelCase规则(首字母小写),我们希望序列化后的JSON字符串符合CamelCase规则,JSON.NET提供的ContractResolver可以设置属性名小写序列化
public class User { public string Name { set; get; } public int Age { set; get; } }
User person = new User { Name = "张三",Age =52 }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(person,new Newtonsoft.Json.JsonSerializerSettings { ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() }); Console.WriteLine(json);
执行结果:
17、JSON.NET中通过特性序列化枚举类型
public enum ProductStatus { NotConfirmed,Active,Deleted } public class Product { public string Name { get; set; } [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))] public ProductStatus Status { get; set; } }
Product user = new Product { Name = @"羽绒服",Status = ProductStatus.Deleted }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(user,Newtonsoft.Json.Formatting.Indented); Console.WriteLine(json);
执行结果:
18、指定需要序列化的属性
[Newtonsoft.Json.JsonObject(Newtonsoft.Json.MemberSerialization.OptIn)] public class Categroy { //Id不需要序列化 public Guid Id { get; set; } [Newtonsoft.Json.JsonProperty] public string Name { get; set; } [Newtonsoft.Json.JsonProperty] public int Size { get; set; } }
Categroy categroy = new Categroy { Id = Guid.NewGuid(),Name = "内衣",Size = 52 }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(categroy,Newtonsoft.Json.Formatting.Indented); Console.WriteLine(json);
执行结果:
19、序列化对象时指定属性名
public class Videogame { [Newtonsoft.Json.JsonProperty("name")] public string Name { get; set; } [Newtonsoft.Json.JsonProperty("release_date")] public DateTime ReleaseDate { get; set; } }
Videogame starcraft = new Videogame { Name = "英雄联盟",ReleaseDate = DateTime.Now }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(starcraft,Newtonsoft.Json.Formatting.Indented); Console.WriteLine(json);
执行结果:
20、序列化时指定属性在JSON中的顺序
public class Personl { [Newtonsoft.Json.JsonProperty(Order = 2)] public string FirstName { get; set; } [Newtonsoft.Json.JsonProperty(Order = 1)] public string LastName { get; set; } }
Personl person = new Personl { FirstName = "张三",LastName = "李四" }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(person,Newtonsoft.Json.Formatting.Indented); Console.WriteLine(json);
执行结果:
21、反序列化指定属性是否必须有值必须不为null,在反序列化一个JSON时,可通过JsonProperty特性的required指定反序列化行为,当反序列化行为与指定的行为不匹配时,JSON.NET将抛出异常,required是枚举,required.Always表示属性必须有值切不能为null,required.AllowNull表示属性必须有值,但允许为null值。
public class Order { [Newtonsoft.Json.JsonProperty(required = Newtonsoft.Json.required.Always)] public string Name { get; set; } [Newtonsoft.Json.JsonProperty(required = Newtonsoft.Json.required.AllowNull)] public DateTime? ReleaseDate { get; set; } }
string json = @"{ 'Name': '促销订单','ReleaseDate': null }"; Order order = Newtonsoft.Json.JsonConvert.DeserializeObject<Order>(json); Console.WriteLine(order.Name); Console.WriteLine(order.ReleaseDate);
执行结果:
22、通过特性指定null值忽略序列化
public class Vessel { public string Name { get; set; } [Newtonsoft.Json.JsonProperty(NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public DateTime? launchdate { get; set; } }
Vessel vessel = new Vessel { Name = "张三" }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(vessel,Newtonsoft.Json.Formatting.Indented); Console.WriteLine(json);
执行结果:
23、忽略不需要序列化的属性,并不是对象所有属性都要参与序列化,我们可以使用JsonIgnore特性排除不需要序列化的属性,下面示例中的PasswordHash将被忽略。
public class Accounts { public string FullName { get; set; } public string EmailAddress { get; set; } [Newtonsoft.Json.JsonIgnore] public string PasswordHash { get; set; } }
Accounts account = new Accounts { FullName = "admin",EmailAddress = "1930906722@qq.com",PasswordHash = "dfsfgerhtyhsasdhjyujtgwe454811sfsg8d" }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(account); Console.WriteLine(json);
执行结果:
24、序列化或反序列化时指定日期时间格式,JSON.NET中提供一个名为JsonSerializerSettings的设置对象,可通过此对象设置很多序列化和反序列化的行为,如果要设置JSON.NET序列化输出的日期时间格式,只需要指定格式化字符串即可。通过JsonSerializerSettings的DateFormatString属性指定日期时间格式:
public class Customer { public string FirstName { get; set; } public string LastName { get; set; } public DateTime CreateDate { get; set; } }
Customer custom = new Customer { FirstName = "张三",LastName = "李四",CreateDate = DateTime.Now }; Newtonsoft.Json.JsonSerializerSettings settings = new Newtonsoft.Json.JsonSerializerSettings { DateFormatString = "yyyy-MM-dd HH:mm:ss",Formatting = Newtonsoft.Json.Formatting.Indented }; string json = Newtonsoft.Json.JsonConvert.SerializeObject(custom,settings); Console.WriteLine(json);
执行结果:
@JsonCreator 自定义反序列化函数 - JSON 框架 Jackson 精解第 5 篇

转:
@JsonCreator 自定义反序列化函数 - JSON 框架 Jackson 精解第 5 篇
Jackson 是 Spring Boot (SpringBoot) 默认的 JSON 数据处理框架,但是其并不依赖于任何的 Spring 库。有的小伙伴以为 Jackson 只能在 Spring 框架内使用,其实不是的,没有这种限制。它提供了很多的 JSON 数据处理方法、注解,也包括流式 API、树模型、数据绑定,以及复杂数据类型转换等功能。它虽然简单易用,但绝对不是小玩具,更多的内容我会写成一个系列,5-10 篇文章,请您继续关注我。
- 《序列化与反序列化核心用法 - JSON 框架 Jackson 精解第 1 篇》
- 《特殊数据格式处理 - JSON 框架 Jackson 精解第 2 篇》
- 《属性序列化自定义排序与字母表排序 - JSON 框架 Jackson 精解第 3 篇》
- 《@JacksonInject 与 @JsonAlias 注解 - JSON 框架 Jackson 精解第 4 篇》
本节继续为大家介绍在 JSON 反序列化过程中,如何使用 @JsonCreator
注解和 @ConstructorProperties
注解自定义反序列化函数。
一、Jackson 反序列化过程做了什么?
对于 Jackson 的 JSON 数据格式,反序列化过程就是将 JSON 字符串反序列化为 java 对象。
ObjectMapper mapper = new ObjectMapper();
//将JSON字符串反序列化为java对象
String jsonInString = "{"name":"乔丹","age":45,"hobbies":["高尔夫球","棒球"]}";
PlayerStar3 jordan = mapper.readValue(jsonInString, PlayerStar3.class);
System.out.println(jordan);
默认情况下,Jackson 在反序列化过程中调用了哪些函数,给大家介绍一下
- 首先调用反序列化的目标类 PlayerStar3 的无参构造函数,构造一个 java 对象
- 然后调用该类的成员变量的 set 方法,为该对象的每一个成员变量赋值。
所以默认情况下,一个 Java 类使用 Jackson 做反序列化,必须有 public 无参构造函数 (java 中不写也默认有),必须有成员变量的 set 方法。
二、@JsonCreator
注解
默认情况下,Jackson 的反序列化过程是上面描述的那样,使用无参构造函数及 set 方法。除此之外,我们还可以使用 @JsonCreator
注解自定义反序列化的过程,在我们自定义的反序列化函数里面,我们有更强的灵活性,可以完成更多的非规定动作。一共有两种自定义反序列化渠道:
@JsonCreator
注解加在构造方法上@JsonCreator
注解加在工厂静态方法上
使用了 @JsonCreator
注解之后,将使用该注解标注的方法进行反序列化对象的构造,默认的使用无参构造函数及 set 方法进行反序列化的过程失效。
2.1.@JsonCreator
注解加在构造方法上
该 PlayerStar3 对应的 JSON 字符串是第一小节中的 jsonInString。下文的构造函数,你希望将哪些属性值赋值给 java 对象的成员变量,你就使用 @JsonProperty("salary")
去定义它。
public class PlayerStar3 {
private String name;
private Integer age;
private String[] hobbies; //业余爱好,数组
private List
friends; // 朋友
private Map
salary; //年收入 Map
//这段是我们的核心代码,使用JsonCreator注解说明该方法是反序列化构造方法。
@JsonCreator
public PlayerStar3(@JsonProperty("name") String name,
@JsonProperty("age") Integer age,
@JsonProperty("hobbies") String[] hobbies,
@JsonProperty("friends") List
friends,
@JsonProperty("salary") Map
salary) {
this.name = name;
this.age = age;
this.hobbies = hobbies;
this.friends = friends;
this.salary = salary;
}
//这里省略一个toString()方法
}
我们使用第一小节中的反序列化代码,将 jsonInString 反序列化构造 PlayerStar3 对象,控制台输出结果如下 (对象的 toString () 方法输出):
PlayerStar3{name=''乔丹'', age=45, hobbies=[高尔夫球, 棒球], friends=null, salary=null}
在 @JsonCreator
标注的构造方法里面下断点,也的确证明在 java 对象反序列化构造的过程中使用的是该方法。
2.2.@JsonCreator
注解加在工厂静态方法上
除了可以将 @JsonCreator
加在构造方法上,还可以使用静态工厂函数反序列化构造 java 对象。使用方法如下:
public class PlayerStar3 {
// 省略若干成员变量的定义,和上文一样
@JsonCreator
public static PlayerStar3 createPlayer(@JsonProperty("name") String name,
@JsonProperty("age") Integer age,
@JsonProperty("hobbies") String[] hobbies,
@JsonProperty("friends") List
friends,
@JsonProperty("salary") Map
salary) {
PlayerStar3 player = new PlayerStar3(); //new 一个java对象
player.name = name; //赋值
player.age = age;
player.hobbies = hobbies;
player.friends = friends;
player.salary = salary;
return player;
}
//这里省略一个toString()方法
}
使用 @JsonCreator
注解加在工厂静态方法上,可以达到一样的反序列化效果。
三、@ConstructorProperties
注解
@ConstructorProperties
注解的作用和 @JsonCreator
注解起到的作用是一致的,但是它只能加在构造方法上,作为反序列化函数。但是它的语法更简洁,使用起来也更加方便,不用 @JsonProperty
注解。又提供了灵活性,我们可以在构造方法反序列化过程中,针对该对象做更多的非规定操作。
@ConstructorProperties({"name", "age","hobbies", "friends","salary"})
public PlayerStar3(String name,
Integer age,
String[] hobbies,
List
friends,
Map
salary) {
this.name = name;
this.age = age;
this.hobbies = hobbies;
this.friends = friends;
this.salary = salary;
}
使用 @ConstructorProperties
注解加在构造方法上,可以达到一样的反序列化效果。
欢迎关注我的博客,里面有很多精品合集
- 本文转载注明出处(必须带连接,不能只转文字):字母哥博客。
觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。
- 《手摸手教你学 Spring Boot2.0》
- 《Spring Security-JWT-OAuth2 一本通》
- 《实战前后端分离 RBAC 权限管理系统》
- 《实战 SpringCloud 微服务从青铜到王者》
- 《VUE 深入浅出系列》
转:
@JsonCreator 自定义反序列化函数 - JSON 框架 Jackson 精解第 5 篇
--Posted from Rpc
c# – 用Json.Net反序列化,将子对象反序列化为字符串/类似的持有json?
考虑这个文件:
{ "cameras": [ { "type": "Some.Namespace.CameraClass","assembly": "Some.Assembly","configuration": { "ip": "127.0.0.1","port": 8080 } } ] }
在运行时,我将使用两个“类型”和“程序集”属性来构造支持特定接口的对象,然后我想将配置加载到该对象中.
但是,在编译时我不知道“配置”将映射到的类型.我想将它保留为json“属性”并将其提供给相机对象,然后让该对象将json反序列化为正确的类型.
因此,我想将包含特定相机类型配置的配置文件的一部分“随身携带”到对象本身,然后让它处理它,像我一样把它当作黑盒子处理它.应该保留该部分的结构,因为在为每个摄像机实现创建配置类型时我想要完全保真,甚至在必要时添加子对象.
对于这个特定的相机,我会配置一个IP地址和一个端口,对于其他一些相机我需要授权数据,而对于其他一些相机则完全不同.
我希望保持这种配置的属性能够直接获取Json,仍然是一个字符串.
这可能吗?
这是一个有一些位注释掉的LINQPad示例:
void Main() { const string configurationFile = @"[ { ""type"": ""UserQuery+Camera1"",""configuration"": { ""id"": 10 } },{ ""type"": ""UserQuery+Camera2"",""configuration"": { ""name"": ""The second camera"" } } ]"; var cameras = JsonConvert.DeserializeObject<Camera[]>(configurationFile); foreach (var camera in cameras) { var type = Type.GetType(camera.Type); var instance = Activator.CreateInstance(type,new object[0]) as ICamera; // instance.Configure(camera.Configuration); } } public class Camera { public string Type { get; set; } public JObject Configuration { get; set; } } public interface ICamera { void Configure(string json); } public class Camera1 : ICamera { private class Configuration { public int Id { get; set; } } public void Configure(string json) { JsonConvert.DeserializeObject<Configuration>(json).Dump(); } } public class Camera2 : ICamera { private class Configuration { public string Name { get; set; } } public void Configure(string json) { JsonConvert.DeserializeObject<Configuration>(json).Dump(); } }
两个注释掉的位,即Camera类中的属性,以及对Configure方法的调用,都是我想要的.
有什么东西我可以标记该属性,或者我可以为该属性选择的其他类型,这将使这工作吗?
我知道我可以使属性动态化,这会将JObject填入其中,但是每个相机实现的每个Configure方法都必须处理JObject而不是已知的非动态类型.
解决方法
using System; using System.IO; using Newtonsoft.Json; using Newtonsoft.Json.Linq; public class Foo { public string Name { get; set; } public int Age { get; set; } public JObject Configuration { get; set; } } public class Test { public static void Main() { var json = File.ReadAllText("test.json"); var foo = JsonConvert.DeserializeObject<Foo>(json); Console.WriteLine(foo.Configuration); } }
Test.json:
{ "name": "Jon","age": 10,"configuration": { "ip": "127.0.0.1","port": 8080 } }
输出:
{ "ip": "127.0.0.1","port": 8080 }
我怀疑你可以直接从JObject反序列化,但如果你真的想,你总是可以将它转换回字符串.
今天关于c# – 使用带有JSON.Net的自定义反序列化器反序列化JSON和c# json反序列化null值处理的介绍到此结束,谢谢您的阅读,有关.NET 4是否具有内置的JSON序列化器/反序列化器?、.Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程、@JsonCreator 自定义反序列化函数 - JSON 框架 Jackson 精解第 5 篇、c# – 用Json.Net反序列化,将子对象反序列化为字符串/类似的持有json?等更多相关知识的信息可以在本站进行查询。
本文标签: