使用 Spring @RequestBody 将负载中具有混合约定的 JSON 转换为实体对象

Using Spring @RequestBody to convert JSON with mixed convention in payload to Entity Object

我正在使用 Spring @RequestBody 将 JSON 有效负载映射到 Java 对象。不幸的是,这个 JSON 有效载荷没有使用集合约定,而是具有同时使用驼峰式和 snake_case.

的名称

要清楚我的 Controller 看起来像这样:

@RequestMapping(value="/mobile/device", method = RequestMethod.PUT)
public ResponseEntity<Object> flagDevice (@RequestBody List<MobileDeviceData> deviceInfoList) {
    ... code here ...
}

MobileDeviceData Entity 对象有多个 setter 方法,例如:

public void setDeviceName(String deviceName) {
    this.deviceName = deviceName;
}

public void setFlagId(int flagId) {
    this.flagId = flagId;
}

当 JSON 对象名称是 camelCase 时,这非常有效并且无需任何额外的努力。但是对于 snake_case 名称,我需要添加 Annotation:

@JsonProperty("flag_id")
private int flagId;

以便它被拾取。

我知道如果可以避免使用 @JsonProperty 不是一个好主意,因为您需要对每个参数进行注释。我的问题是,是否有更通用的方法来强制匹配 snake_case 与 Entity 对象中相应的驼峰命名法?显然要做到这一点而不会搞砸那些已经是驼峰式的。

根据 article here,有一种简单的方法可以反序列化 MobileDeviceData class。下面是示例代码:

@JsonDeserialize(using = UserDeserializer.class)
public class User {
    private ObjectId id;
    private String   username;
    private String   password;
    public User(ObjectId id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public ObjectId getId()       { return id; }
    public String   getUsername() { return username; }
    public String   getPassword() { return password; }
}

假设用户是 class 我们有兴趣为其编写反序列化器。这里没什么值得注意的,除了告诉 Jackson 谁知道 deserialize 这个 class.

的注释
public class UserDeserializer extends JsonDeserializer {
    @Override
    public User deserialize(JsonParser jsonParser,
            DeserializationContext deserializationContext) throws IOException {
        ObjectCodec oc = jsonParser.getCodec();
        JsonNode node = oc.readTree(jsonParser);
        return new User(null,
                node.get("username").getTextValue(),
                node.get("password").getTextValue());
    }
}

反序列化器是通过扩展 Jackson 的抽象 JsonDeserializer class 并赋予它我们想要 deserialize 的类型来创建的。很难弄清楚您可以通过 field nameJsonParserObjectCodec.

引用 JSON

希望对您有所帮助。 如有需要请随时评论!

经过一段时间的研究,我现在意识到按照要求做任何事情都会适得其反。

当您收到(反序列化)一个 JSON 对象时,通常期望您使用相同的参数传递(序列化)。如果一个实现以相同的方式提取驼峰式和下划线参数,那么它就不知道以后如何正确反序列化。通过遵循标准约定,然后对所有异常使用 @JsonProperty,仍然可以反序列化并稍后像接收到的那样交付 JSON 对象。