Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 序列化和反序列化属性不一致_Java_Spring Boot_Lombok_Mapstruct - Fatal编程技术网

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

Java 序列化和反序列化属性不一致,java,spring-boot,lombok,mapstruct,Java,Spring Boot,Lombok,Mapstruct,我有两个服务A和服务B 一些上游正在调用服务,请求示例json如下: type of given request model class here is ServiceARequest { "A": { "pwId": 0, "pwType": 0, "pwMode": 0 }, "B": "string", "C"

我有两个服务A服务B

一些上游正在调用服务,请求示例json如下:

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"
    }
  }
}
正如您所看到的,服务请求服务请求映射字段中存在一个问题,因为某些属性的大小写不同,但它们的类型相同

那么在这种情况下我该怎么办?我是否需要创建两个具有相同名称和不同属性名称的类,然后我需要将它们放在不同的包中,或者如果我对A、B和C使用相同的类,那么字段名称只能是pwidpwid

如何从ServiceARequest结构到ServiceBRequest进行这种映射 结构,然后使用MapStruct从ServiceBrense反向映射到ServiceAreRequest? ServiceBRequest和ServiceBreResponse的结构完全相同


在评论部分讨论后更新。

我不认为您必须在这里使用mapstruct。我的意思是你可以,但是首先你需要创建你想要映射的POJO,所以据我所知,它应该是映射到ServiceBRequest的ServiceARequest类,这里是问题所在。因为两个POJO都有类A和C的属性,但是A和C有不同的字段名,这取决于父类型,这意味着您必须为ServiceARequest定义类A,然后为ServiceBRequest定义不同版本的类A等等。然后映射会非常简单,而且是向前的,但是最终会得到一堆结构非常相似的类,所以它看起来不太好,也不整洁

我会以不同的方式处理。在代码中,可以对A和C使用相同的类,这并不重要。重要的是请求的json结构不同。因此,无论何时请求序列化/反序列化,都必须确保json结构正确,这意味着您只需要关心序列化/反序列化。在这里,
@jsonaas
很方便

如果我理解正确,您的服务会收到以下json:

{
  "A": {
    "pwId": 0,
    "pwType": 0,
    "pwMode": 0 
  },
  "B": "string",
  "C": {
    "ccNum": "string"
    }
}
json被映射到类
ServiceARequest
,它可以按如下方式实现(注意:所有类都必须有setter和getter,我只是使用它们来缩短代码):

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
perfecty。然后需要向服务B发送请求,因此需要定义
ServiceBRequest
类:

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));
我得到的结果是:

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

我认为这可能会有所帮助:@SergeiTonoian,我读了博客,但我仍然不清楚在我的情况下应该如何做。我不太明白这与MapStruct的关系。你能分享一些yohr Pojo/吗mappers@tusharRawat我已经发布了一个例子,说明如何在您的case@Filip,我需要以某种方式使用MapStruct来定义Mapper接口,这样映射是在内部为我完成的,而不是在外部完成的。我想使用MapStruct接口设计模式在内部进行映射,不使用我自己的映射器,那么是否可以使用MapStruct@tusharRawat嗯,你想画什么还不太清楚。MapStruct将一个类映射到另一个类,那么您希望exaclty映射哪些类?如果ServiceARequest到ServiceBRequest并对A和C使用相同的类,那么我有一个问题-为什么?如果ServiceARequest和ServiceBRequest是您自己的类,为什么它们不能具有相同的结构?假设您将ServiceARequest映射到ServiceBRequest,那么之后您会如何处理ServiceBRequest?好的。比如说,我有服务a和服务B的API规范,我不能更改任何人的API规范。在API规范中,我们得到了两个服务的json(请求/响应结构),因此如果我想从服务A中使用服务B,那么我必须按照服务B的API合同的给定请求结构发送请求,因此,我还需要根据Probelm语句中提到的服务B的请求Json来设计类及其成员变量。@Tusharawat我编辑了我的回答OK,那么我们可以使用MapStruct来实现吗?
{"CCM":{"A":{"pwid":0,"pwtype":0,"pwmode":0},"B":"string","C":{"ccnum":"string"}}}