0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Spring MVC】で simple な form の作り方

Last updated at Posted at 2022-01-07

まえがき

  • シンプルを目指すので、<form:form> 形式のタグライブラリ不使用にしたい
  • form拡張タグは便利で良いのですが、独自の書き方を覚える手間があるので
  • 自分で作る Form オブジェクトに値を入れたい(パラメータ個別にしない)
  • エラーハンドリングもなるべくシンプルに
  • エスケープ処理は自前で c:out または fn:escapeXml
  • 試行錯誤して何とかなりそうなので忘備録として残します

環境

  • Spring framework 4 (古い...)
  • Bootstrap 3 (古い...)
  • JDK 1.8
  • JSP

作り方

  • URL (例)
  • /contextPath/inputAction/ : Form 表示URL
  • /contextPath/nextAction/ : Form の post 先 URL
  • /contextPath/finishAction/ : 完了画面

form 準備 (html/jsp)

inputAction.jsp
		<form id="form" method="post" action="/contextPath/nextAction/" class="form-horizontal">
		<div class="row row-center">
			<div class="col-xs-10">
				<div class="form-group">
					<label for="param1" class="control-label col-xs-2">パラメータ1</label>
					<div class="col-xs-8">
						<input id="param1" name="param1" type="text"
							class="form-control" value="${fn:escapeXml(form.param1)}">
						<%-- エラー時メッセージ表示用 --%>
						<c:if test="${!empty errorMap['param1']}">
						<div style="text-align:left"><small class="text-danger"><c:out value="${errorMap['param1']}"/></small></div>
						</c:if>
					</div>
				</div>
			</div>
			<div class="col-xs-10">
				<div class="form-group">
					<label for="param2" class="control-label col-xs-2">パラメータ2</label>
					<div class="col-xs-8">
						<input id="param2" name="param2" type="text"
							class="form-control" value="${fn:escapeXml(form.param2)}">
						<%-- エラー時メッセージ表示用 --%>
						<c:if test="${!empty errorMap['param2']}">
						<div style="text-align:left"><small class="text-danger"><c:out value="${errorMap['param2']}"/></small></div>
						</c:if>
					</div>
				</div>
				<div class="form-group">
					<div class="col-xs-offset-2 col-xs-10" style="text-align:left">
						<button id="formSubmit" name="formSubmit" type="submit" class="btn btn-primary">登録</button>
					</div>
				</div>
			</div>
		</div>
		</form>
  • ${form} は後ほど説明します Form オブジェクト
  • ${errorMap} はエラー内容が入ってくる Map です
  • escapeXml を自前でやる必要あり
  • とてもシンプルにできます。パラメータが増えたら同様に増やすだけ。

CustomForm クラス

CustomForm.java
public class CustomForm {

	private Long 		param1;
	private String 		param2;

	private Map<String, Object> errorMap;

	// コンストラクタ
	public CustomForm() {
		errorMap = Collections.synchronizedMap(new MultiValueMap<String, Object>());
	}
	// バリデーション
	public boolean validate() {
		if (param1 == null || param1 < 0) {
			errorMap.put("param1", "パラメータ1が正しくありません。");
		}
		if (StringUtils.isBlank(param2) || StringUtils.length(param2) > 50) {
			errorMap.put("param2", "パラメータ2の長さが1~50文字ではありません。");
		}
		if (errorMap.isEmpty()) {
			return true;
		}
		return false;
	}
	// getter,setter,etc...
}
  • org.apache.commons.collections4.map.MultiValueMap をエラーマップにしているのでエラー内容を複数設定可能

inputAction 用 メソッド

CustomFormController.java
	@RequestMapping(value = "/inputAction/", method = RequestMethod.GET)
	public String inputAction(
			Model model, HttpServletRequest request) {

		return inputActionInternal(null, model, request);
	}
	public String inputActionInternal(CustomForm errorForm,
			Model model, HttpServletRequest request) {
	
		// 何か処理があれば追加…

		// 初回表示用
		if (errorForm == null) {
			CustomForm form = new CustomForm();
			model.addAttribute("form", form);
		}
		else {
			// エラー表示用
			model.addAttribute("form", errorForm);
		}
		return "inputAction";
	}
  • エラー時の Form オブジェクトを表示するためにメソッドを2つに分けています

nextAction 用 メソッド

CustomFormController.java
	@RequestMapping(value = "/nextAction/", method = {RequestMethod.GET,RequestMethod.POST})
	public Object nextAction(@ModelAttribute CustomForm form,
			Model model, HttpServletRequest request, HttpServletResponse response, RedirectAttributes attributes) {

		// バリデーション
		if (!form.validate()) {
			// 入力エラー
			return inputActionInternal(form, model, request);
		}

		// データ登録など…

		// 完了画面へリダイレクト
		RedirectView redirect = new RedirectView("/finishAction/");
		attributes.addFlashAttribute("form", form);
		redirect.setContextRelative(true);
		redirect.setExposeModelAttributes(false);
		return redirect;
	}

完了画面は表示するだけなので省略します。
<form:form> 形式じゃなくても割と使えます。
以上、お疲れさまでした!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?