一般方式
@RestController
public class StudentController {
@PostMapping("/students")
public String create(@RequestBody Student student) {
if(student.getId() == null) {
throw new RuntimeException("id 不可為 null");
}
return "執行資料庫的 Create 操作";
}
}
當我們request body 只傳了name 沒有 id時


驗證請求參數 pom.xml 設定
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
提醒: Spring Boot 2.3 之後的才需要額外去加上這個validation
@Valid
對要驗證的參數 加上 @NotNull
代表說這個id的值不可以為null
這樣就可以去檢查id 這個請求參數的值了
import javax.validation.constraints.NotNull;
public class Student {
@NotNull // 要選 javax.validation.constraints 這個package
Integer id;
}
在這邊要加上 @Valid 這樣 vo 的 @NotNull 才會生效
@RestController
public class StudentController {
@PostMapping("/students")
public String create(@RequestBody @Valid Student student) {
return "執行資料庫的 Create 操作";
}
}
Talend API Tester 少了一個id 結果會怎麼樣?
request body
console: [Field error in object 'student' on field 'id': rejected value [null];
2023-02-05 14:38:17.616 WARN 5272 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver :
Resolved [org.springframework.web.bind.MethodArgumentNotValidException:
Validation failed for argument [0] in public java.lang.String com.example.demo.StudentController.create(com.example.demo.Student):
[Field error in object 'student' on field 'id': rejected value [null];
codes [NotNull.student.id,NotNull.id,NotNull.java.lang.Integer,NotNull];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.id,id];
arguments []; default message [id]]; default message [不得是空值]] ]
content-type 錯誤
Talend API Tester
如果沒有加上Content-Type:application/json
Spring Boot 無法判斷是request body 是json格式 會跳415

在header 加上 Content-Type:application/json

console:
2023-02-05 14:09:29.639 WARN 9992 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver :
Resolved [org.springframework.web.HttpMediaTypeNotSupportedException:
Content type 'text/plain;charset=UTF-8' not supported]
json 格式錯誤
Talend API Tester
request body
console:
2023-02-05 14:36:10.232 WARN 5272 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver :
Resolved [org.springframework.http.converter.HttpMessageNotReadableException:
JSON parse error: Unexpected character ('"' (code 34)): was expecting comma to separate Object entries;
nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('"' (code 34)):
was expecting comma to separate Object entries<EOL> at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream);
line: 3, column: 4]]
常用的 驗證請求參數的註解
| @NotNull | 不能為null |
| @NotBlank | 不能為null ,且不能空白的字串 , 用在驗證String 類型的參數上 |
| @NotEmpty | 不能為null ,且size必須>0 , 用在驗證集合類型 (List ,Set ,Map) 的參數上 |
| @Min | 值必須 >= value , 用在驗證數字類型的參數上 |
| @Max | 值必須 <= value , 用在驗證數字類型的參數上 |
@NotBlank 測試
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public class Student {
@NotNull
Integer id;
@NotBlank
String name;
}
Talend API Tester
request body
console:
2023-02-05 14:47:17.182 WARN 11184 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver :
Resolved [org.springframework.web.bind.MethodArgumentNotValidException:
Validation failed for argument [0] in public java.lang.String com.example.demo.StudentController.create(com.example.demo.Student):
[Field error in object 'student' on field 'name':
rejected value [null]; codes [NotBlank.student.name,NotBlank.name,NotBlank.java.lang.String,NotBlank];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.name,name];
arguments []; default message [name]]; default message [不得空白]] ]
@NotEmpty 測試
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
public class Student {
@NotNull
Integer id;
@NotBlank
String name;
@NotEmpty
List<String> courseList;
}
Talend API Tester
request body
console: courseList is nullconsole: courseList 是空集合
因為size>0 ,所以通過了檢查
可以同時加上多個驗證請求參數的註解
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
public class Student {
@NotNull
@Min(1000)
Integer id;
}
其他 驗證請求參數的註解
| @Size(min ,max) | min <= 字串長度 or 集合的size <= max ,可以只設定 max 或 min |
| 必須符合電子郵件的格式 | |
| @Pattern(regexp) | 必須符合正規表達式的regexp |
| @Past | 必須比當前時間早 ,也就是被註解的參數必須是以前的時間 |
| @Future | 必須比當前時間晚 ,也就是被註解的參數必須是未來的時間 |
| @AssertTrue | 必須為 true ,用在驗證boolean 類型的參數上 |
| @AssertFalse | 必須為 false ,用在驗證boolean 類型的參數上 |
| @Null | 必須為null |
總結
驗證請求參數的註解 分成兩種
@Valid + @驗證請求參數
@RestController
public class StudentController {
@PostMapping("/students")
public String create(@RequestBody @Valid Student student) { // 驗證請求參數的註解 @Valid
return "執行資料庫的 Create 操作";
}
}
@Validated + @驗證請求參數
直接把驗證請求參數寫在裡面 要讓裡面註解的 @Min(100) 生效 需要在最上面加上 @Validated
@RestController
@Validated
public class StudentController {
@GetMapping("/students/{studentId}")
public String read(@PathVariable @Min(100) Integer studentId) { // 可以直接使用 @Min(100)
return "執行資料庫的 Read 操作";
}
}
http status code
用來表示這次http 請求的結果為何
可以根據首位數字分成五大類
1xx: 資訊
2xx: 成功
| 200 | OK | 請求成功 |
| 201 | Created | 請求成功且新的資源成功被創建 ,通常用在POST 的response |
| 202 | Accepted | 請求已經接受 , 但尚未處理完成 |
3xx: 重新導向
| 301 | Moved Permanently | 永久性重新導向 , 新的 url 應放在 response header 的 “Location” 中返回 , 通常會用在網頁班加上 |
| 302 | Found | 臨時重新導向 , 新的臨時性的 url 應放在 response header 的 “Location” 中返回 |
4xx: 前端請求錯誤
| 400 | Bad Request | 前端的請求參數有錯誤 (ex: 前端傳給後端的參數名稱不同 、請求格式有問題) |
| 401 | Unauthorized | 沒有通過身份驗證 |
| 403 | Forbidden | 請求背後端拒絕 , 通常是權限不足導致的 |
| 404 | Not Found | 網頁不存在 , 可能是資源被移走或是 url 輸入錯誤 |
5xx: 後端處理有問題
| 500 | Internal Server Error | 後端在執行程式時發生錯誤 , 可能是程式內有bug 導致的 |
| 503 | Service Unavailable | 由於臨時維護或是流量太大 , 後端目前沒有辦法處理請求 |
| 504 | Gateway Timeout | 請求超時 |
Spring Boot 預設返回的 http 狀態碼
正常執行 test 方法 ,返回200
@RestController
public class MyController5 {
@RequestMapping("/test")
public String test() {
return "Hello World";
}
}