In a Spring application I want to use my own JsonSerializer with a RestController. My JsonSerializer is registered in a Jackson2ObjectMapperBuilder. So far so good, but when I annotate the respective fields with @JsonSerialize Spring MVC complains that there is no converter found for my class. Here is the code:
public class DurationAsHourSerializer extends JsonSerializer<Duration>{
@Override
public void serialize(Duration value, JsonGenerator gen, SerializerProvider serializers)
throws IOException, JsonProcessingException {
gen.writeNumber(value.toHours());
}
}
@Configuration
@EnableWebMvc
public class AppConfig {
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
SimpleModule module = new SimpleModule();
module.addSerializer(Duration.class, new DurationAsHourSerializer());
b.modulesToInstall(module);
return b;
}
}
@EqualsAndHashCode
@ToString
public class Order {
@Getter
@Setter
private String id;
@Getter
@Setter
@NotNull
private String customerId;
@Getter
@Setter
private ZonedDateTime validFrom;
@Getter
@Setter
private ZonedDateTime validTo;
@Getter
@Setter
@JsonSerialize(as=DurationAsHourSerializer.class)
private Duration maxDuration;
@Getter
@Setter
@JsonSerialize(as=DurationAsHourSerializer.class)
private Duration actDuration;
}
@RestController
@RequestMapping("order")
public class OrderController {
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> createOrder(@RequestBody @Valid Order order) {
HttpHeaders headers = new HttpHeaders();
headers.setLocation(ServletUriComponentsBuilder.fromCurrentRequest().path("/" + order.getId()).build().toUri());
return new ResponseEntity<>(null, headers, HttpStatus.CREATED);
}
@RequestMapping(method = RequestMethod.GET)
public Order getExample() {
Order order = new Order();
order.setMaxDuration(Duration.ofHours(10));
return order;
}
}
When I send a request to getExample(), I get the following error:
java.lang.IllegalArgumentException: No converter found for return value of type: class com.sap.sptutorial.rest.Order at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:178) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]
Why can't the Converter use my serializer, or why does my serializer make the otherwise existing converter unavailable?
PS: This is a follow up to How do I use a custom Serializer with Jackson? where I tried to use a Field Formatter for the same job, and learned that Formatters are not used for the Jackson Serialization.