使用 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 name
和 JsonParser
的 ObjectCodec
.
引用 JSON
希望对您有所帮助。
如有需要请随时评论!
经过一段时间的研究,我现在意识到按照要求做任何事情都会适得其反。
当您收到(反序列化)一个 JSON 对象时,通常期望您使用相同的参数传递(序列化)。如果一个实现以相同的方式提取驼峰式和下划线参数,那么它就不知道以后如何正确反序列化。通过遵循标准约定,然后对所有异常使用 @JsonProperty
,仍然可以反序列化并稍后像接收到的那样交付 JSON 对象。
我正在使用 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 name
和 JsonParser
的 ObjectCodec
.
希望对您有所帮助。 如有需要请随时评论!
经过一段时间的研究,我现在意识到按照要求做任何事情都会适得其反。
当您收到(反序列化)一个 JSON 对象时,通常期望您使用相同的参数传递(序列化)。如果一个实现以相同的方式提取驼峰式和下划线参数,那么它就不知道以后如何正确反序列化。通过遵循标准约定,然后对所有异常使用 @JsonProperty
,仍然可以反序列化并稍后像接收到的那样交付 JSON 对象。