[英]Serialization and Deserialization property inconsistencies
我有 2 个服务 A和服务 B 。
一些上游正在使用请求样本 json 调用服务 A:
type of given request model class here is ServiceARequest
{
"A": {
"pwId": 0,
"pwType": 0,
"pwMode": 0
},
"B": "string",
"C": {
"ccNum": "string"
}
}
我需要像这样从服务 A 请求服务 B:
type of given request model class here is ServiceBRequest
{ "CCM": {
"A": {
"pwid": 0,
"pwyype": 0,
"pwmode": 0
},
"B": "string",
"C": {
"ccnum": "string"
}
}
}
如您所见,将ServiceARequest的字段映射到ServiceBRequest存在问题,因为某些属性的大小写不同,但它们的类型相同。
那么在这种情况下我应该怎么做呢? 我是否需要创建 2 个具有相同名称和不同属性名称的类,然后我需要将它们放在不同的包下,或者如果我对 A、B 和 C 使用相同的类,那么字段名称只能是pwid或pwId
如何使用MapStruct进行这种从 ServiceARequest 结构到 ServiceBRequest 结构的映射,然后从 ServiceBResponse 到 ServiceARequest 的反向映射? ServiceBRequest 和 ServiceBResponse 的结构完全相同。
在评论部分讨论后更新。
我没有看到你必须在这里使用 mapstruct 。 我的意思是你可以,但首先你需要创建你想要 map 的 POJO,所以据我所知,它应该是映射到 ServiceBRequest 的 ServiceARequest class,这就是问题所在。 Cause both POJOs has properties of classes A and C, but A and C have different fields names depending on parent type, which means you will have to define class A for ServiceARequest, then different version of class A for ServiceBRequest and so on. 然后映射会非常简单明了,但是你最终会得到一堆结构非常相似的类,所以它看起来不太好和整洁。
我会以不同的方式处理它。 在您的代码中,您可以对 A 和 C 使用相同的类,这没关系。 重要的是您的请求的不同 json 结构。 所以每当你请求序列化/反序列化时,你必须确保 json 结构是正确的,这意味着你只需要关心序列化/反序列化。 这里@JsonAlias
可以派上用场。
如果我理解正确的话,你会得到关注 json 的服务A:
{
"A": {
"pwId": 0,
"pwType": 0,
"pwMode": 0
},
"B": "string",
"C": {
"ccNum": "string"
}
}
即 json 映射到 class ServiceARequest
,可以如下实现(注意:所有类都必须有setter和getter,我只是省略它们以使代码更短):
public class ServiceARequest {
@JsonProperty("A")
private A a;
@JsonProperty("B")
private String b;
@JsonProperty("C")
private C c;
//you have to define an empty constructor
public ServiceARequest() {
}
}
A 和 C 类:
public class A {
@JsonProperty("pwid")
@JsonAlias("pwId")
private int pwId;
@JsonProperty("pwtype")
@JsonAlias("pwType")
private int pwType;
@JsonProperty("pwmode")
@JsonAlias("pwMode")
private int pwMode;
public A() {
}
}
public class C {
@JsonProperty("ccnum")
@JsonAlias("ccNum")
private String ccNum;
public C() {
}
}
使用这些注释,您传入的 json 将被映射到ServiceARequest
完美。 然后需要向服务B发送请求,所以需要定义ServiceBRequest
class:
public class ServiceBRequest {
@JsonProperty("CCM")
private ServiceARequest ccm;
@JsonCreator
public ServiceBRequest(@JsonProperty("CCM") ServiceARequest serviceARequest) {
this.ccm = serviceARequest;
}
}
然后只需创建一个新的 ServiceBRequest 实例,它就可以发送到服务 B。这是测试代码:
ObjectMapper mapper = new ObjectMapper();
//Json from your example mapped to serviceARequest
ServiceARequest serviceARequest = mapper.readValue("{\n" +
" \"A\": {\n" +
" \"pwId\": 0,\n" +
" \"pwType\": 0,\n" +
" \"pwMode\": 0 \n" +
" },\n" +
" \"B\": \"string\",\n" +
" \"C\": {\n" +
" \"ccNum\": \"string\"\n" +
" }\n" +
"}", ServiceARequest.class);
// create a new instance of serviceBRequest passing serviceARequest as parameter
// (we need serviceARequest to be a field CCM inside serviceBRequest)
ServiceBRequest serviceBRequest = new ServiceBRequest(serviceARequest);
//map serviceBRequest to json and print
System.out.println(mapper.writeValueAsString(serviceBRequest));
我得到的 output:
{"CCM":{"A":{"pwid":0,"pwtype":0,"pwmode":0},"B":"string","C":{"ccnum":"string"}}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.