On Mon, Jan 30, 2023 at 11:53 AM itineric itineric <itine...@gmail.com> wrote:
>
> Hi all,
>
> I'm trying to work with interfaces and related bean implementation of that 
> interface. So far, all good.
> I then tried to add some Map<String, Object> to the equation and I cannot 
> understand why I get this result.
> Short story: I'm trying to get the @class to be set to the interface name 
> using a TypeIdResolver and it work as expected on a direct call but not when 
> the object is inside a Map.

Although I did not read the example in detail, I think you are bumping
into the same problem as countless other developers: Java Type
Erasure.

Meaning that passing root-level values that have generic type will NOT
have their type information available.

Try this by wrapping your `Map` into wrapper like:

public class MapWrapper {
   public Map<String, Object> parameters;
}

and serialize that.

More specifically if you pass `Map` directly into ObjectMapper, it is
only seen as `Map<?.?>`
This is problematic because you need the base type of Map values to be
`UserInterface` I think.
So type must be seen as `Map<String, UserInterface>` or so.

If possible maybe you should try creating helper type, something like:

  public class UserTypeMap extends HashMap<String, UseInterface> { }

since it would contain necessary type information (being concrete
type, not generic).

-+ Tatu +-


> I simplified everything to get an example, here it is :
>
> UserInterface.java
> @JsonTypeInfo(use = Id.CLASS)
> @JsonTypeIdResolver(UserTypeResolver.class)
> public interface UserInterface
> {
>   String getName();
> }
>
> UserImplementation.java
> public class UserImplementation implements UserInterface
> {
>   private String name;
>
>   @Override
>   public String getName()
>   {
>     return this.name;
>   }
>
>   public void setName(final String name)
>   {
>     this.name = name;
>   }
> }
>
> UserTypeResolver.java
> public class UserTypeResolver implements TypeIdResolver
> {
>   private JavaType baseType;
>
>   @Override
>   public void init(final JavaType baseType)
>   {
>     this.baseType = baseType;
>   }
>
>   @Override
>   public String idFromValue(final Object value)
>   {
>     return idFromValueAndType(value, value.getClass());
>   }
>
>   @Override
>   public String idFromValueAndType(final Object value, final Class<?> 
> suggestedType)
>   {
>     return "com.example.jackson.UserInterface";
>   }
>
>   @Override
>   public String idFromBaseType()
>   {
>     return idFromValueAndType(null, this.baseType.getRawClass());
>   }
>
>   @Override
>   public JavaType typeFromId(final DatabindContext context, final String id)
>     throws IOException
>   {
>     return 
> TypeFactory.defaultInstance().constructSpecializedType(this.baseType, 
> UserImplementation.class);
>   }
>
>   @Override
>   public String getDescForKnownTypeIds()
>   {
>     return null;
>   }
>
>   @Override
>   public Id getMechanism()
>   {
>     return Id.CLASS;
>   }
> }
>
> And finally the test I played:
>
>     final UserImplementation user = new UserImplementation();
>     user.setName("test");
>
>     final Map<String, Object> parameters = new HashMap<>();
>     parameters.put("user", user);
>
>     final ObjectMapper mapper = new ObjectMapper();
>     mapper.enableDefaultTyping(DefaultTyping.JAVA_LANG_OBJECT, As.PROPERTY);
>
>     StringWriter writer = new StringWriter();
>     mapper.writeValue(writer, user);
>     System.out.println(writer);
>
>     writer = new StringWriter();
>     mapper.writeValue(writer, parameters);
>     System.out.println(writer);
>
> The output is:
> {"@class":"com.example.jackson.UserInterface","name":"test"}
> {"user":{"@class":"com.example.jackson.UserImplementation","name":"test"}}
>
> The expected output I'd like to see:
> {"@class":"com.example.jackson.UserInterface","name":"test"}
> {"user":{"@class":"com.example.jackson.UserInterface  ","name":"test"}}
>
> What am I doing wrong? Is that the expected output? What could I do to get 
> the one I expect?
>
> Thank you
>
>
> --
> You received this message because you are subscribed to the Google Groups 
> "jackson-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to jackson-user+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/jackson-user/afe8ba30-a9de-4a48-8c6e-2407115694den%40googlegroups.com.

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to jackson-user+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jackson-user/CAL4a10hEda0LaKHzP6SaNcyTGQw3sAmKb1kPdhCuODUdVVVDgA%40mail.gmail.com.

Reply via email to