【问题标题】:Injecting additional fields in serialization在序列化中注入额外的字段
【发布时间】:2014-01-03 15:49:18
【问题描述】:

我有使用 Jackson 序列化的对象。例如

class A {
    int id;
    String value
}

被序列化为:

{
    "id": 1,
    "value": "test"
}

现在我想在序列化版本中添加一个附加字段

{
    "id": 1,
    "value": "test"
    "__errors__": [
        { field: "id", "message": "already in use" },
        { field: "value", "message": "field to long" },
    ]
}

该字段由Error类列表组成:

class Error {
    String field;
    String message;
}

这应该在序列化时完成,并且在不向 A 类添加方法/属性的情况下工作

那么有没有办法将其他字段注入到杰克逊映射器中?最好是一个通用方法,它适用于传递给映射器的所有类,无需额外代码。

(背景:我想用它在正常结果中向 AngularJS 返回验证错误。因为将两者放在容器中会使客户端的代码复杂化。)

提前致谢!

编辑:

想象最终的用法可能是这样的:

ObjectMapper mapper = ...;
PrintWriter out = ...;

// Normally the parsed user input
A a = new A( 5, "test" );

// Normally generated by validation of user input
List<Error> errors = Arrays.asList( new Error( "id", "already in use" ) );

// No write it as combined json
mapper.writeValue( out, a, error );
// ... or ...
customWrite( out, a, error );

EDIT2:

目前我正在研究两种可能的解决方案:

  1. 编写自定义序列化程序。似乎是一个干净的解决方案,但需要完成默认序列化程序所做的所有事情。但这是一个复杂的解决方案,因为我首先必须弄清楚自定义序列化和扩展默认值是如何工作的。
  2. 只需使用字符串替换和连接。分别编写两个对象并删除凝视/闭合花括号并将一个附加到另一个上。很快,但很脏。 (我真的不喜欢这个,但它可以工作。)

【问题讨论】:

  • 你想在什么时候注入错误?您能否为您希望错误注入的样子添加一些代码?您始终可以序列化为 ObjectNode,然后手动添加它。我只是想弄清楚您希望将错误数据存储在哪里。
  • 感谢您的评论。我添加了一个编辑。我希望这能让它更清楚。

标签: java json angularjs rest jackson


【解决方案1】:

您可以使用ObjectMapper.convertValue 方法轻松做到这一点。见下例:

A a = new A(101, "test");
List<Error> errors = Arrays.asList(new Error("id", "already in use"), new Error("value",
        "field to long"));

// Create Jackson objects
ObjectMapper jsonMapper = new ObjectMapper();
MapType mapType = jsonMapper.getTypeFactory().constructMapType(LinkedHashMap.class,
        String.class, Object.class);

// Create map
LinkedHashMap<String, Object> map = jsonMapper.convertValue(a, mapType);
map.put("__errors__", errors);

// Serialize map
String json = jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);

System.out.println(json);

以上示例打印:

{
  "id" : 101,
  "value" : "test",
  "__errors__" : [ {
    "field" : "id",
    "message" : "already in use"
  }, {
    "field" : "value",
    "message" : "field to long"
  } ]
}

【讨论】:

  • 不错!不知道我可以使用杰克逊来构建地图。正是我需要的。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-02
  • 2022-08-08
  • 1970-01-01
  • 2015-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多