I have a Spring Rest Controller and a "command"/DTO object for the POST method on the controller. I also wrote a serializer / deserializer for one of the fields "due" - which is a Calendar object.
Since Jackson2 dependencies are defined in pom.xml, I expect Spring to detect my deserializer and use it to convert a String input to java.util.Calendar. However, I get a "no matching editors or conversion strategy found" exception. My serializer is working ... only the deserializer won't work!
Rest Controller (TaskController.java)
@Controller
public class TasksController {
...
@RequestMapping(value = "/tasks", method = RequestMethod.POST)
public @ResponseBody Task createTask(@Valid TasksCommand tasksCommand){
Task task = new Task();
task.setName(tasksCommand.getName());
task.setDue(tasksCommand.getDue());
task.setCategory(tasksCommand.getCategory());
return task;
}
}
The command / dto object:
public class TasksCommand {
@NotBlank
@NotNull
private String name;
@JsonDeserialize(using = CalendarDeserializer.class)
@JsonSerialize(using = CalendarSerializer.class)
private Calendar due;
private String category;
... getters & setters ...
}
Serializer for Calendar - for my custom date format
public class CalendarSerializer extends JsonSerializer<Calendar>{
@Override
public void serialize(Calendar calendar, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss Z"); // Z - RFC 822 time zone
jgen.writeString(simpleDateFormat.format(calendar.getTime()));
}
}
Deserializer for Calendar
public class CalendarDeserializer extends JsonDeserializer<Calendar> {
private static Logger logger = Logger.getLogger(CalendarDeserializer.class);
@Override
public Calendar deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
String dateStr = jsonParser.getText();
logger.info("deserializing date:" + dateStr);
return Calendar.getInstance();
}
}
I have Jackson2 dependencies specified in Maven. When doing a GET (code not shown here), the serializer gets invoked correctly, and I see a JSON output of the "Task" object.
However, when I make an HTTP POST as below
curl -X POST -d name=task1 -d category=weekly -d due=01/01/2013 http://localhost:8080/tasks
the deserializer is never detected and I get an exception
Failed to convert property value of type java.lang.String to required type java.util.Calendar for property due; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Calendar] for property due: no matching editors or conversion strategy found
Since the serializer is getting detected, I don't understand why the deserializer is not detected and invoked correctly. From what I have read, having Jackson2 library on classpath will be detected by Spring and it would automatically add MappingJackson2HttpMessageConverter to the list of message converters. So this code should detect the string in HTTP POST and convert it to java.util.Calendar using the Deserializer. What am I missing?