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.

【覚書】パラメーターのチェックもしたいダウンロード処理

Posted at

こういうパターンはどうだろう、というメモ以外のなにものでもない。

諸元

ユーザーが画面で指定した条件に基づいてデータ検索を行い、結果をCSVでダウンロードさせるWebアプリケーションの機能を作ることになったんだ。
え、めっちゃよくあるやつじゃん。朝飯前じゃん。
ああそうさ、めっちゃよくあるやつさ。ピースオブケークさ。
だけどジョニィ?ちょっと待ってくれよ。
「CSVダウンロード」か「バリデーションエラー」かでサーバーのレスポンスを切り替えなきゃいけない。
おっと、オーケーオーケー、ジョニィ、君の言いたいことはわかる。わかるよ。
それだけならちょっと複雑でサーバー側の挙動がわかりにくくなるけど出来ないことはないさ。
問題は***「画面に表示しているけどサーバー側に送らない情報が存在」しているうえ、「それを共通機能で取得しているから独自で追加対応が必要」***なんだ。
例えばユーザーIDだけをサーバーに送っているけど名称は表示だけに使っている、そんな情報を想像してくれ。
それを(無駄だけど)リクエストに含めたとしても、バリデーションエラー時に状態復元をフックしなきゃいけない。
面倒くさい。
ジョニィ、きみはせっかちすぎる。君の悪い癖だぜ。
そう、表示だけ情報にまつわる部分、3パターンもあるんだ…いい加減面倒くさすぎる

どうするか

2段階に分けちゃえ。

  1. Ajaxで事前チェック
  2. エラーがない場合にformをsubmit

問題は

  • その気になればチェックした値をユーザーが書き換えてダウンロード要求だせちゃう
  • Springを使ってるけどバリデーション(HibernateValidator)結果をどう反映するか
    • JSPなら<form:errors>で自動的にやってくれるけど…

前者はパラメーターとソルト値からハッシュを生成し、トークンとして返すことでパラメーター改竄を検出可能にして対応としました。
ダウンロードリクエスト時にトークンが無かったり、再生成したハッシュと異なっていたらNG。

後者は数年前に実装したけど使ってなかった共通部品を使い、SpringのBindingResultからi18nの解決を行った上、パラメーター名と紐づけたJSONとして返却し、JavaScript側でゴリゴリDOM書き換えて対応しました:(

どうも<form:errors path="target"><span id="target.errors"/>を生成するようなので同様のものをdisplay:noneのうえ用意し書き換える…。
このあたりはもっといいやり方がある気がする。

今日知った小ネタ

lombokの@Dataで特定項目をhashCode(とequals)から除きたい!

@EqualsAndHashCode(exclude = {"token"})

Ajaxリクエスト時はトークンがなく、ダウンロードリクエスト時はトークンがあるので差が出ちゃう。

jQueryのセレクタはドットが含まれていると動かない!

このようにエスケープする

$('#target\\.errors').text('');

なお、トークンをリクエストヘッダーにくっつけられないかな、と思ったけどどうもHTMLだけじゃ実現できない様子:(
<meta>タグにありそうだけどね。

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?