5

I am using Spring-boot 2.1.6 and i have DTO:

@AllArgsConstructor
@Builder
@Data // setters, getters, others
@NoArgsConstructor
public class ExampleDto {
    private String fieldOne;
    private String fieldsTwo;

}

Do i really need that many Lombok annotation here? Which will Jackson use by default when deserializing over HTTP connection (microservices)? I guess only NoArgsConstructor + setters would be fine? Or does it use reflection and only providing no-arg-constructor is fine?

Is there an option to change behaviour of Jackson to use only AllArgsConstructor or builder? I saw in logs that my app uses Jackson to deserialize stuff.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.8.8</version>
    <scope>provided</scope>
</dependency>

 <dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

Edit:

My question is different from Can't make Jackson and Lombok work together cause it works.

tryingHard
  • 1,794
  • 4
  • 35
  • 74
  • Possible duplicate of [Can't make Jackson and Lombok work together](https://stackoverflow.com/questions/39381474/cant-make-jackson-and-lombok-work-together) – Strelok Oct 25 '19 at 10:58
  • @Strelok My question is different from `Can't make Jackson and Lombok work together` cause it works together. – tryingHard Oct 25 '19 at 11:08
  • Maybe you should read the actual linked question because the top voted answer tells you how to use the Lombok builders . You’re hardly trying – Strelok Oct 25 '19 at 11:13
  • 1
    My questions was partly about how `Jackson` works by default I don't see that mentioned there. – tryingHard Oct 25 '19 at 11:15

6 Answers6

8

Jackson uses default (no argument) constructor to create object and then sets value using setters. so you only need @NoArgsConstructor and @Setter.

Irtaza Zaidi
  • 106
  • 5
1

The Jackson deserialization by default uses the no-args constructor and the setters of the object. So with Lombok, you'll need a minimum of:

@NoArgsConstructor
@Setter
public class ExampleDto {
    private String fieldOne;
    private String fieldsTwo;
}

(Note if you're ever serializing then you'll need at least a @Getter).

There is an option to override the default deserialization of Jackson to use the Lombok builder. This is covered in top answer to Can't make Jackson and Lombok work together (as others have mentioned). I.e.

@Builder
@Data
@JsonDeserialize(builder = ExampleDto.ExampleDtoBuilder.class)
public class ExampleDto {
    private String fieldOne;
    private String fieldsTwo;
}

@JsonPOJOBuilder(withPrefix = "") 
public static class ExampleDtoBuilder {

}
isak gilbert
  • 2,541
  • 1
  • 14
  • 11
1

Jackson uses default NoArgsConstructor and Setters.

If you don't provide Setters, jackson will set values using reflection. See - How does jackson set private properties without setters?

wut
  • 19
  • 4
1

Although above answers work to solve the mentioned issue, as an updated answer, according to the lombok official website, from 1.18.14, @Jacksonized was introduced, which automatically configures the generated builder class to be used by Jackson's deserialization. Therefore, your code could be like this:

@Builder
@Jacksonized
public class ExampleDto {
    private String fieldOne;
    private String fieldsTwo;
}
khesam109
  • 510
  • 9
  • 16
0

According to this tutorial jackson searches for getter- and setter-methods. Also to create an object of the type a default constructor is needed. So basically you need a class that satisfies the java bean conventions.

Long story short: You need @Data for getter- and setter-methods and @NoArgsConstructor for the default constructor to satisfy the bean convention. @AllArgsConstructor and @Builder should not be needed for jackson.

Tobias
  • 2,547
  • 3
  • 14
  • 29
  • Additional question was: `Is there an option to change behaviour of Jackson to use only AllArgsConstructor or builder?` – tryingHard Oct 25 '19 at 10:39
  • I don't think there is such an option, although I'm not quite shure about it. But to use only an `@AllArgsConstructor` jackson would need to know at least the order of elements in the constructor, which should be not possible I think. So it's just an educated guess, but I think it's not possible. – Tobias Oct 25 '19 at 11:03
0

Well since you are using Spring Boot, there should be a Jackson configuration class somewhere annotated with @Configuration. Something like this should enable serialization for your Java bean without the need for any annotation

@Configuration
public class JacksonConfiguration {

   @Bean
   public ObjectMapper objectMapper() {
      ObjectMapper mapper = new ObjectMapper();
      objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
      return mapper;
   }

}
allkenang
  • 1,511
  • 15
  • 12