2017-11-03 2 views
0

私はclass Admin extends User {}です。 AdminUserの両方が、私は右JaxRSサービスにこのJSONを送信しています@XmlRootElementJaxRSとJacksonとの多型

@XmlRootElement 
public class User { 
    .... 
} 

@XmlRootElement 
public class Admin extends User { 

    String statement; 
} 

を拡張します。ここでは

{ 
    "id": "84", 
    "content": "blablah", 
    "user": { 
     "id": 1, 
     "email": "[email protected]", 
     "name": "Nicolas", 
     "male": true, 
     "admin": true, 
     "statement":"hello world" 
    } 
} 

は、Webサービスです。コメントにはUserが含まれているはずですが、ここではstatementフィールドがUserに不明なAdminがあります。そのUserがあるので

@POST 
@Path("{id}/comments") 
public Response createComment(@PathParam("id") long topicId, Comment comment) { ... } 

Comment

はジャクソン Commentは受け付けていません Admin

@XmlRootElement 
public class Comment { 
    String id; 
    String content; 
    User user = null; 
} 

どのように私は、ジャクソンは、ユーザーの任意の種類を受け入れることを教えてください?ほとんどのJava EEと互換性のある(つまり、別のJsonハンドラを持つサーバと)互換性を持たせるには?

+0

あなたは@XmlElement(名前=「ユーザーを試してみましたが"、type = Admin.class)コメントクラス –

+0

必ずしも管理者ではありません。ユーザーまたは管理者がコメントを作成できます –

答えて

1

多型のオブジェクトとジャクソンのアプローチは、あなたが次にあなたは、単に使用することができます

"user": { 
    "type": "Admin", 
    ... 
} 

のようなものにあなたのJSONを変更することができれば、あなたのJSONにいくつかの追加のフィールドを追加し、@JsonTypeInfoを使用することです

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") 
@JsonSubTypes({ 
     @JsonSubTypes.Type(name = "User", value = User.class), 
     @JsonSubTypes.Type(name = "Admin", value = Admin.class) 
}) 
static class User { 
    public String id; 
} 

jsonを変更できない場合は、そのようなケースを処理するデフォルトの方法がなく、カスタムを直列化する必要があるため、複雑になることがありますr。そして、ベースの単純な場合は、次のようなものになります。

public static class PolymorphicDeserializer extends JsonDeserializer<User> { 
    ObjectMapper mapper = new ObjectMapper(); 

    @Override 
    public User deserialize(JsonParser p, DeserializationContext ctxt) 
      throws IOException, JsonProcessingException { 
     JsonNode tree = p.readValueAsTree(); 

     if (tree.has("statement")) // <= hardcoded field name that Admin has 
      return mapper.convertValue(tree, Admin.class); 

     return mapper.convertValue(tree, User.class); 

    } 
} 

をあなたはObjectMapper

ObjectMapper mapper = new ObjectMapper(); 
SimpleModule module = new SimpleModule(); 
module.addDeserializer(User.class, new PolymorphicDeserializer()); 
mapper.registerModule(module); 

または注釈付きでそれを登録できます。

@JsonDeserialize(using = PolymorphicDeserializer.class) 
class User { 
    public String id; 
} 
関連する問題