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

Mik*_*ike 6 java spring jackson redis

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

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

public class UserAccountAuthentication implements Authentication {
    private List<GrantedAuthority> authorities;
    private boolean authenticated = true;
    ...
}
Run Code Online (Sandbox Code Playgroud)

Jackson成功序列化了对象但未能将其反序列化,但有以下异常:

abstract types can only be instantiated with additional type information
Run Code Online (Sandbox Code Playgroud)

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

@JsonTypeInfo(
Run Code Online (Sandbox Code Playgroud)

但是我不能在这种情况下这样做,因为它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
Run Code Online (Sandbox Code Playgroud)

}


摘要GrantedAuthority只是填充SimpleGrantedAuthority.

所以我试过了:

objectMapper.registerSubtypes(SimpleGrantedAuthority.class);
Run Code Online (Sandbox Code Playgroud)

但仍然没有运气.

Ess*_*Boy 5

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

public class UserAccountAuthenticationSerializer extends JsonDeserializer<UserAccountAuthentication> {

@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<JsonNode> 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;
}
Run Code Online (Sandbox Code Playgroud)

}

这是我的json

{"authenticated":true,"authorities":[{"authority":"role1"},{"authority":"role2"}],"details":null,"principal":null,"credentials":null,"name":null}
Run Code Online (Sandbox Code Playgroud)

然后在POJO的顶部

@JsonDeserialize(using = UserAccountAuthenticationSerializer.class)
public class UserAccountAuthentication  implements Authentication {
Run Code Online (Sandbox Code Playgroud)

这是测试

@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);
Run Code Online (Sandbox Code Playgroud)

}