4

What is the correct way to register a custom deserializer for a path variable in Spring web reactive?

Example:

@GetMapping("test/{customType}")
public String test(@PathVariable CustomType customType) { ...

I tried ObjectMapperBuilder, ObjectMapper and directly via @JsonDeserialize(using = CustomTypeMapper.class) but it wont register:

Response status 500 with reason "Conversion not supported."; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type '...CustomType'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type '...CustomType': no matching editors or conversion strategy found
Journeycorner
  • 2,474
  • 3
  • 19
  • 43
  • 1
    Perhaps try providing a [Converter](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/convert/converter/Converter.html) and also [register it](https://stackoverflow.com/questions/35025550/register-spring-converter-programmatically-in-spring-boot). – Andrew S Jun 14 '18 at 18:04
  • @JourneyCorner are you using Spring Boot? – Brian Clozel Jun 14 '18 at 19:50

2 Answers2

4

For path variables deserialization you don't need to involve jackson, you can use org.springframework.core.convert.converter.Converter

For example:

@Component
public class StringToLocalDateTimeConverter
  implements Converter<String, LocalDateTime> {

    @Override
    public LocalDateTime convert(String source) {
        return LocalDateTime.parse(
          source, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
    }
}

@GetMapping("/findbydate/{date}")
public GenericEntity findByDate(@PathVariable("date") LocalDateTime date) {
    return ...;
}

Here's an article with examples

MarkHuntDev
  • 181
  • 3
  • 21
1

I ended up using @ModelValue because it semantically is not a deserialization, just parsing a key.

@RestController
public class FooController {

   @GetMapping("test/{customType}")
   public String test(@ModelAttribute CustomType customType) { ... }
}

@ControllerAdvice
public class GlobalControllerAdvice {

   @ModelAttribute("customType")
   public CustomType getCustomType(@PathVariable String customType) {
      CustomeType result = // map value to object
      return result;
   }
}
Journeycorner
  • 2,474
  • 3
  • 19
  • 43