# RequestParameter

參考資料:(<https://www.baeldung.com/spring-request-param>) ModifyDate:2019/03/02

**@RequestParam 和 屬性，還有 @RequestParam & @PathVariable 的區別**

## RequestMapping

參考資料:(<https://www.baeldung.com/spring-requestmapping>)

```
@RequestMapping(value = "/ex/foos", method = RequestMethod.GET)
@ResponseBody
public String getFoosBySimplePath(){
    return "Get some Foos";
}
```

## 簡單映射 A Simple Mapping (如何接到 QueryString 的參數)

QueryString 的 **key** 和程式內的 **變數名稱** 相同，則可以直接Mapping

```
@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam String id) {
    return "ID: " + id;
}
```

```
http://localhost:8080/api/foos?id=abc
----
ID: abc
```

## 指定請求參數 Specifying the Request Parameter Name

如果希望 QueryString 的 **key** 和程式內的 **變數名稱** 不同，則可以使用 **name** 這個屬性進行配置。

```
@PostMapping("/api/foos")
@ResponseBody
public String addFoo(@RequestParam(name = "id") String fooId, @RequestParam String name) { 
    return "ID: " + fooId + " Name: " + name;
}
```

這三個都可以達到同樣效果

```
@RequestParam(name = "id") String fooId
@RequestParam(value = "id") String fooId
@RequestParam("id") String fooId
```

## 製作可選的請求參數 Making an Optional Request Parameter

通常 @RequestParam 會默認為必填，這樣倘若沒有打參數，就會跳出錯誤

```
GET /api/foos HTTP/1.1
-----
400 Bad Request
Required String parameter 'id' is not present
```

所以我們可以將配置，改為可選

```
@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam(required = false) String id) { 
    return "ID: " + id;
}
```

這樣，不論是

```
http://localhost:8080/api/foos?id=abc
----
ID: abc



http://localhost:8080/api/foos
----
ID: null
```

該呼叫都可以正常調用，但是沒有傳的參數會綁定為Null。

## 請求參數的默認值 A Default Value for the Request Parameter

利用屬性 **defaultValue** 設置 默認值

```
@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam(defaultValue = "test") String id) {
    return "ID: " + id;
}
```

```
http://localhost:8080/api/foos
----
ID: test


http://localhost:8080/api/foos?id=abc
----
ID: abc
```

當設置 defaultValue 這個屬性時，就像 required = false，而事實上 也的確被設置為 false。

## 映射所有參數 Mapping All Parameters

直接將 QueryString 的所有參數 key,value ，都放到一個 Map 裡

```
@PostMapping("/api/foos")
@ResponseBody
public String updateFoos(@RequestParam Map<String,String> allParams) {
    return "Parameters are " + allParams.entrySet();
}
```

```
curl -X POST -F 'name=abc' -F 'id=123' http://localhost:8080/api/foos
-----
Parameters are {[name=abc], [id=123]}
```

```
http://localhost:8080/api/foos?id=12&magic=Brian
-----
Parameters are [id=12, magic=Brian]
```

## 映射多值參數 Mapping a Multi-Value Parameter

QueryString 的 一個 key 可以有多個 value

```
@GetMapping("/api/foos")
@ResponseBody
public String getFoos(@RequestParam List<String> id) {
    return "IDs are " + id + " size = " + id.size();
}
```

分別可以使用下列兩種

```
http://localhost:8080/api/foos?id=1,2,3
----
IDs are [1, 2, 3] size = 3

http://localhost:8080/api/foos?id=1&id=4
----
IDs are [1, 4] size = 2
```

但是不可以同時使用

```
http://localhost:8080/api/foos?id=1,2,3&id=4
-----
IDs are [1,2,3, 4] size = 2
```

## @RequestParam vs @PathVariable

@RequestParam 和 @PathVariable 都可以從URI提取值

### 查詢參數 & URI路徑

@RequestParam 是從查詢參數(QueryString) @PathVariable 是從URI路徑(ResourcePath)

@PathVariable

```
@GetMapping("/foos/{id}")
@ResponseBody
public String getFooById(@PathVariable String id) {
    return "ID: " + id;
}
```

```
http://localhost:8080/foos/abc
----
ID: abc
```

@RequestParam

```
@GetMapping("/foos")
@ResponseBody
public String getFooByIdUsingQueryParam(@RequestParam String id) {
    return "ID: " + id;
}
```

```
http://localhost:8080/foos?id=abc
----
ID: abc
```

### 編碼與精確值

@PathVariable 是從URI路徑 獲得參數，所以不會被編碼。 @RequestParam 則會被編碼。

@PathVariable

```
http://localhost:8080/foos/ab+c
----
ID: ab+c
```

@RequestParam

```
http://localhost:8080/foos?id=ab+c
----
ID: ab c
```

### 可選值

@PathVariable 從 Spring 4.3.3 開始，required 這個屬性讓其變得可選。

**用大括號去配置多個路徑**

```
@GetMapping({"/myfoos/optional", "/myfoos/optional/{id}"}) //注意大括號
@ResponseBody
public String getFooByOptionalId(@PathVariable(required = false) String id){
    return "ID: " + id;
}
```

```
http://localhost:8080/myfoos/optional/abc
----
ID: abc

http://localhost:8080/myfoos/optional
----
ID: null
```

**當使用 @PathVariable 的可選屬性時，要注意路徑衝突**


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://brianwu.gitbook.io/brian/java/spring/requestparam.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
