【问题标题】:Serialize and Deserialize Java object having vavr list序列化和反序列化具有 vavr 列表的 Java 对象
【发布时间】:2021-08-14 18:43:04
【问题描述】:

我有一个带有 vavr 列表的 Java 对象。

@Value
@Builder(toBuilder = true)
public class Customer {

    private final List<Remark> remarks;

}

当我序列化对象 objectwriter.writeValueAsString(currentDossier) 并在我看到的 JSON 输出中打印值时,

    { "remarks" : {
        "empty" : true,
        "lazy" : false,
        "async" : false,
        "traversableAgain" : true,
        "sequential" : true,
        "ordered" : false,
        "singleValued" : false,
        "distinct" : false,
        "orNull" : null,
        "memoized" : false
      } 
    }

其中备注是对象内的 vavr 列表字段。

现在,如果我尝试将相同的值反序列化到对象 objectMapper.readValue(json, Customer.class) 中,则会出现错误:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `io.vavr.collection.List` 
(no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: (String)"{"remarks" : {

为什么尝试反序列化时序列化的 JSON 文本不起作用?

  @Test
  public void mapperForVavrList() throws JsonProcessingException {
    Customer cus = Customer.builder().remarks(List.empty()).build();

    ObjectWriter ow = new ObjectMapper()
      .writer().withDefaultPrettyPrinter();

    String json1 = ow.writeValueAsString(cus);

    log.info(json1);

    ObjectMapper objectMapper = new ObjectMapper();
    Customer cus2 = objectMapper.readValue(json1, Customer.class);

    log.info(cus2.toString());

  }

Java 代码中是否有其他方法可以以文本格式打印 vavr 对象并将其转换回 POJO?

【问题讨论】:

标签: java json jackson vavr


【解决方案1】:

您可以使用 jackson 轻松地将 vavr 对象序列化/反序列化到 JSON。你需要做的是在ObjectMapper的实例上注册VavrModule

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new VavrModule());

要获取VavrModule,您需要将依赖项添加到vavr-jackson

编辑

在这里您可以找到一个完整的工作示例:

import com.fasterxml.jackson.databind.ObjectMapper;
import io.vavr.collection.List;
import io.vavr.jackson.datatype.VavrModule;
import org.apache.commons.lang3.builder.ToStringBuilder;

import java.io.IOException;

class Lol2 {

    public static void main(String[] args) throws IOException {
        Customer c = new Customer();
        Remark r = new Remark();
        r.whatever = "whatever";
        c.remarks = List.of(r);

        ObjectMapper ow = new ObjectMapper();
        ow.registerModule(new VavrModule());

        System.out.println(c);
        String json = ow.writeValueAsString(c);
        System.out.println(json);
        Customer c2 = ow.readValue(json, Customer.class);
        System.out.println(c2);

    }
}

class Customer {

    List<Remark> remarks;

    public List<Remark> getRemarks() {
        return remarks;
    }

    public void setRemarks(List<Remark> remarks) {
        this.remarks = remarks;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this)
            .append("remarks", remarks)
            .toString();
    }
}

class Remark {

    String whatever;

    public String getWhatever() {
        return whatever;
    }

    public void setWhatever(String whatever) {
        this.whatever = whatever;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this)
            .append("whatever", whatever)
            .toString();
    }
}

【讨论】:

  • 现在我收到错误Can not deserialize instance of io.vavr.collection.List out of START_OBJECT token。我可以理解当我从某个外部源获取 json 输入时是否收到此错误,但这里我只是使用 jackson 对对象进行序列化和反序列化,所以不知道为什么会出现错误
  • 能否提供重现此问题的代码:sscce.org?w
  • 我在问题中使用mapperForVavrList() 中的相同代码。刚刚添加了objectMapper.registerModule(new VavrModule()); 行。然后我在Customer cus2 = objectMapper.readValue(json1, Customer.class); 行得到错误
  • @firstpostcommenter 请查看我编辑的答案。此外,这不是您使用的代码。没有提供Remark 类。
  • @firstpostcommenter,当您寻求帮助时,您应该尊重其他人在空闲时间免费帮助您。用一个好的、可复制的例子来浪费他们的时间。
猜你喜欢
  • 2018-02-27
  • 1970-01-01
  • 2018-07-11
  • 1970-01-01
  • 2015-06-12
  • 2016-10-14
  • 2014-12-24
  • 2013-04-11
  • 1970-01-01
相关资源
最近更新 更多