Spring controller won’t deserialize instant

I’m having trouble integrating Spring with Jackson.

I have a POJO which has some Instant fields with a custom date format:

public class C{
   @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy HH:mm:ss", timezone = "UTC")
   private Instant postedAtFrom;
   @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy HH:mm:ss", timezone = "UTC")
   private Instant postedAtTo;
}

Then I’m trying to use this POJO as a query parameter for a rest GET mapping:

@RestController
@RequestMapping("/c")
@RequiredArgsConstructor
@Slf4j
public class AnnounceController {

   @Autowired
   private final ObjectMapper objectMapper;

   @PostConstruct
   public void test() throws JsonProcessingException {

      System.out.println(objectMapper.readValue("{"postedAtFrom":"20-05-2022 15:50:07"}", C.class));

   }

   @GetMapping
   public BasicResponse<Page<Announce>> get(final C filter, @NonNull final Pageable page) {
      return   new BasicResponse<>(service.get(filter, page));
   }
   
}

The PostConstruct code works fine and it prints exactly what it should print, but whenever I try to make a get to that endpoint with the very same request:

CURL
    GET /c?postedAtFrom=20-05-2022 15:50:07 HTTP/1.1
    Host: localhost 

I get this exception:

org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'filter' on field 'postedAtFrom': rejected value [20-05-2022 15:50:07]
codes [typeMismatch.filter.postedAtFrom,typeMismatch.postedAtFrom,typeMismatch.java.time.Instant,typeMismatch]
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [filter.postedAtFrom,postedAtFrom]
arguments []
default message [postedAtFrom]]
default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.Instant' for property 'postedAtFrom'
nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@com.fasterxml.jackson.annotation.JsonFormat java.time.Instant] for value [20-05-2022 15:50:07]
nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [20-05-2022 15:50:07]]

Here is the code for the ObjectMapper bean:

@Bean
   @Primary
   public ObjectMapper configure(@NonNull final ObjectMapper objectMapper) {
      final SimpleModule javaTimeModule = new JavaTimeModule()
              .addDeserializer(Instant.class, InstantDeserializer.INSTANT)
              .addSerializer(Instant.class, InstantSerializer.INSTANCE);
      return objectMapper.registerModule(javaTimeModule);

   }

I would like to to resolve this using the designed tools of Spring and Jackson. Please do not suggest a workaround like “convert it to a string” or “make a post”.

8

As others have stated in the comments, it’s not very clear what you’re expecting to happen. I make assumptions below.

Considering the @JsonFormat annotation and the custom ObjectMapper, if you’re expecting Jackson to kick in here and parse JSON, that’s not going to happen. To be clear, no Jackson nor JSON parsing is involved anywhere in here.

Your final C filter handler method parameter isn’t annotated with something like @RequestBody (and you’re not sending a request body in that GET Curl call). Without an annotation, Spring MVC falls back to handling the parameter as a model attribute and processes it with ModelAttributeMethodProcessor.

It creates an instance of your type C and attempts to populate its fields with query (or form- if that’s what you had used) parameters. In this case, it’ll look for a query parameter named postedAtFrom to match the field (really the bean/pojo accessor, which I also assume you have).

The processor uses a set of Converter instances to populate the fields from String values (the query parameters) into the complex types your model attribute type is likely using.

Spring Boot maintains its own list of default Converter instances. There’s one in there for java.time types, Jsr310DateTimeFormatAnnotationFormatterFactory (this isn’t the Converter, but it’s what the Converter uses), which is set up to handle String to Instant conversion.

However, your query parameter value, 20-05-2022 15:50:07, is not going to be parseable as an Instant, there’s information about the Instant missing (timezone for one). In certain, you’d be able to annotate your field @DateTimeFormat to specify a custom format, but I don’t think that’ll work here.

You can instead change your field to be a LocalDateTime

@DateTimeFormat(pattern = "dd-MM-yyyy HH:mm:ss")
private LocalDateTime postedAtFrom;

with an appropriate pattern matching your input. And, whenever you need an Instant, use LocalDateTime‘s toInstant method with an appropriate ZoneOffset.

Alternatively, you can configure Spring Boot with your own list of Converter instances that can parse directly to an Instant with your own DateTimeFormatter. See this post for information on how to do that.

1

@Savior’s answer looked very good but because I didn’t really know how a new date converter would mingle among the others spring already has I went to a less elegant but easier solution. I added a set method in my POJO

   @DateTimeFormat(pattern = "dd-MM-yyyy HH:mm:ss")
   public void setPostedAtFrom(final String date) {
      this.postedAtFrom = LocalDateTime.parse(date, SIMPLE_DATE_FORMAT).atZone(ZoneId.systemDefault()).toInstant();
   }

 
   @DateTimeFormat(pattern = "dd-MM-yyyy HH:mm:ss")
   public void setPostedAtTo(final String date) {
      this.postedAtTo = LocalDateTime.parse(date, SIMPLE_DATE_FORMAT).atZone(ZoneId.systemDefault()).toInstant();
   }

   private static final DateTimeFormatter SIMPLE_DATE_FORMAT = new DateTimeFormatterBuilder()
           .appendPattern("dd-MM-yyyy HH:mm:ss")
           .toFormatter();

the @DateTimeFormat is really irrelevant here but helps me to remember what is the format that string is supposed to come [this is a really big pojo]

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật