首頁 > 軟體

springboot中的controller注意事項說明

2022-03-18 16:00:40

關於controller注意事項

spring boot的controller水深無比,經過學習,我總結一些tips,以便以後參照,減少錯誤:

1.controller主要有兩個標籤

@Controller和@RestController,兩個標籤無法同時發揮作用,前者標註的類只能返回靜態檔案,後者標註的類用於返回資料型別如json字串

2.使用@Controller標籤時

templates下的檔案並不能被識別(自己試驗過,發現和網上很多說法都不一樣),只有static資料夾下檔案能直接被讀取,具體程式碼如下:

@RequestMapping(value="/", method= RequestMethod.GET)
public String home() {
    return "views/index.html";
}

這裡static作為根目錄被存取。

各種controller的寫法

最近玩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/me@example.com/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": "someone@example.com"}

然後請求模型還是沿用之前的:

class UserCreateRequest {undefined
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) {}
}

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com