简体   繁体   English

序列化和反序列化属性不一致

[英]Serialization and Deserialization property inconsistencies

I have 2 services A and service B .我有 2 个服务 A服务 B

Some upstream is calling service A with request sample json as:一些上游正在使用请求样本 json 调用服务 A:

type of given request model class here is ServiceARequest
{
  "A": {
    "pwId": 0,
    "pwType": 0,
    "pwMode": 0 
  },
  "B": "string",
  "C": {
    "ccNum": "string"
    }
}

I need to make request for service B from service A like this:我需要像这样从服务 A 请求服务 B:

type of given request model class here is ServiceBRequest
{ "CCM": {
    "A": {
    "pwid": 0,
    "pwyype": 0,
    "pwmode": 0 
  },
  "B": "string",
  "C": {
    "ccnum": "string"
    }
  }
}

As you can see there is an issue in mapping fields of ServiceARequest to ServiceBRequest as casing of some the properties are not same, but the type of them are same.如您所见,将ServiceARequest的字段映射ServiceBRequest存在问题,因为某些属性的大小写不同,但它们的类型相同。

So what should I do in this case?那么在这种情况下我应该怎么做呢? Do I need to create 2 classes with same name and different property names, then I need to put them under different packages, OR if I use the same classes for A, B and C, then field names can only be either pwid or pwId我是否需要创建 2 个具有相同名称和不同属性名称的类,然后我需要将它们放在不同的包下,或者如果我对 A、B 和 C 使用相同的类,那么字段名称只能是pwidpwId

How to do this kind of mapping from ServiceARequest structure to ServiceBRequest structure here and then inverse mapping from ServiceBResponse to ServiceARequest, using MapStruct ?如何使用MapStruct进行这种从 ServiceARequest 结构到 ServiceBRequest 结构的映射,然后从 ServiceBResponse 到 ServiceARequest 的反向映射? Structure of ServiceBRequest and ServiceBResponse are exactly same. ServiceBRequest 和 ServiceBResponse 的结构完全相同。

Updated after discussion in the comments section.在评论部分讨论后更新。

I don't see that you have to use mapstruct here.我没有看到你必须在这里使用 mapstruct 。 I mean you can, but first you would need to create POJOs you would like to map, so as I understood it should be ServiceARequest class mapped to ServiceBRequest, and here is the problem.我的意思是你可以,但首先你需要创建你想要 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. 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. And then mapping would be quite simple and strightforward, but you end up with a bunch of classes with quite similar structure, so it doesn't look great and neat.然后映射会非常简单明了,但是你最终会得到一堆结构非常相似的类,所以它看起来不太好和整洁。

I would approach it differently.我会以不同的方式处理它。 Inside your code you can use same classes for A and C, it doesn't matter.在您的代码中,您可以对 A 和 C 使用相同的类,这没关系。 What matters is different json structure for your requests.重要的是您的请求的不同 json 结构。 So whenever you requests serialized/deserialized you have to make sure that json structure is correct, which means you only have to care about serialization/deserialization.所以每当你请求序列化/反序列化时,你必须确保 json 结构是正确的,这意味着你只需要关心序列化/反序列化。 And here @JsonAlias can be handy.这里@JsonAlias可以派上用场。

If I understood correclty you get following json coming to your serviceA:如果我理解正确的话,你会得到关注 json 的服务A:

{
  "A": {
    "pwId": 0,
    "pwType": 0,
    "pwMode": 0 
  },
  "B": "string",
  "C": {
    "ccNum": "string"
    }
}

That json is mapped to class ServiceARequest , which can be implemented as follows (note: all classes must have setters and getters, I just ommit them to make the code shorter):即 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 and C classes: 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() {
    }
}

With those annotations your incoming json will be mapped to ServiceARequest perfeclty.使用这些注释,您传入的 json 将被映射到ServiceARequest完美。 Then you need to send a request to service B, so you need to define ServiceBRequest class:然后需要向服务B发送请求,所以需要定义ServiceBRequest class:

public class ServiceBRequest {

    @JsonProperty("CCM")
    private ServiceARequest ccm;

    @JsonCreator
    public ServiceBRequest(@JsonProperty("CCM") ServiceARequest serviceARequest) {
        this.ccm = serviceARequest;
    }
}

Then just create a new instance of ServiceBRequest and it can be sent to the service B. Here is the test code:然后只需创建一个新的 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));

The output I got:我得到的 output:

{"CCM":{"A":{"pwid":0,"pwtype":0,"pwmode":0},"B":"string","C":{"ccnum":"string"}}}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM