0

I refer to this question for my classes and code, but this time with another error.

I have since the above question added an empty constructor to ProtocolContainer.

The situation is now that a .NET app (C#) is creating the JSON string using DataContractJsonSerializer. The ProtocolContaier has a "SubPacket" defined as a DataPacket, and then there are subclasses to DataPacket (so this is a polymorphic problem).

The string looks like this:

{"DataPacketJSONString":null,"DataPacketType":"MyPackage.DataPackets.LoginRequestReply","MessageId":6604,"SenderUsername":null,"SubPacket":{"__type":"LoginRequestReply:#MyPackage.DataPackets","Reason":"Wrong pass or username","Success":false,"Username":"User1"}}

Note the __type in the JSON above. That is something that .NET created to keep track of what type of object the "SubPacket" is.

The problem is how to deserialize it on the Java side, using Jackson?

It gives me the following error:

org.codehaus.jackson.map.JsonMappingException: Could not resolve type id 'LoginRequestReply:#MyPackage.DataPackets' into a subtype of [simple type, class MyPackage.DataPacket] at [Source: java.io.StringReader@40561798; line: 1, column: 168] (through reference chain: MyPackage.ProtocolContainer["SubPacket"])

And my guess is that Jackson can't interpret the __type in the JSON string above. And I think that is dues to its format. The question is: how can it be resolved?

DataPacket.java - the superclass, defined in ProtocolContainer (see link above):

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 
{
    
}
halfer
  • 19,824
  • 17
  • 99
  • 186
Ted
  • 19,727
  • 35
  • 96
  • 154

1 Answers1

1

So, one solution (that I find ugly) is to adapt the JsonSubTypes so it looks the same as what is created on the C# end:

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

I havent found any better way.

Ted
  • 19,727
  • 35
  • 96
  • 154
  • I don't understand what about this is ugly. It appears to me that the type name in the JSON is mapped to the name of the Java target type. What would a cleaner solution look like? – Programmer Bruce Dec 06 '11 at 05:17