使用jackson将子类属性包装到子键中

时间:2016-11-15 09:10:39

标签: java json jackson

我的REST服务需要返回格式为的信息:

{
  "code": 1000,
  "message": "Success",
  "description": null,
  "data": [
    {
      "custId": "00000023401443",
      "engName": "MISTER NORWAYTEST'S PASSPORT",
    }
  ]
}

其中JSON消息的第一层基本上类似于消息头,以提供有关消息传递的技术详细信息,而“data”键包含实际的业务信息。

如果我要创建一个类来反映这一点,我默认会出现这样的东西:

public class ResponseModel<T> implements Serializable{
    private Integer code;
    private String message;
    private String description;
    @JsonProperty(value = "data")
    private T dataObj;
}

但这样做会导致我的控制器都返回相同的对象而没有真正的业务上下文值到类名并降低了可读性:

@GetMapping("/profile/{userId}")
public ResponseEntity<ResponseModel> getProfile(@PathVariable String userId) {
...
}

我想要做的是将ResponseModel用作超类,然后将它们继承到具有真实业务上下文名称(例如客户或帐户)的子类中。但是为了遵守所需的JSON格式,我需要确保将子类的属性包装成“数据”键。

我有办法做到这一点吗?使用@JsonRootName也会包装超类属性。

1 个答案:

答案 0 :(得分:1)

您想要的格式问题就在这里:

"data": *[* <---- HERE THAT BRACKET

如果您想要一个支架,这意味着您的数据是一个列表,那么您需要通过dataObj列表来修复它:

@JsonProperty(value = "data")
private List<T> dataObj;

现在我没有看到继承ResponseModel的重点,您可以执行以下操作:

public ResponseEntity<ResponseModel> myControllerMethod(){
    List<Account> list = myService.readAccounts();
    return new ResponseModel<Account>(list);//default code OK,...
}

如果你使你的Business类继承了ResponseModel,它只是一个处理控制器结果的包装器,你将把你的业务层与控制器的特定层混合起来,这不是一个好主意。

  

但这样做会导致我的控制器都返回相同的对象而没有真正的业务上下文值到类名并降低了可读性:

在Java的控制器中,你假设只有非常少的行,基本上,调用服务,检查答案/处理异常,返回响应。所以我没有看到任何可读性问题,因为如果这样的话。如果您谈论通用返回值,只需正确命名您的方法。