Using Gson with Interface Types

前端 未结 6 834
生来不讨喜
生来不讨喜 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:40

    Polymorphic mapping of the type described is not available in Gson without some level of custom coding. There is an extension type adapter available as an extra that provides a bulk of the functionality you are looking for, with the caveat that the polymorphic sub-types need to be declared to the adapter ahead of time. Here is an example of its use:

    public interface Response {}
    
    public interface Request {
        public Response process();
    }
    
    public class LoginRequest implements Request {
        private String userName;
        private String password;
    
        // Constructors, getters/setters, overrides
    }
    
    public class PingRequest implements Request {
        private String host;
        private Integer attempts;
    
        // Constructors, getters/setters, overrides
    }
    
    public class RequestTest {
    
        @Test
        public void testPolymorphicSerializeDeserializeWithGSON() throws Exception {
            final TypeToken> requestListTypeToken = new TypeToken>() {
            };
    
            final RuntimeTypeAdapterFactory typeFactory = RuntimeTypeAdapterFactory
                    .of(Request.class, "type")
                    .registerSubtype(LoginRequest.class)
                    .registerSubtype(PingRequest.class);
    
            final Gson gson = new GsonBuilder().registerTypeAdapterFactory(
                    typeFactory).create();
    
            final List requestList = Arrays.asList(new LoginRequest(
                    "bob.villa", "passw0rd"), new LoginRequest("nantucket.jones",
                    "crabdip"), new PingRequest("example.com", 5));
    
            final String serialized = gson.toJson(requestList,
                    requestListTypeToken.getType());
            System.out.println("Original List: " + requestList);
            System.out.println("Serialized JSON: " + serialized);
    
            final List deserializedRequestList = gson.fromJson(serialized,
                    requestListTypeToken.getType());
    
            System.out.println("Deserialized list: " + deserializedRequestList);
        }
    }
    

    Note that you don't actually need to define the type property on the individual Java objects - it exists only in the JSON.

提交回复
热议问题