2016-03-01 48 views
6

我需要保存和加載對象從redis。傑克遜反序列化與春天的界面列表對象

對象包含的GrantedAuthority的名單(除其他事項外),這是一個接口:

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

傑克遜成功序列化對象,但失敗並出現以下異常反序列化:

abstract types can only be instantiated with additional type information 

我知道我可以指定類型加入:

@JsonTypeInfo(

B ut我不能這樣做,因爲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); 

,仍然沒有運氣。

+0

你看看你的getter和setter方法是正確寫入? –

+0

沒有getter和setter它的對象在內部工作的私人列表。 – Mike

回答

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; 
} 

}

這是我的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); 

}

+0

我跟着你的代碼一步一步,並得到它的編譯,但是當它運行「反序列化程序」永遠不會斷點,就好像它從不運行,我得到這個錯誤:org.codehaus.jackson.map.JsonMappingException:不能反序列化的實例com.coronet.online.security.GrantedAuthorityContainer out of START_ARRAY token at [Source:[email protected];行:1,列:2](通過參考鏈:com.coronet.online.security.UserAccountAuthentication [「權威」]) – Mike

+0

你可以發佈你的JSON,我已經添加了我的測試中使用的賈森。 –

+0

現在這樣做...... – Mike