最近玩SpingBoot,以下是一些Controller的各種寫法
本文我們將分爲四部分:
1、Controller的類型(傳統的 和 REST)
2、路由(Routes)
3、如何接收數據
4、Controller示例
Controller 類型
你也許每天都在使用Spring ,但你知道controller有幾種類型嗎?其實controller是有兩種的,一種就是傳統的web的那種controller,而另外一種就是REST類型的controller。
@Controller 通常是被使用服務於web 頁面的。默認,你的controller方法返回的是一個string 串,是表示要展示哪個模板頁面或者是要跳轉到哪裏去。
@RestController 就是專門用在編寫API的時候,特別那種返回一個JSON,或者是XML等等。然後方法返回的是可以是一個對象,是一個可以被序列化的對象。
當然了你也可以通過controller來實現返回JSON、XML這些。只是這裏爲了"REST",得另立門戶,這樣會更加的清晰明瞭。
路由(Routes)
這裏的路由就是指http method。(GET,POST,PUT,PATCH,DELETE)。
HTTP Methods
在Spring boot中,http method可以被用類似“*Mapping”的格式來表示:
@GetMapping
@PostMapping
@PutMapping
@PatchMapping
@DeleteMapping
然後這些註解中可以添加path,像下面這樣:
例子: @GetMapping("/users")
一個比較典型的REST controller 一般是像下面這樣來映射路由的:
@RestController
public class UsersController {
@GetMapping("/users")
public List<User> index() {...}
@GetMapping("/users/{id}")
public User show(...) {...}
@PostMapping("/users")
public User create(...) {...}
@PutMapping("/users/{id}")
public User update(...) {...}
@DeleteMapping("/users/{id}")
public void delete(...) {...}
}
還有一種比較常見的做法是通過在controller類上添加一個@RequestMapping註解。這樣相當於可以把上面的所有的mapping前綴添加到這裏。
像下面這樣(基於上面的例子修改):
@RestController
@RequestMapping("/users")
public class UsersController {
@GetMapping
public List<User> index() {...}
@GetMapping("{id}")
public User show(...) {...}
@PostMapping
public User create(...) {...}
@PutMapping("{id}")
public User update(...) {...}
@DeleteMapping("{id}")
public void delete(...) {...}
}
返回狀態
Controller的方法可以去指定一個返回狀態碼。默認的是返回一個200 OK,如果是沒有返回值(void)則返回 204 No Content。
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User create(...) {...}
路徑變量
你可以通過添加@PathVariable註解來把路徑上的值捕獲下來:
// DELETE /users/123
@DeleteMapping("/users/{id}")
public void delete(@PathVariable long id) {...}
默認情況下,參數名必須要和路徑上的變量名一樣。但你也可以通過下面的方式來修改,就是你通過給@PathVariable賦值爲路徑變量名,然後參數名就可以是不一樣的了:
// GET /users/[email protected]/edit
@GetMapping("/users/{email}/edit"
public String edit(@PathVariable("email") String userEmail) {...}
接收數據
查詢字符參數
如果是通過?xxx=xxx&yyy=yyy來傳遞過來的參數,那麼我們可以通過@RequestParam來獲取:
// GET /users?count=10
@GetMapping("/users")
public List<User> index(@RequestParam int count) {...}
默認的話,變量名必須要和查詢字符參數是一樣的。你也可以通過下面的方式來修改:
// GET /users?num_per_page=50
@GetMapping("/users")
public List<User> index(@RequestParam("num_per_page") int numPerPage) {...}
提交HTML表單數據
如果我們想要創建一個用戶。這時候,我麼可能在前端,寫下面這樣一個form:
<form action="/users" method="POST">
<input name="name"/>
<input name="email"/>
<button type="submit">Create User</button>
</form>
現在我們創建一個請求模型,用來匹配我們的前端form結構:
class UserCreateRequest {
private String name;
private String email;
/* Getters & Setters omitted */
}
然後我們就可以在controller對應的方法上來捕獲form裏的值,我們通過對參數添加一個@ModelAttribute註解就可以實現了:
@PostMapping("/users")
public User create(@ModelAttribute UserCreateRequest request) {...}
提交JSON
就像上面例子那樣,我們創建一個用戶,然後是一個JSON格式:
{ "name": "Som Eone", "email": "[email protected]"}
然後請求模型還是沿用之前的:
class UserCreateRequest {
private String name;
private String email;
}
然後我們使用@RequestBody來捕獲前端發送過來的JSON串,然後反序列化到我們的請求模型UserCreateRequest:
@PostMapping
public User create(@RequestBody UserCreateRequest request) {...}
Controller 舉例
以下是使用上述所有註解創建Controller的示例。 沒有具體邏輯,只是簡單的展示上面說到的各個註解。
傳統的controller
這類型的controller返回值表示要展示的頁面或要跳轉到哪個請求。
@Controller
@RequestMapping("/users")
public class UsersController {
@GetMapping
public String index() {
return "users/index";
}
@GetMapping("{id}")
public String show(@PathVariable long id) {
return "users/show";
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public String create(@ModelAttribute UserCreateRequest request) {
return "redirect:/users";
}
@PutMapping("{id}")
public String update(@PathVariable long id, @RequestBody UserUpdateRequest request) {
return "redirect:/users/" + id;
}
@DeleteMapping("{id}")
public String delete(@PathVariable long id) {
return "redirect:/users";
}
}
REST controller
這類型的controller返回值是一些對象,這些對象要被序列化成JSON、XML等其他格式,並不是表示要跳轉到哪個HTML模板。
@RestController
@RequestMapping("/users")
public class UsersController {
@GetMapping
public List<User> index() { return new ArrayList<User>();
}
@GetMapping("{id}")
public User show(@PathVariable long id) { return new User();
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User create(@RequestBody UserCreateRequest request) {
return new User();
}
@PutMapping("{id}")
public User update(@PathVariable long id, @RequestBody UserUpdateRequest request) {
return new User();
}
@DeleteMapping("{id}")
public void delete(@PathVariable long id) {}
}