Десериализовать строку JSON, сгенерированную из .NET, используя Джексона - PullRequest
0 голосов
/ 03 декабря 2011

Я ссылаюсь на этот вопрос для моих классов и кода, но на этот раз с другой ошибкой: Десериализация JSON с Джексоном - почему JsonMappingException «Нет подходящего конструктора»?

После этого вопроса я добавил пустой конструктор в ProtocolContainer.

ТАК что сейчас ситуация. Приложение .NET (C #) создает строку JSON с использованием DataContractJsonSerializer. В ProtocolContaier есть «SubPacket», определенный как DataPacket, а затем существуют подклассы для DataPacket (так что это полиморфная проблема).

Строка выглядит так:

{ "DataPacketJSONString": нулевой, "DataPacketType": "MyPackage.DataPackets.LoginRequestReply", "MessageId": 6604, "SenderUsername": нулевой, "подпакет": { "__ типа": "LoginRequestReply: # MyPackage.DataPackets «„Причина“:» Неправильно pass или username "," Success ": false," Username ":" User1 "}}

Обратите внимание на __type в JSON выше. Это то, что .NET создал, чтобы отслеживать тип объекта «SubPacket».

Проблема в том, как десериализовать его на стороне Java, используя Джексона?

Это дает мне следующую ошибку:

org.codehaus.jackson.map.JsonMappingException: не удалось разрешить тип id 'LoginRequestReply: # MyPackage.DataPackets' в подтип [простой тип, класс MyPackage.DataPacket] в [Источник: java.io.StringReader@40561798; строка: 1, столбец: 168] (через цепочка ссылок: MyPackage.ProtocolContainer ["SubPacket"])

И я предполагаю, что Джексон не может интерпретировать __type в строке JSON выше. И я думаю, что это связано с его форматом. Вопрос: как это можно решить?

DataPacket.java - суперкласс, определенный в ProtocolContainer (см. Ссылку выше):

package MyPackage;

import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonTypeInfo;

import MyPackage.DataPackets.*;

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="__type")
@JsonSubTypes(
{
    @JsonSubTypes.Type(value = LoginRequest.class, name = "LoginRequest"),
    @JsonSubTypes.Type(value = LoginRequestReply.class, name = "LoginRequestReply")
})
public class DataPacket 
{

}

1 Ответ

1 голос
/ 03 декабря 2011

Итак, одно решение (которое я считаю уродливым) - адаптировать JsonSubTypes так, чтобы оно выглядело так же, как то, что создано на C #:

@JsonSubTypes(
{
    @JsonSubTypes.Type(value = LoginRequest.class, name = "LoginRequest:#MyPackage.DataPackets"),
    @JsonSubTypes.Type(value = LoginRequestReply.class, name = "LoginRequestReply:#MyPackage.DataPackets")
})

Я не нашел лучшего способа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...