Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.9k views
in Technique[技术] by (71.8m points)

java - Unable to deserialise via mixin

Attached is my json. I am receiving this from an endpoint. I have the object type in my consuming app. the object contains; success, message and loggedInMember (which is an object). In the json, the feeClasses contains a lot of fields and objects etc which is why i have not included the whole json. I am only interested in the success and message fields.

{
    "header":{
    "messageId":null,
            "receivedTimestamp":1611246394839,
            "replyTo":null,
            "redelivered":false,
            "originator":null
},
    "internalId":null,
        "auditPoints":[

],
        "success":true,
        "message":"",
        "loggedInMember":{
            "feeClasses":{
...CONTAINS A LOT OF FIELDS...
    }
}
}

I am trying to map this response to the object type, hence essentially leaving loggedInMembers null. This is my test I am trying to run:

   public void test() throws JsonProcessingException
   {
      //String json = "{"header":{"messageId":null,"bucketNumber":null,"senderSubId":null,"senderLocationId":null,"onBehalfOfCompId":null,"onBehalfOfSubId":null,"onBehalfOfLocationId":null,"correlationId":null,"receivedTimestamp":1611246394839,"replyTo":null,"redelivered":false,"originator":null},"internalId":null,"auditPoints":[],"success":true,"message":"","loggedInMember":{"memberLoginName":"BMARTINTEST","memberId":"201901241246290000036402D","settlementAccountIds":["201901241246290000036491D"],"parentMemberId":"1","firmId":"990","memberType":"INDIVIDUAL","memberAccountType":"PROD","password":"D1208B304FD7AA6187690A389A5040C1D9B07643","feeClasses":{"byId":{"201902120947520000559606D":{"memberLoginName":"BMARTINTEST","feeClassId":"201508041827550000942152D","memberFeeClassId":"201902120947520000559606D","allocatedDate":{"year":2019,"month":2,"day":12,"timeMillis":1549929600000},"firstUsedForTradeDate":{"year":2019,"month":2,"day":12,"timeMillis":1549929600000},"firstUsedForSettlementDate":null,"usableFromDate":{"year":2019,"month":2,"day":12,"timeMillis":1549929600000},"usableToDate":{"year":2019,"month":2,"day":19,"timeMillis":1550534400000},"usableToTimestamp":1550613600000,"usableBusinessDaysAllocated":6,"usableBusinessDaysRemaining":0,"narrative":"Bonus assigned to member at first-time funding of amount 4000.00 : Set expiration date/time","disabled":false,"usableForTrade":true,"usableForSettlement":true},"202001290940390000868824D":{"memberLoginName":"BMARTINTEST","feeClassId":"202001290940340000776406D","memberFeeClassId":"202001290940390000868824D","allocatedDate":{"year":2020,"month":1,"day":29,"timeMillis":1580256000000},"firstUsedForTradeDate":null,"firstUsedForSettlementDate":null,"usableFromDate":{"year":2020,"month":1,"day":6,"timeMillis":1578268800000},"usableToDate":{"year":2020,"month":2,"day":27,"timeMillis":1582761600000},"usableToTimestamp":1582840800000,"usableBusinessDaysAllocated":0,"usableBusinessDaysRemaining":0,"narrative":"Added NO_FEES_CLASS","disabled":false,"usableForTrade":true,"usableForSettlement":true},"201901241246290000036417D":{"memberLoginName":"BMARTINTEST","feeClassId":"201508041736360000943781D","memberFeeClassId":"201901241246290000036417D","allocatedDate":{"year":2019,"month":1,"day":24,"timeMillis":1548288000000},"firstUsedForTradeDate":null,"firstUsedForSettlementDate":null,"usableFromDate":{"year":2019,"month":1,"day":24,"timeMillis":1548288000000},"usableToDate":null,"usableToTimestamp":null,"usableBusinessDaysAllocated":0,"usableBusinessDaysRemaining":0,"narrative":null,"disabled":false,"usableForTrade":true,"usableForSettlement":true}},"empty":false},"legalName":"Martin Birch","taxId":"345335454","taxCountryId":"US","currency":"USD","lastTradeId":null,"introducingBrokerMemberId":null,"introducingBrokerMemberName":null,"introducingBrokerMemberCode":null,"clearedByMemberId":"SECOND_TEST","clearedByMemberLoginName":null,"memberProblems":[],"emailNotificationEnabled":true,"rtafLevelId":0,"rtafAmount":0,"maxNumberOfPositionAccounts":1,"ciciIdentifier":null,"traderRequired":false,"interestClass":"INDIVIDUAL","memberCreatedDate":1548333989000,"parentMemberLoginNames":["NADEX.COM","NADEX"],"demoStartDate":null,"demoEndDate":null,"clientIdMaxLimit":null,"memberAccountApplicationFieldData":null,"rank":0,"uuid":"201901241246290000036395D","referrerId":"raf4qam5h00s36d","testMember":false},"allReplyToSource":[],"sendToOriginatorOnly":false}";
String json = "{
" +
              "   "header":{
" +
              "      "messageId":null,
" +
              "      "receivedTimestamp":1611246394839,
" +
              "      "replyTo":null,
" +
              "      "redelivered":false,
" +
              "      "originator":null
" +
              "   },
" +
              "   "internalId":null,
" +
              "   "auditPoints":[
" +
              "      
" +
              "   ],
" +
              "   "success":true,
" +
              "   "message":"",
" +
              "   "loggedInMember":{
" +
              "      "feeClasses":{
" +
              "         
" +
              "      }
" +
              "   }
" +
              "}";
      ObjectMapper objectMapper = new ObjectMapper();
      objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
      objectMapper.addMixIn(LogonResponseMessage.class, LogonResponseMixin.class);

      LogonResponseMessage responseMessage = objectMapper.readValue(json, LogonResponseMessage.class);

      System.out.println(responseMessage);
   }

My mixin:

public abstract class LogonResponseMixin
{
   LogonResponseMixin(@JsonProperty("success") boolean success, @JsonProperty("message") String message){};

   @JsonIgnore
   abstract Member loggedInMember();

   @JsonIgnore
   abstract MemberFeeClasses feeClasses();

   @JsonIgnore
   abstract Header header();
}

I am getting the following error: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of domain.xyz.MemberFeeClasses (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

Am i creating the mixin wrong? I have asked in a previous question and using mixin was the general consensus but it doesn't seem to play ball with me.

Thank you.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The reason why MemberFeeClasses cannot be constructed is the same as your initial problem, just add a mixin for all classes

See the example below:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.Setter;

import java.io.IOException;

public class Test {

  //------------------------------------------------//
  //          PART 1 - MAIN TEST METHOD
  //------------------------------------------------//
  public static void main(String[] args) throws IOException {

    String json = "{
" +
        "   "header":{" +
        "   },
" +
        "   "success":true,
" +
        "   "message":"",
" +
        "   "loggedInMember":{
" +
        "      "feeClasses":{
" +
        "         "amount": "20"
" +
        "      }
" +
        "   }
" +
        "}";
    ObjectMapper objectMapper = new ObjectMapper();
    //objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    objectMapper.addMixIn(LogonResponseMessage.class, LogonResponseMixin.class);
    objectMapper.addMixIn(Member.class, MemberMixin.class);
    objectMapper.addMixIn(MemberFee.class, MemberFeeMixin.class);

    LogonResponseMessage responseMessage = objectMapper.readValue(json, LogonResponseMessage.class);

    System.out.println(responseMessage.loggedInMember.feeClasses.amount);
  }

  //------------------------------------------------//
  //          PART 2 - CREATOR MIXIN
  //------------------------------------------------//
  static abstract class LogonResponseMixin {
    LogonResponseMixin(@JsonProperty("success") boolean success,
                       @JsonProperty("message") String message,
                       @JsonProperty("header") Header header,
                       @JsonProperty("loggedInMember") Member member) {
    }
  }

  static abstract class MemberMixin {
    MemberMixin(@JsonProperty("feeClasses") MemberFee feeClasses) {
    }
  }

  static abstract class MemberFeeMixin {
    @JsonCreator
    MemberFeeMixin(@JsonProperty("amount") String amount) {
    }
  }

  //------------------------------------------------//
  //          PART 3 - EXAMPLE CLASS DEFINITION
  //------------------------------------------------//
  static class Header {
  }

  @Getter
  @Setter
  static class Member {
    private MemberFee feeClasses;

    public Member(MemberFee feeClasses) {
      this.feeClasses = feeClasses;
    }
  }

  @Getter
  @Setter
  static class MemberFee {
    private String amount;
    public MemberFee(String amount) {
      this.amount = amount;
    }
  }

  @Getter
  @Setter
  static class LogonResponseMessage {
    private boolean success;
    private String message;
    private Header header;
    private Member loggedInMember;

    public LogonResponseMessage(boolean success, String message, Header header, Member member) {
      this.success = success;
      this.message = message;
      this.header = header;
      this.loggedInMember = member;
    }
  }
}


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...