Ich habe gerade ein seltsames Problem mit JodaTime DateTimes und einem Spring MVC Controller. Obwohl ich sehe, dass die mit InitBinder annotierte Methode aufgerufen wird, hat sie keine Auswirkungen, die Zeichenfolgen der Testanforderung sind nicht an mein Domänenobjekt gebunden, wie die folgende Fehlermeldung besagt:
org.springframework.validation.BeanPropertyBindingResult: 2 Fehler
Feldfehler im Objekt 'eventCommand' im Feld 'endDate': abgelehnter Wert [29/03/2015 12:13]; Codes [typeMismatch.eventCommand.endDate,typeMismatch.endDate,typeMismatch.org.joda.time.DateTime,typeMismatch]; Argumente [org.springframework.context.support.DefaultMessageSourceResolvable: Codes [eventCommand.endDate,endDate]; Argumente []; Standardmeldung [endDate]]; Standardmeldung [Konnte Eigenschaftswert vom Typ 'java.lang.String' nicht in den erforderlichen Typ 'org.joda.time.DateTime' für das Feld 'endDate' konvertieren; die innere Ausnahme ist org.springframework.core.convert.ConversionFailedException: Konvertierung vom Typ java.lang.String in Typ @javax.validation.constraints.NotNull @javax.persistence.Column @org.hibernate.annotations.Type org.joda.time.DateTime für Wert '29/03/2015 12:13' fehlgeschlagen; die innere Ausnahme ist java.lang.IllegalArgumentException: Ungültiges Format: "29/03/2015 12:13" ist zu kurz]
Feldfehler im Objekt 'eventCommand' im Feld 'startDate': abgelehnter Wert [28/03/2015 12:13]; Codes [typeMismatch.eventCommand.startDate,typeMismatch.startDate,typeMismatch.org.joda.time.DateTime,typeMismatch]; Argumente [org.springframework.context.support.DefaultMessageSourceResolvable: Codes [eventCommand.startDate,startDate]; Argumente []; Standardmeldung [startDate]]; Standardmeldung [Konnte Eigenschaftswert vom Typ 'java.lang.String' nicht in den erforderlichen Typ 'org.joda.time.DateTime' für das Feld 'startDate' konvertieren; die innere Ausnahme ist org.springframework.core.convert.ConversionFailedException: Konvertierung vom Typ java.lang.String in Typ @javax.validation.constraints.NotNull @javax.persistence.Column @org.hibernate.annotations.Type org.joda.time.DateTime für Wert '28/03/2015 12:13' fehlgeschlagen; die innere Ausnahme ist java.lang.IllegalArgumentException: Ungültiges Format: "28/03/2015 12:13" ist zu kurz]
Hier ist der wichtige Teil des Controllers:
@Controller
@RequestMapping("/***/event")
public class EventController {
private static final String COMMAND = "eventCommand";
@Autowired
private EventDao eventDao;
@InitBinder(value = COMMAND)
public void customizeConversions(WebDataBinder binder) {
DateFormat df = new SimpleDateFormat("dd/MM/yyyy HH:mm");
df.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(df, true));
}
@RequestMapping(value = {
"/new",
"/edit/{id}"
}, method = POST)
public ModelAndView save(@ModelAttribute(COMMAND) @Valid final Event event, final BindingResult result) {
if (result.hasErrors()) {
return populatedEventForm(event);
}
eventDao.saveOrUpdate(event);
return successfulRedirectionView();
}
private ModelAndView successfulRedirectionView() {
return new ModelAndView("redirect:index.jsp");
}
private ModelAndView populatedEventForm(final Event event) {
ModelMap model = new ModelMap(COMMAND, event);
return new ModelAndView("event/form.jsp", model);
}
}
Sowie die Testanforderung (gesteuert von spring-test-mvc):
@Test
public void when_saving_valid_event_then_routed_to_home() throws Exception {
mvc.perform(post("/***/event/new").
param("title", "zuper title").
param("description", "zuper description").
param("startDate", "28/03/2015 12:13").
param("endDate", "29/03/2015 12:13")).
andExpect(status().isOk()).
andExpect(view().name("redirect:index.jsp"));
}
Und die Entität:
@Entity
public class Event {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id")
private long id;
@NotBlank
@Length(max = 1000)
@Column(name = "description", nullable = false)
private String description = "";
@NotNull
@Column(name = "start_date", nullable = false)
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime startDate;
@NotNull
@Column(name = "end_date", nullable = false)
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime endDate;
@NotBlank
@Length(max = 255)
@Column(name = "title", nullable = false, unique = true)
private String title = "";
/* setters & getters */
}
Wenn ich die mit @InitBinder annotierte Methode beibehalte, ist das Ergebnis dasselbe... Ich habe dieselbe Art von Datenbindung für eine andere Entität (mit 1 DateTime-Mitglied) und es funktioniert einwandfrei.
Irgendwelche Ideen, was falsch läuft?
Vielen Dank im Voraus,
Rolf