jackson使用spring接口列表反序列化对象

我需要从redis保存和加载对象。

该对象包含GrantedAuthority(以及其他内容)的列表,它是一个接口:

public class UserAccountAuthentication implements Authentication { private List authorities; private boolean authenticated = true; ... } 

Jackson成功序列化了对象但未能通过以下exception对其进行反序列化:

 abstract types can only be instantiated with additional type information 

我知道我可以通过添加以下内容来指定类型:

 @JsonTypeInfo( 

但是我不能在这种情况下这样做,因为GrantedAuthority是Spring的一个接口,我不能改变它。


序列化的json是:

 { "authorities": [ { "authority": "ROLE_NORMAL_USER" } ], "authenticated": true, "securityToken": { "expiration": 1458635906853, "token": "sxKi3Pddfewl2rgpatVE7KiSR5qGmhpGl0spiHUTLAAW8zuoLFE0VLFYcfk72VLnli66fcVmb8aK9qFavyix3bOwgp1DRGtGacPI", "roles": [ "ROLE_NORMAL_USER" ], "expired": false, "expirationDateFormatted": "2016-03-22 08:38:26.853 UTC" }, "name": "admin", "expired": false 

}


抽象的GrantedAuthority只用SimpleGrantedAuthority填充。

所以我试过:

 objectMapper.registerSubtypes(SimpleGrantedAuthority.class); 

但仍然没有运气。

我认为你需要添加一个自定义反序列化器

 public class UserAccountAuthenticationSerializer extends JsonDeserializer { @Override public UserAccountAuthentication deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { UserAccountAuthentication userAccountAuthentication = new UserAccountAuthentication(); ObjectCodec oc = jsonParser.getCodec(); JsonNode node = oc.readTree(jsonParser); userAccountAuthentication.setAuthenticated(node.get("authenticated").booleanValue()); Iterator elements = node.get("authorities").elements(); while (elements.hasNext()) { JsonNode next = elements.next(); JsonNode authority = next.get("authority"); userAccountAuthentication.getAuthorities().add(new SimpleGrantedAuthority(authority.asText())); } return userAccountAuthentication; } 

}

这是我的json

 {"authenticated":true,"authorities":[{"authority":"role1"},{"authority":"role2"}],"details":null,"principal":null,"credentials":null,"name":null} 

然后在你POJO的顶部

 @JsonDeserialize(using = UserAccountAuthenticationSerializer.class) public class UserAccountAuthentication implements Authentication { 

这是测试

 @Test public void test1() throws IOException { UserAccountAuthentication userAccountAuthentication = new UserAccountAuthentication(); userAccountAuthentication.setAuthenticated(true); userAccountAuthentication.getAuthorities().add(new SimpleGrantedAuthority("role1")); userAccountAuthentication.getAuthorities().add(new SimpleGrantedAuthority("role2")); String json1 = new ObjectMapper().writeValueAsString(userAccountAuthentication); UserAccountAuthentication readValue = new ObjectMapper().readValue(json1, UserAccountAuthentication.class); String json2 = new ObjectMapper().writeValueAsString(readValue); assertEquals(json1, json2); 

}