当前位置: 首页 > 面试题库 >

使用Jackson自定义JSON反序列化

左丘修齐
2023-03-14
问题内容

我正在使用Flickr
API
。调用该flickr.test.login方法时,默认的JSON结果为:

{
    "user": {
        "id": "21207597@N07",
        "username": {
            "_content": "jamalfanaian"
        }
    },
    "stat": "ok"
}

我想将此响应解析为Java对象:

public class FlickrAccount {
    private String id;
    private String username;
    // ... getter & setter ...
}

JSON属性应按以下方式映射:

"user" -> "id" ==> FlickrAccount.id
"user" -> "username" -> "_content" ==> FlickrAccount.username

不幸的是,我无法找到一种使用Annotations做到这一点的好方法。到目前为止,我的方法是将JSON字符串读入a Map<String, Object>并从中获取值。

Map<String, Object> value = new ObjectMapper().readValue(response.getStream(),
        new TypeReference<HashMap<String, Object>>() {
        });
@SuppressWarnings( "unchecked" )
Map<String, Object> user = (Map<String, Object>) value.get("user");
String id = (String) user.get("id");
@SuppressWarnings( "unchecked" )
String username = (String) ((Map<String, Object>) user.get("username")).get("_content");
FlickrAccount account = new FlickrAccount();
account.setId(id);
account.setUsername(username);

但是我认为,这是有史以来最不优雅的方式。有没有简单的方法,可以使用注释还是自定义反序列化器?

这对我来说将是很明显的,但是当然不起作用:

public class FlickrAccount {
    @JsonProperty( "user.id" ) private String id;
    @JsonProperty( "user.username._content" ) private String username;
    // ... getter and setter ...
}

问题答案:

您可以为此类编写自定义解串器。它可能看起来像这样:

class FlickrAccountJsonDeserializer extends JsonDeserializer<FlickrAccount> {

    @Override
    public FlickrAccount deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        Root root = jp.readValueAs(Root.class);

        FlickrAccount account = new FlickrAccount();
        if (root != null && root.user != null) {
            account.setId(root.user.id);
            if (root.user.username != null) {
                account.setUsername(root.user.username.content);
            }
        }

        return account;
    }

    private static class Root {

        public User user;
        public String stat;
    }

    private static class User {

        public String id;
        public UserName username;
    }

    private static class UserName {

        @JsonProperty("_content")
        public String content;
    }
}

之后,您必须为您的类定义一个反序列化器。您可以按照以下步骤进行操作:

@JsonDeserialize(using = FlickrAccountJsonDeserializer.class)
class FlickrAccount {
    ...
}


 类似资料:
  • 我试图用Jackson库创建复杂类的对象。每个对象都有一个模式,反序列化器需要使用该模式来解释JSON。我的问题是如何向反序列化器提供模式? 反序列化程序扩展了类JSONDeserializer,该类具有无参数构造函数和必须重写的抽象方法反序列化(解析器、上下文)。我想改用另一种方法反序列化(解析器、上下文、值),其中值是部分构造的对象,其中包括模式。也就是说,反序列化方法可以调用value。sc

  • 我目前正在尝试使用Jackson2.8.4将自定义映射类型序列化和反序列化为JSON。我已经设法基于这个答案实现了序列化,但我正在与反序列化作斗争。下面是一个例子:

  • 我想通过扩展默认的反序列化器来创建自己的反序列化器,在其后面设置更多的值: 如您所见,我还想将此DTO母类重用于其他DTO。 我没有找到任何这样的例子。我真的是世界上第一个 反序列化的“AsUsual”(p,ctxt)应该是什么 我应该使用什么motherclass?JsonDeserializer/StdDeserializer/UntypedObjectDeserializer 反序列化程序会

  • 我有下面的JSON,我正试图使用Jackson API反序列化它 我基本上需要一个附件类,它有一个AttachmentFile对象列表,如下所示: 如何使用自定义反序列化器实现这一点? 谢谢

  • 情况如下:我已经设法让Jackson反序列化以下通用 作为HTTP客户端,并使用exchange

  • 问题内容: 我在使用Gson解析JSON响应时遇到问题。 JSON字串: 我有这两个课程: 但是当使用Gson解析这个时我有一个异常。我知道这是因为响应数组的第一个元素不是对象,而是整数。 所以问题是,我能以某种方式解决它吗? 问题答案: 您必须编写一个 自定义反序列化器 。我会做这样的事情: 首先,您需要包括一个新的类,而不是已有的两个类: 然后,您需要一个自定义解串器,类似于以下内容: 然后,