2016-03-01 11 views
6

私はレディスからオブジェクトを保存して読み込む必要があります。ジャックソンは、スプリングのインターフェースのリストを持つオブジェクトを逆直列化します

オブジェクトがインタフェースである(とりわけ)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を追加してタイプを指定できることを知っていますこの場合、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

あなたのコードをステップバイステップで実行してコンパイルしましたが、 "deserializer"を実行しても決してブレークポイントが実行されず、このエラーが発生した場合は、次のようになります:org.codehaus.jackson.map.JsonMappingException:インスタンスをdeserializeできませんSTART_ARRAYトークンのうちcom.coronet.online.security.GrantedAuthorityContainer [ソース:[email protected]; – Mike

+0

jsonを投稿できますか?Jasonをテストに追加しましたか? –

+0

今のところ... – Mike

関連する問題