3

誰か助けてくれませんか。ユーザーからデータを収集する必要がある Spring MVC / Webflow Web アプリを作成しています。バックエンド スキーマを反映するフォーム バッキング オブジェクトがあります (クラスの生成には JAXB が使用されたと思います)。とにかく、キャプチャする必要があるフィールドの 1 つは DOB です。フォーム バッキング オブジェクトでは、XMLGregorianCalendar 型の単一のプロパティです。

ほとんどの場合、フォームの html 入力フィールドは、フォーム バッキング オブジェクトのプロパティに 1 対 1 でマッピングされます。ゲッターとセッター)。良い :)

しかし、日付フィールドは少し異なります。フォーム バッキング オブジェクトでは、1 つの getter/setter ペアを持つ 1 つのプロパティのみです。しかし、画面上では 3 つの別々のフィールドとして表示したい場合があります。おそらく、日のドロップダウン、月のドロップダウン、年のテキストボックスです。

この種の問題は、バックエンド テクノロジに関係なく、すべての Web アプリケーションで必ず発生します。他の人はどのように対処しているのか気になります。

私は2つの考えを持っています:

1) dobDay、dobMonth、および dobYear のプロパティを持つようにフォーム バッキング オブジェクトを拡張し、バリデータの一部として 3 つの値を取得し、それらから実際の DOB プロパティを設定します。私は過去にこれを行ったことがありますが、ある程度は機能しますが、特に Web アプリに多くの日付がある場合は、少し面倒に感じます。

2) この魔法を実行する jsp taglib を見つけるか、作成してください。フォームをレンダリングするときにこの作業がどのように機能するかを確認できます.taglibはFBOのプロパティ名で呼び出すことができ、現在の日付値を取得してから、出力3つのhtmlフィールドに書き込むことができます. しかし、提出がどのように機能するかわかりません.3つのhtmlフィールドを読み取り、それらをFBOの不動産に「接着」する必要があります.

ですから、これはただの助けを求める呼びかけにすぎません。過去に、他の人はこの種のことで何をしたのでしょうか?

あなたの考えに感謝します

ネイサン

4

1 に答える 1

4

どちらのオプションも使用できますが、コマンド オブジェクトに日付コンポーネントを含めるのはあまり巧妙ではないことに同意する傾向があります。

ページに日付フィールド用の非表示フィールドを追加し、その値を使用して日、月、年の 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);
        }
    }
}
于 2012-08-12T17:11:27.417 に答える