2013-08-26 7 views
2

저는 유형 식별자가 다른 여러 유형의 묶음에 대한 래퍼 인 객체에 대해 Gson에서 사용자 정의 디시리얼라이저를 작성하려고합니다. 여기 GSON : 객체를 포함하는 String을 기반으로 내부 객체를 비 직렬화합니다.

내 문제 도메인의 간단한 개요입니다 : 나는 사용자가 관련이없는 도메인 객체의 다양한 포함 할 수 서로에게 메시지를 보낼 수있는

, 그리고 내가 좋아하는 뭔가를 직렬화하는 :

public class Message { 
    public String messageType; 
    public Object messageData; 
} 

JavaScript를 통해 messageData 객체가 생성되면 프로그래머는 모든 객체 유형을 하나의 필드 "messageData"로 막 잡기로 결정했습니다. messageData는 기본 클래스 또는 인터페이스를 공유하지 않는 User, Video, Website, Picture와 같은 여러 도메인 객체가 될 수 있습니다.

{ "messageType": "video", "messageData": { "videoId": 1, "videoTitle": "my vid" } } 

또는

{ "messageType": "picture", "messageData": { "pictureId": 1, "pictureUrl": "http://www.example.com/cat.jpg" } } 

목표는 messageType입니다 걸릴로 직렬화하기 위해 적절한 클래스를 선택하는 것을 사용하는 것입니다 : 같은

은 그래서 (간체) JSON 개체를 볼 수 있었다 .

나는 이런 식으로 뭔가 함께 올라와있다 :

public class MessageJsonDeserializer implements JsonDeserializer<Message> { 

    @Override 
    public Message deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 
     throws JsonParseException { 


     JsonObject obj = json.getAsJsonObject(); 
     Message message = new Message(); 
     message.messageType = obj.get("messageType").getAsString(); 
     message.messageData = MessageDataMapper.map(message.messageType, obj.get("messageData")); // maps and casts to the correct Video/Picture,Website etc.. 
     return message; 
    } 
} 

이 확인 작동하지만의 그 메시지가 자동으로 직렬화 할 수있는 다른 분야의 많은 계획을 가지고 생각한 것 같다, 나는 수동으로해야 할 것 JsonObject를 파싱하고 해당 필드를 추출합니다.

내가 하이브리드 방식을 사용할 수 있고 Gson이 비 Object 필드를 자동으로 직렬화하지만 해당 messageData 필드에 사용자 정의 serializer를 사용하여 해당 messageType을 고려할 수있는 방법이 있습니까?

답변

1

슬프게도, 그렇지 않습니다. 적어도 내가 결정할 수 있었던 것은 아니었다. 거기에 "사용자 지정 필드 X를 deserialize,하지만 나머지는 super.deserialize()"와 같은 작업을 수행 할 방법이 없습니다. 하나님께서는 내가 시도한 것을 압니다. 위안이라면, 내가 보았던 모든 Json 디시리얼라이저에서 사실 인 것 같습니다.

+0

예, 슬픈 일입니다. (경험을 공유해 주셔서 감사합니다! – Paul

2

그것은 조금 늦게 될 수도 있지만 RuntimeTypeAdapter에 대한이 답변이 해결에 도움이 될 수 있습니다

https://stackoverflow.com/a/15737704/433421

RuntimeTypeAdapter 당신이 JSON에서 자체 구성 형식 속성을 평가 할 수 있습니다, 귀하의 경우에는 "messageType"을 입력하고 값을 제공된 POJO 클래스에 등록하십시오.

이 대답에 제공된 링크를보고 javadoc의 사용 예를 확인하십시오.

GSon은 POJO 클래스 자체의 직렬화 및 비 직렬화를 처리합니다.

messageData의 필드에 임의의 개체가 포함되어있는 경우 MessageJsonDeserializer에서와 마찬가지로 사용자 지정 JsonDeserializer 인스턴스를 등록해야합니다.

희망이 도움이됩니다.

+0

추가 사항 : RuntimeTypeAdapter를 수정하여 주어진 JSON 계층 구조의 한 수준 위로 type-attribute를 찾으십시오.이 유형 속성은 messageData 구조에 있어야하므로 필요합니다. 또한 javadoc-example의 Shape.class와 비슷한 모든 messageData 구조에 대해 추상 수퍼 클래스를 정의해야 할 수도 있습니다. –

관련 문제