SpringRESTでのURLエンコードされたフォームデータの処理
1. 概要
エンドユーザーにとって、フォーム送信のプロセスは便利であり、ある程度、データを入力して送信ボタンをクリックするのと同じです。 ただし、エンジニアリングの観点からは、バックエンド処理のためにこのデータをクライアント側からサーバー側に確実に送受信するには、エンコードメカニズムが必要です。
このチュートリアルの範囲では、は、SpringWebアプリケーションでそのデータをapplication/x-www-form-urlencodedコンテンツタイプとして送信するフォームの作成に焦点を当てます。
2. フォームデータエンコーディング
フォーム送信に最も一般的に使用されるHTTPメソッドはPOSTです。 ただし、 idempotent フォームの送信には、HTTPGETメソッドを使用することもできます。 また、メソッドを指定する方法は、フォームのメソッド属性を使用することです。
GETメソッドを使用するフォームの場合、フォームデータ全体がクエリ文字列の一部として送信されます。 ただし、POSTメソッドを使用している場合、そのデータはHTTPリクエストの本文の一部として送信されます。
さらに、後者の場合、フォームのenctype属性を使用してデータのエンコードを指定することもできます。これは、 application /x-www-form-urlencodedと2つの値を取ることができます。 multipart /form-data。
2.1. メディアタイプapplication/ x-www-form-urlencoded
HTML フォームのデフォルト値は、enctype属性のapplication / x-www-form-urlencodedです。これは、データが完全にテキストである基本的なユースケースを処理するためです。 それでも、ユースケースにファイルデータのサポートが含まれる場合は、 multipart /form-dataの値でオーバーライドする必要があります。
基本的に、フォームデータをアンパサンド(&)文字で区切られたキーと値のペアとして送信します。 また、それぞれのキーと値は等号(=)で区切られます。 さらに、すべての予約文字と英数字以外の文字は、パーセントエンコードを使用してエンコードされます。
3. ブラウザでのフォーム送信
基本を説明したので、次に、SpringWebアプリでフィードバック送信の簡単なユースケースのためにURLエンコードされたフォームデータを処理する方法を見てみましょう。
3.1. ドメインモデル
フィードバックフォームでは、コメントとともに送信者の電子メールIDを取得する必要があります。 それでは、フィードバッククラスでドメインモデルを作成しましょう。
public class Feedback {
private String emailId;
private String comment;
}
3.2. フォームを作成
単純なHTMLテンプレートを使用して動的Webフォームを作成するには、プロジェクトでThymeleafを構成する必要があります。 この後、フォームのフィードバックビューを提供するGETエンドポイント/フィードバックを追加する準備が整いました。
@GetMapping(path = "/feedback")
public String getFeedbackForm(Model model) {
Feedback feedback = new Feedback();
model.addAttribute("feedback", feedback);
return "feedback";
}
ユーザー入力をキャプチャするためのモデル属性としてfeedbackを使用していることに注意してください。 次に、feedback.htmlテンプレートにフィードバックビューを作成しましょう。
<form action="#" method="post" th:action="@{/web/feedback}" th:object="${feedback}">
<!-- form fields for feedback's submitter and comment info -->
</form>
もちろん、 enctype 属性を明示的に指定する必要はありません。これは、 application /x-www-form-urlencodedのデフォルト値を選択するためです。
3.3. PRGフロー
ブラウザのフィードバックフォームからのユーザー入力を受け付けているため、 POST / REDIRECT / GET(PRG)送信ワークフローを実装して、重複した送信を回避する必要があります。
まず、フィードバックフォームのアクションハンドラーとして機能するPOSTエンドポイント / web /Feedbackを実装しましょう。
@PostMapping(
path = "/web/feedback",
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public String handleBrowserSubmissions(Feedback feedback) throws Exception {
// Save feedback data
return "redirect:/feedback/success";
}
次に、GETリクエストを処理するリダイレクトエンドポイント / Feedback /successを実装できます。
@GetMapping("/feedback/success")
public ResponseEntity<String> getSuccess() {
return new ResponseEntity<String>("Thank you for submitting feedback.", HttpStatus.OK);
}
ブラウザでのフォーム送信ワークフローの機能を検証するには、 localhost:8080 /Feedbackにアクセスしてみましょう。
最後に、フォームデータがURLエンコードされた形式で送信されていることを確認することもできます。
emailId=abc%40example.com&comment=Sample+Feedback
4. ブラウザ以外のリクエスト
ブラウザベースのHTTPクライアントがない場合があります。 代わりに、クライアントはcURLやPostmanなどのユーティリティである可能性があります。 このような場合、HTMLWebフォームは必要ありません。 代わりに、POST要求を処理する /Feedbackエンドポイントを実装できます。
@PostMapping(
path = "/feedback",
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public ResponseEntity<String> handleNonBrowserSubmissions(@RequestBody Feedback feedback) throws Exception {
// Save feedback data
return new ResponseEntity<String>("Thank you for submitting feedback", HttpStatus.OK);
}
データフローにHTMLフォームがない場合、必ずしもPRGパターンを実装する必要はありません。 ただし、リソースがAPPLICATION_FORM_URLENCODED_VALUEメディアタイプを受け入れるように指定する必要があります。
最後に、cURLリクエストでテストできます。
curl -X POST \
http://localhost:8080/feedback \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'emailId=abc%40example.com&comment=Sample%20Feedback'
4.1. FormHttpMessageConverter基本
application / x-www-form-urlencoded データを送信するHTTPリクエストは、Content-Typeヘッダーでこれを指定する必要があります。 内部的には、Springは FormHttpMessageConverter クラスを使用してこのデータを読み取り、メソッドパラメーターにバインドします。
メソッドパラメーターのタイプがMultiValueMapの場合、@ RequestParamまたは@RequestBodyアノテーションを使用して、HTTPリクエストの本文に適切にバインドできます。これは、サーブレットAPIがクエリパラメーターを組み合わせるためです。データをパラメータと呼ばれる単一のマップに形成します。これにはリクエスト本文の自動解析が含まれます。
@PostMapping(
path = "/feedback",
consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE})
public ResponseEntity<String> handleNonBrowserSubmissions(
@RequestParam MultiValueMap<String,String> paramMap) throws Exception {
// Save feedback data
return new ResponseEntity<String>("Thank you for submitting feedback", HttpStatus.OK);
}
ただし、フィードバックドメインオブジェクトなど、MultiValueMap以外のタイプのメソッドパラメーターの場合は、@RequestBodyアノテーションのみを使用する必要があります。
5. 結論
このチュートリアルでは、Webフォームでのフォームデータのエンコードについて簡単に学びました。 また、Spring Boot Webアプリにフィードバックフォームを実装することにより、ブラウザーおよびブラウザー以外のHTTP要求のURLエンコードされたデータを処理する方法についても説明しました。
いつものように、チュートリアルの完全なソースコードは、GitHubでから入手できます。