どちらのオプションも使用できますが、コマンド オブジェクトに日付コンポーネントを含めるのはあまり巧妙ではないことに同意する傾向があります。
ページに日付フィールド用の非表示フィールドを追加し、その値を使用して日、月、年の 3 つの組み合わせを埋める場合、番号 2 が機能します。フォームの送信時に、最初に JavaScript を使用して、この非表示フィールド内のコンボから値を再構築する必要があります (コマンド オブジェクトの日付フィールドにマップされます)。
これが最もクリーンな方法だと思いますが、JavaScript を使用したくない場合は、3 つの値を (コマンド オブジェクトに対応するフィールドなしで) 送信し、コマンドがバインドされた後にそれらを組み立てることができます。
使用しているSpringバージョンについては言及していませんが、2.xの場合、メソッドのワークフローonBind
に介入して、そこで値を再構築できます。
Spring 3 で変更され、コントローラー クラスは注釈付きコントローラーを支持して廃止されましたが、InitBinderをリクエストと組み合わせて使用してカスタム日付エディターを登録し、フィールドを再構築すると、同様の結果が得られる可能性があります。例えば:
指示:
public class TestCommand implements Serializable {
private static final long serialVersionUID = 1L;
private Date someDate;
public Date getSomeDate() {
return someDate;
}
public void setSomeDate(Date someDate) {
this.someDate = someDate;
}
}
コントローラ:
@Controller
@RequestMapping(value="/testAction")
public class TestController {
@RequestMapping(method=RequestMethod.GET)
public String handleInit() {
return "form";
}
@InitBinder
protected void initBinder(WebDataBinder dataBinder, WebRequest webRequest) {
dataBinder.registerCustomEditor(Date.class, "someDate", new TestPropertyEditor(webRequest));
}
@RequestMapping(method=RequestMethod.POST)
public String handleSubmit(@ModelAttribute("testCommand") TestCommand command, BindingResult result) {
return "formResult";
}
}
形:
<form:form modelAttribute="testCommand" action="testAction" method="post">
<%-- need a parameter named "someDate" or Spring won't trigger the bind --%>
<input type="hidden" name="someDate" value="to be ignored" />
year: <input type="text" name="year" value="2012" /><br/>
month: <input type="text" name="month" value="5" /><br/>
day: <input type="text" name="day" value="6" /><br/>
<input type="submit" value="submit" />
</form:form>
フォーム結果:
some date: ${testCommand.someDate}
プロパティ エディタ:
public class TestPropertyEditor extends PropertyEditorSupport {
private WebRequest webRequest;
public TestPropertyEditor(WebRequest webRequest) {
this.webRequest = webRequest;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
Map<String, String[]> parameterMap = webRequest.getParameterMap();
// should validate these...
Integer year = Integer.valueOf(parameterMap.get("year")[0]);
Integer month = Integer.valueOf(parameterMap.get("month")[0]);
Integer day = Integer.valueOf(parameterMap.get("day")[0]);
try {
String value = String.format("%1$d-%2$d-%3$d", year, month, day);
setValue(new SimpleDateFormat("yyyy-MM-dd").parse(value));
} catch (ParseException ex) {
setValue(null);
}
}
}