Jackson JSON Processor
  1. Jackson JSON Processor
  2. JACKSON-178

Add option for overriding default property name introspection strategy

    Details

    • Type: New Feature New Feature
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.8.0
    • Component/s: None
    • Labels:
      None
    • Number of attachments :
      0

      Description

      (based on a request from mailing list)

      There exist JSON content where property names are consistent, but not compatible with Java camel case naming convention. Although it is possible to override name to use on case-by-case basis using annotations, it would be good to have option to define alternative name handling strategies. Specific case requested was:


      I'm trying to integrate with a legacy system that has upper camel case names for fields in the Json. Something like:

      { UserName: 'bob', Address: 'somewhere'}

      I'm using the ObjectMapper to try and speed development but according to the docs it would create something like:

      { userName: 'bob', address: 'somewhere'}

      such that relatively simple change to strategy would work. But there are other similarly consistent but different naming conventions (use underscores instead of camel case etc) that would require alternative methods.

        Activity

        Hide
        Jeff Schnitzer added a comment -

        I'm interested in a feature like this specifically to deserialize Facebook's JSON, which is full of fields like "first_name" and "last_name".

        Looking at it just from the deserialization side, is there any current mechanism which would let me map these to standard java property names? I could probably create a global handler for missing fields, convert any underscores, and try to set the fields myself, but this seems like a hack.

        Thanks,
        Jeff

        Show
        Jeff Schnitzer added a comment - I'm interested in a feature like this specifically to deserialize Facebook's JSON, which is full of fields like "first_name" and "last_name". Looking at it just from the deserialization side, is there any current mechanism which would let me map these to standard java property names? I could probably create a global handler for missing fields, convert any underscores, and try to set the fields myself, but this seems like a hack. Thanks, Jeff
        Hide
        Jeff Schnitzer added a comment -

        ...and I know I can do it case-by-case with annotations, but I'm hoping for a more automatic solution. Thanks.

        Show
        Jeff Schnitzer added a comment - ...and I know I can do it case-by-case with annotations, but I'm hoping for a more automatic solution. Thanks.
        Hide
        Tatu Saloranta added a comment -

        Yes, the idea would be to avoid having to use explicit annotations, if there is a pattern that could be used.

        I think the place I would look into is AnnotationHandler, which (I hope!) is where name canonicalization is done. JacksonAnnotationIntrospector has the default one in-built, but for custom version it could be sub-classed.
        This is not ideal; so for pluggable naming strategy an additional abstraction would be needed. I haven't had time to work on this at all, but am willing to help if anyone wants to have a look.

        Show
        Tatu Saloranta added a comment - Yes, the idea would be to avoid having to use explicit annotations, if there is a pattern that could be used. I think the place I would look into is AnnotationHandler, which (I hope!) is where name canonicalization is done. JacksonAnnotationIntrospector has the default one in-built, but for custom version it could be sub-classed. This is not ideal; so for pluggable naming strategy an additional abstraction would be needed. I haven't had time to work on this at all, but am willing to help if anyone wants to have a look.
        Hide
        Pascal Gélinas added a comment -

        I would also like a feature of this kind. We have our own convention for field naming and it would be nice to have some sort of global configuration so I don't have to specify annotation for the fields.

        For now, I use the workaround you suggested, namely, I subclass JacksonAnnotationIntrospector and I overide find(De)SerializablePropertyName . This works very well for my case.

        Show
        Pascal Gélinas added a comment - I would also like a feature of this kind. We have our own convention for field naming and it would be nice to have some sort of global configuration so I don't have to specify annotation for the fields. For now, I use the workaround you suggested, namely, I subclass JacksonAnnotationIntrospector and I overide find(De)SerializablePropertyName . This works very well for my case.
        Hide
        Tatu Saloranta added a comment -

        Thanks for the tip on work around! This feature is still something we would like to do – make sure you vote for it, since I try to consider popularity of issues when planning on what to work on (esp. if I do not need a feature myself immediately).

        Show
        Tatu Saloranta added a comment - Thanks for the tip on work around! This feature is still something we would like to do – make sure you vote for it, since I try to consider popularity of issues when planning on what to work on (esp. if I do not need a feature myself immediately).
        Hide
        Pascal Gélinas added a comment -

        I was trying to add auto detection (JsonAutoDetect) of private field and I found out that the workaround doesn't work: the AnnotationIntrospector has no relation with the visibily checker, and thus could not translate the name if it was found because of the visibility instead of annotation (JsonSerialize or JsonProperty).

        I found another workaround though:
        1- Subclass BeanSerializerFactory and extends the method _constructWriter(). Change the "name" parameter to anything you want (in my case, change camel case format and remove leading identifier) then call super method.
        2- Subclass BeanDeserializerFactory and extends the method constructSettableProperty() – make sure it's the AnnotatedField overload. Do the same thing you did with the serializer, and you should be set for all cases.

        This workaround seems to work for everything, since the serializer/deserializer don't do any modification to its specified property name, nor any filtering based on annotation.

        Show
        Pascal Gélinas added a comment - I was trying to add auto detection (JsonAutoDetect) of private field and I found out that the workaround doesn't work: the AnnotationIntrospector has no relation with the visibily checker, and thus could not translate the name if it was found because of the visibility instead of annotation (JsonSerialize or JsonProperty). I found another workaround though: 1- Subclass BeanSerializerFactory and extends the method _constructWriter(). Change the "name" parameter to anything you want (in my case, change camel case format and remove leading identifier) then call super method. 2- Subclass BeanDeserializerFactory and extends the method constructSettableProperty() – make sure it's the AnnotatedField overload. Do the same thing you did with the serializer, and you should be set for all cases. This workaround seems to work for everything, since the serializer/deserializer don't do any modification to its specified property name, nor any filtering based on annotation.
        Hide
        Tatu Saloranta added a comment -

        Ok, will finally start working on this. I think it should be relatively simple to do, by adding something like "PropertyNamingStrategy" (abstract class, to allow adding methods in future), which is called during serializer/deserializer construction. Instance of this class may be called for various parts of logical property (getter, setter, field), in cases where no explicit name has been indicated (via @JsonProperty); and is passed information about member (method, field), BeanProperty (if available; gives access to other annotations).

        Show
        Tatu Saloranta added a comment - Ok, will finally start working on this. I think it should be relatively simple to do, by adding something like "PropertyNamingStrategy" (abstract class, to allow adding methods in future), which is called during serializer/deserializer construction. Instance of this class may be called for various parts of logical property (getter, setter, field), in cases where no explicit name has been indicated (via @JsonProperty); and is passed information about member (method, field), BeanProperty (if available; gives access to other annotations).
        Hide
        Tatu Saloranta added a comment -

        Implemented: now one can extend CustomNamingStrategy, register via ObjectMapper, and support non-Java-Bean style naming strategies.

        Show
        Tatu Saloranta added a comment - Implemented: now one can extend CustomNamingStrategy, register via ObjectMapper, and support non-Java-Bean style naming strategies.

          People

          • Assignee:
            Tatu Saloranta
            Reporter:
            Tatu Saloranta
          • Votes:
            3 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: