簡體   English   中英

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

[英]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 使用相同的類,那么字段名稱只能是pwidpwId

如何使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM