Can't make Jackson and Lombok work together

后端 未结 14 1264
伪装坚强ぢ
伪装坚强ぢ 2020-11-27 13:48

I am experimenting in combining Jackson and Lombok. Those are my classes:

package testelombok;

import com.fasterxml         


        
相关标签:
14条回答
  • 2020-11-27 14:09

    I've all my classes annotated like this:

    @JsonAutoDetect(fieldVisibility = Visibility.ANY)
    @JsonInclude(JsonInclude.Include.NON_DEFAULT)
    @Data
    @Accessors(fluent = true)
    @NoArgsConstructor
    @AllArgsConstructor
    

    It worked with all Lombok and Jackson versions for, at least, a couple of years.

    Example:

    @JsonAutoDetect(fieldVisibility = Visibility.ANY)
    @JsonInclude(JsonInclude.Include.NON_DEFAULT)
    @Data
    @Accessors(fluent = true)
    @NoArgsConstructor
    @AllArgsConstructor
    public class Person {
        String id;
        String first;
        String last;
    }
    

    And that's it. Lombok and Jackson play together like a charm.

    0 讨论(0)
  • 2020-11-27 14:09

    I was having issues with getting Lombok to not add the ConstructorProperies annotation so went the other way and disabled Jackson from looking at that annotation.

    The culprit is JacksonAnnotationIntrospector.findCreatorAnnotation. Notice:

    if (_cfgConstructorPropertiesImpliesCreator
                && config.isEnabled(MapperFeature.INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES)
    

    Also notice JacksonAnnotationIntrospector.setConstructorPropertiesImpliesCreator:

    public JacksonAnnotationIntrospector setConstructorPropertiesImpliesCreator(boolean b)
    {
        _cfgConstructorPropertiesImpliesCreator = b;
        return this;
    }
    

    So two options, either set the MapperFeature.INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES to false or create a JacksonAnnotationIntrospector set setConstructorPropertiesImpliesCreator to false and set this AnnotationIntrospector into the ObjectMapper via ObjectMapper.setAnnotationIntrospector.

    Notice a couple things, I am using Jackson 2.8.10 and in that version MapperFeature.INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES does not exist. I am not sure in which version of Jackson it was added. So if it is not there, use the JacksonAnnotationIntrospector.setConstructorPropertiesImpliesCreator mechanism.

    0 讨论(0)
  • 2020-11-27 14:11

    I had exactly the same issue, "solved" it by adding the suppressConstructorProperties = true parameter (using your example):

    @Value
    @Wither
    @AllArgsConstructor(suppressConstructorProperties = true)
    public class TestFoo {
        @JsonProperty("xoom")
        private String x;
        private int z;
    }
    

    Jackson apparently does not like the java.beans.ConstructorProperties annotation added to constructors. The suppressConstructorProperties = true parameter tells Lombok not to add it (it does by default).

    0 讨论(0)
  • 2020-11-27 14:13

    For me it worked when I have updated lombok version to: 'org.projectlombok:lombok:1.18.0'

    0 讨论(0)
  • 2020-11-27 14:14

    You need to have this module as well. https://github.com/FasterXML/jackson-modules-java8

    then turn on -parameters flag for your compiler.

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.7.0</version>
                    <configuration>
                        <compilerArgs>
                            <arg>-parameters</arg>
                        </compilerArgs>
                    </configuration>
                </plugin>
    
    0 讨论(0)
  • 2020-11-27 14:21
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @Data
    public class Person {
       String id;
       String first;
       String last;
    }
    

    Additional to the Data Class, it should be correct configured the ObjectMapper. In this case, it is working ok with a ParameterNamesModule configuration, and setting visibility of Fields and Creator Methods

        om.registerModule(new ParameterNamesModule());
        om.setVisibility(FIELD, JsonAutoDetect.Visibility.ANY);
        om.setVisibility(CREATOR, JsonAutoDetect.Visibility.ANY);
    

    Then it should work as expected.

    0 讨论(0)
提交回复
热议问题