Spring Handler Method Argument 2 - Request Parameter(query or form data)

25516 ワード

「要求パラメータ」(Request Paramter)がスプリングHandlerメソッドでどのように処理されるかをまとめてみます.
Http Query Paramterまたは本文に移動できます.スプリングは、この2つのパラメータを要求パラメータと見なし、同じと見なします.

@RequestParam

@Controller
public class EventController {
	@GetMapping("/events/{id}")
    @ResponseBody
    public Event getEvents(
    	@PathVariable Integer id,
        @RequestParam(required=false, defaultValue="None") String name) {
    	Event event = new Event();
        event.setId(id);
        return event;
    }
}
@RequestParamでパラメータを受信して処理required属性は必須です.defaultValue属性がパラメータを受信できない場合は、属性の値に設定します.@RequestParam(value="name") String nameValueを使用してパラメータに異なる名前を指定できますが、コードを短くするには一致することをお勧めします.

パラメータをMap形式で処理


別の形で
@Controller
public class EventController {
	@GetMapping("/events/{id}")
    @ResponseBody
    public Event getEvents(
    	@PathVariable Integer id,
        @RequestParam Map<String, String> params) {
    	Event event = new Event();
        event.setId(params.get("name"));
        return event;
    }
}
前述したように、Mapタイプ@RequestParamを使用する場合、Mapを使用することができる.

テストメソッド


Handlerが次のように定義されている場合:
@GetMapping("/event/{id}")
@ResponseBody
public Event getEvent(@PathVariable Integer id,
                      @RequestParam String name,
                      @RequestParam Integer limit) {
    Event event = new Event();
    event.setId(id);
    event.setName(name);
    event.setLimit(limit);
    return event;
}
MockMvcを使用して要求パラメータをテストします.


import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


@SpringBootTest
@AutoConfigureMockMvc
class EventControllerTest {
    @Autowired
    MockMvc mockMvc;

    @Test
    public void getEventTest() throws Exception {
        mockMvc.perform(get("/events/1")
                .param("name", "A")
                .param("limit", "10"))
                .andDo(print())
                .andExpect(status().isOk());
    }
}
伝達パラメータのテストには、paramを使用します.

@ModelAttribute


メソッドArgumentに@ModelAttributeを適用すると、モデルのプロパティにアクセスできます.
適切な宣言を使用すると、自分で実行する必要があるqueryパラメータとformフィールドをグループ化および変換する代わりに使用できます.これは、スプリングがデータバインド操作の代わりになることを意味します.
次のコードに代わります.
@GetMapping("/events")
@ResponseBody
public Event getEvent(@RequestParam String name,
                      @RequestParam Integer limit) {
    Event event = new Event();
    event.setName(name);
    event.setLimit(limit);
    return event;
}
使用@ModelAttribute
@PostMapping("/event")
@ResponseBody
public Event getEvent(@ModelAttribute Event event) {
    return event;
}
query paramterまたはformフィールドにアクセスするだけです.
ただし、Binding中に無効な値が存在します(入力した文字列がIntegerを変換できない場合).
この場合、@ModelAttibuteは、各フィールド値を検証する役割を果たすこともできる.異常値(特別な設定なし)が発生した場合、応答400.ただし、誤ったフォーマットを自分で処理したい場合は、このような状況が発生する可能性があります.

@ModelAttributeを使用してBindingResultを使用してフィールド値を検証し、処理します。


@ModelAttributeが適用されているArgumentの隣にBindingResultがArgumentとして受信された場合、Binding Errorは異常なしになります.
@PostMapping("/event")
@ResponseBody
public Event getEvent(@ModelAttribute  Event event, BindingResult bindingResult) {
    if(bindingResult.hasErrors())
    {
        bindingResult.getAllErrors().forEach(error -> {
            System.out.println("===================");
            System.out.println(error);
        });
    }
    return event;
}
BindingResultのエラーをコンソールのコードに書き込みます.
前述したように、@ModelAttributeはバインドに失敗した場合にのみエラーが発生します.フィールド値の範囲をさらにカスタマイズする場合は、@Validまたは@Validatedオペレーティングシステムを使用します.

@Valid、@Validated検証モデルの使用

@PostMapping("/event")
@ResponseBody
public Event getEvent(@ModelAttribute  Event event, BindingResult bindingResult) {
    if(bindingResult.hasErrors())
    {
        bindingResult.getAllErrors().forEach(error -> {
            System.out.println("===================");
            System.out.println(error);
        });
    }
    return event;
}
イベントのLimit値の範囲を制限する場合は、@Min設定および@ValidをHandler Arcgumentに適用します.
public class Event {
    ...
    @Min(0)
    private Long limit;
    ...
}
Annotation(制約@Min(0))を適用し、次の要求を処理します.
mockMvc.perform(post("/event")
                .param("limit", "-30"))
                .andDo(print())
                .andExpect(status().isOk());
コンソールのBinding Errorは次のとおりです.
===================
Field error in object 'event' on field 'limit': rejected value [-30]; 
ただし、@Valid@Validatedの違いは、@Validatedであり、もしそうであれば、グループを指定して検証することができる.

@ModelAttributeのクリーンアップ

@ModelAttributeでは、ReqeustParameterをモデルに割り当て、各データに適切なデータをバインドできます.特別な設定がない場合、バインディングに失敗すると400 BadRequstが返されます.BindingResult ArcgumentがHandler Arcgumentとして受信された場合、Binding Errorは内部で処理できます.
また、@Validおよび@Validatedを使用して、各フィールドを検証することもできます.

Spring MVC処理Binding Error


コードを記述するには、Thymeleafのコードを使用する必要があります.そのため、エラーを処理する簡単な典型的なスキームを記述する必要があります.
表示
  • GET /events/form:Form画面
  • ユーザーはFormのフィールドを入力します.(異常入力制限の値は負です.)
  • POST /eventsPOSTによる登録フィールドの要求
  • ハンドルは、フォームフィールド値
  • Spring@ModelAttributeおよび@Validに検証およびバインドされます.
  • 検証に失敗した場合、BindingResultには失敗理由Errorが含まれ、BindingResultはデフォルトでモデルに表示され、Error理由のあるGET /events/formの画面に戻ります.
  • 検証に成功すると、別のイベントリスト画面にリダイレクトされます.