On Thu, Dec 20, 2018 at 11:22 AM matt Smith <[email protected]> wrote:
>
> I encountered a case where class level JsonSerializable annotation does not 
> require registration with Simple Module  but method level does.

Hmmh. This seems odd, let's see.

> Here is the example I tried
>
> @JsonSerialize(using = ItemRowSerializer.class )
>         private ItemRow tes
> tItem(){
>             return new ItemRow("abc", Arrays.asList("item1", "item2", 
> "item3"));
>         }
>
>
> I test it out like this
>
>
> String jsonResult =  new ObjectMapper().writeValueAsString(testItem());
> System.out.println(jsonResult);
>
> I noticed that jsonString did not serialize using ItemRowSerializer.

Ah. No, it won't. Jackson does not see you calling the method; Jackson
sees the object you pass, which was returned by the method. There is
no linkage there: Jackson can only introspects classes you pass to it.

> However, when I did this, it gave the expected jsonString
>
>
> SimpleModule module = new SimpleModule()
>  module.addSerializer(ItemRowSerializer.class)
>  mapper.register(module);
>  String jsonResult =  new ObjectMapper().writeValueAsString(testItem());
>  System.out.println(jsonResult);
>
>
> On the otherhand, if I had my ItemRow class annoated with @JsonSerializable,  
> there was no need with module at all.

I think you mean `@JsonSerialize` here (there is interface type
`JsonSerializable`, but no annotation).

> i.e
>
> @JsonSerializable(using = ItemRowSerailizer
> public class ItemRow<T> {...}
>
>
> Since I am passing this serialized object over the wire, I do not prefer to 
> write to mapper and send string representation across.
>
> how would I go about getting method level annotation working without module 
> registration?

Method level annotations only work when property is accessed via
method (or field) in question.

So if you had something like:

public class Rows
   @JsonSerialize(using = .... )
   public ItemRow<Type> getRows() { ... }
}

and serialized an instance of `Rows`, serializer would be found. But
for root values, there is no such reference.

On related note, I strongly recommend always using a wrapper type
around generic values, so that root value is never of generic type.
Reason for this is that Java Type Erasure will often cause problems if
attempting to pass an instance of generic type -- so Jackson can not
detect intended type (all it sees is type variable from class
declaration).

So, attempts to serialize, say, Row<T>, will be seen as `Row<?>`, and
possibly (although not always) cause issues in finding handlers for
the type -- for example, if value type has annotations, they may not
be visible.

-+ Tatu +-

-- 
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 [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to