GVKun编程网logo

如何通过Jackson的注释定义通用列表反序列化器?(jackson 反序列化 指定具体类型)

6

此处将为大家介绍关于如何通过Jackson的注释定义通用列表反序列化器?的详细内容,并且为您解答有关jackson反序列化指定具体类型的相关问题,此外,我们还将为您介绍关于.NET4是否具有内置的JS

此处将为大家介绍关于如何通过Jackson的注释定义通用列表反序列化器?的详细内容,并且为您解答有关jackson 反序列化 指定具体类型的相关问题,此外,我们还将为您介绍关于.NET 4是否具有内置的JSON序列化器/反序列化器?、c# – 使用带有JSON.Net的自定义反序列化器反序列化JSON、Gson、jackson 序列化,反序列化(单个、集合)、Jackson json序列化和反序列化工具类的有用信息。

本文目录一览:

如何通过Jackson的注释定义通用列表反序列化器?(jackson 反序列化 指定具体类型)

如何通过Jackson的注释定义通用列表反序列化器?(jackson 反序列化 指定具体类型)

假设我有一个具有列表属性的对象:

public class Citizen {    name    List<Tickets> tickets    List<Fines> fines}

我想通过注释为列表定义一个通用的自定义反序列化器:

public class Citizen {    ...    @JsonDeserializer(MyListDeserializer<Tickets>) // <-- generic deserializer    public void setTickets(List<Tickets> tickets) {        this.tickets = tickets;    }    @JsonDeserializer(MyListDeserializer<Fines>) // <-- how can I do that?     public void setFines(List<Fines> fines) {        this.fines = fines;    }}

我正在寻找一种创建“通用”反序列化器的方法-
一种能够对两种类型的列表进行反序列化的方法,类似于ContextualDeserializer,用于使用Jackson将JSON映射到不同类型的地图。

最终目的是实现自定义反序列化逻辑,MyListDeserializer以将空字符串反序列""化为空列表,但是我想了解一种通用方法,而不仅仅是空字符串。

答案1

小编典典

您可以指定反序列化器类,使用该类对带有注释contentUsing属性的列表元素进行反序列化@JsonDeserializer

public class Citizen {    ...    @JsonDeserializer(contentUsing=MyListDeserializer.class)     public void setTickets(List<Tickets> tickets) {        this.tickets = tickets;    }}

使解串器扩展,JsonDeserializer<BaseClass>并在BaseClass中具有一个属性,该属性存储具体类的实际类型。

abstract class BaseTickets {    String ticketType;    public String getTicketType()}public class MyListDeserializer extends JsonDeserializer<BaseTickets> {    @Override    public BaseTickets deserialize(JsonParser jsonParser, DeserializationContext arg1) throws IOException, JsonProcessingException {        ObjectCodec oc = jsonParser.getCodec();        JsonNode node = oc.readTree(jsonParser);        Iterator<JsonNode> elements = node.getElements();        for (; elements.hasNext();) {            String type = (String) elements.next().get("ticketType");            if (type.equals()){               //create concrete type here            }        }     }

或者,如果您要为所有没有通用基类的List类型使用一个反序列化器,则可以使用using属性具有MyListDeserializerextend
JsonDeserialize<Object>。为了确定list元素的类型,您必须编写一个自定义的序列化程序,将类型信息添加到列表中,然后可以在通用反序列化程序中使用它。

public class Citizen {    ...    @JsonDeserializer(using=MyListDeserializer.class)    @JsonSerializer(using=MyListSerializer.class)     public void setTickets(List<Tickets> tickets) {        this.tickets = tickets;    }}public class MyListSerializer extends JsonSerializer<Object> {    @Override    public void serialize(Object list, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {        @SuppressWarnings("rawtypes")        jgen.writeStartObject();        String type = getListType(list);        jgen.writeStringField("listType", type);        jgen.writeObjectField("list", list)    }}

.NET 4是否具有内置的JSON序列化器/反序列化器?

.NET 4是否具有内置的JSON序列化器/反序列化器?

.NET 4是否附带任何可对JSON数据进行序列化/反序列化的类?

  • 我知道有第三方库,例如JSON.NET,但是我正在寻找内置在.NET中的东西。

  • 我在MSDN上找到了数据合同,但是它是用于WCF的,而不是Winforms或WPF的。

c# – 使用带有JSON.Net的自定义反序列化器反序列化JSON

c# – 使用带有JSON.Net的自定义反序列化器反序列化JSON

我有这样的 JSON:
{
  "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

Gson、jackson 序列化,反序列化(单个、集合)

Gson、jackson 序列化,反序列化(单个、集合)

实体类:

package com.nf.redisDemo1.entity;


public class News {

    private long id;
    private String title;
    private String body;

    public News() {
    }

    public News(String title, String body) {
        this.title = title;
        this.body = body;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    @Override
    public String toString() {
        return "News{" +
                "id=" + id +
                ", title=''" + title + ''\'''' +
                ", body=''" + body + ''\'''' +
                ''}'';
    }
}

Gson实现:

package com.nf.blog;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.nf.redisDemo1.entity.News;

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        News news = new News("2019快来了?你准备怎么过年呢?", "身为一个热爱IT行业的程序员,当然是写程序搞事情了。");
        Gson gson = new Gson();

        //单个对象的序列化及反序列化

        //序列化
        String newsStr = gson.toJson(news);
        System.out.println("JSON字符串:");
        System.out.println(newsStr);

        //反序列化
        News news_new = gson.fromJson(newsStr, News.class);
        System.out.println("实体对象:");
        System.out.println(news_new);

        //List集合的序列化和反序列化
        List<News> newsList = new ArrayList<>();
        newsList.add(news);
        newsList.add(new News("你想做的是什么呢?","多写代码,知道闭眼写一个项目为止。"));

        //序列化
        String newListStr = gson.toJson(newsList);
        System.out.println("集合序列化后:");
        System.out.println(newListStr);

        //反序列化
        List<News> newsList_new = gson.fromJson(newListStr, new TypeToken<List<News>>() {}.getType());
        System.out.println("JSON字符串反序列化:");
        System.out.println(newsList_new);


    }

}

 

 jascson 方式实现:

package com.nf.blog;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.nf.redisDemo1.entity.News;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) throws IOException {
        News news = new News("2019快来了?你准备怎么过年呢?", "身为一个热爱IT行业的程序员,当然是写程序搞事情了。");
        ObjectMapper objectMapper = new ObjectMapper();

        // jackson 单个对象的序列化及反序列化
        //序列化
        String newsStr = objectMapper.writeValueAsString(news);
        System.out.println("JSON字符串:");
        System.out.println(newsStr);

        //反序列化
        News news_new = objectMapper.readValue(newsStr,News.class);
        System.out.println("实体对象:");
        System.out.println(news_new);

        //List集合的序列化和反序列化
        List<News> newsList = new ArrayList<>();
        newsList.add(news);
        newsList.add(new News("你想做的是什么呢?","多写代码,知道闭眼写一个项目为止。"));

        //序列化
        String newListStr = objectMapper.writeValueAsString(newsList);
        System.out.println("集合序列化后:");
        System.out.println(newListStr);

        //反序列化
        List<News> newsList_new = objectMapper.readValue(newListStr, new TypeReference<List<News>>(){});
        System.out.println("JSON字符串反序列化成List集合:");
        System.out.println(newsList_new);

        News[] newsArr = objectMapper.readValue(newListStr,News[].class);
        System.out.println("JSON字符串反序列化成数组:");
        System.out.println(newsArr);


    }

}

 

 

止境(LC)

 

Jackson json序列化和反序列化工具类

Jackson json序列化和反序列化工具类

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.List;

/**
 * Jackson json序列化和反序列化工具类
 * Created by macro on 2018/4/26.
 */
public class JsonUtil {

    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 将对象转换成json字符串。
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json结果集转化为对象
     * 
     * @param jsonData json数据
     * @param beanType 对象中的object类型
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 将json数据转换成pojo对象list
     */
    public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
        try {
            List<T> list = MAPPER.readValue(jsonData, javaType);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
    
}

 

关于如何通过Jackson的注释定义通用列表反序列化器?jackson 反序列化 指定具体类型的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于.NET 4是否具有内置的JSON序列化器/反序列化器?、c# – 使用带有JSON.Net的自定义反序列化器反序列化JSON、Gson、jackson 序列化,反序列化(单个、集合)、Jackson json序列化和反序列化工具类等相关知识的信息别忘了在本站进行查找喔。

本文标签: