Using Gson with Interface Types

前端 未结 6 814
生来不讨喜
生来不讨喜 2020-12-03 03:16

I am working on some server code, where the client sends requests in form of JSON. My problem is, there are a number of possible requests, all varying in small implementatio

6条回答
  •  离开以前
    2020-12-03 03:18

    Assuming that the different possible JSON requests you may have are not extremely different to each other, I suggest a different approach, simpler in my opinion.

    Let's say that you have these 3 different JSON requests:

    {
        "type":"LOGIN",
        "username":"someuser",
        "password":"somepass"
    }
    ////////////////////////////////
    {
        "type":"SOMEREQUEST",
        "param1":"someValue",
        "param2":"someValue"
    }
    ////////////////////////////////
    {
        "type":"OTHERREQUEST",
        "param3":"someValue"
    }
    

    Gson allows you to have a single class to wrap all the possible responses, like this:

    public class Request { 
      @SerializedName("type")   
      private String type;
      @SerializedName("username")
      private String username;
      @SerializedName("password")
      private String password;
      @SerializedName("param1")
      private String param1;
      @SerializedName("param2")
      private String param2;
      @SerializedName("param3")
      private String param3;
      //getters & setters
    }
    

    By using the annotation @SerializedName, when Gson try to parse the JSON request, it just look, for each named attribute in the class, if there's a field in the JSON request with the same name. If there's no such field, the attribute in the class is just set to null.

    This way you can parse many different JSON responses using only your Request class, like this:

    Gson gson = new Gson();
    Request request = gson.fromJson(jsonString, Request.class);
    

    Once you have your JSON request parsed into your class, you can transfer the data from the wrap class to a concrete XxxxRequest object, something like:

    switch (request.getType()) {
      case "LOGIN":
        LoginRequest req = new LoginRequest(request.getUsername(), request.getPassword());
        break;
      case "SOMEREQUEST":
        SomeRequest req = new SomeRequest(request.getParam1(), request.getParam2());
        break;
      case "OTHERREQUEST":
        OtherRequest req = new OtherRequest(request.getParam3());
        break;
    }
    

    Note that this approach gets a bit more tedious if you have many different JSON requests and those requests are very different to each other, but even so I think is a good and very simple approach...

提交回复
热议问题