
使用NestJS和Prisma構建REST API:身份驗證
新建項目相關的類
新建 MyResponse,作為統一樣式 JSON 的實體類
public class MyResponse{
private String status;
private String message;
// 省略 getter setter constructor
}
新建 User,傳入參數的檢驗
public class User {
@NotEmpty(message = "用戶名不能為空")
@Pattern(regexp = "^[a-zA-Z0-9]{3,16}$", message = "用戶名需3到16位的英文,數字")
private String username;
// 省略 getter setter constructor
}
新建 MyException,自定義異常
public class MyException extends Throwable{
private final String status;
private final String message;
public MyException(String status,String message) {
this.status=status;
this.message=message;
}
public String getStatus() {
return status;
}
@Override
public String getMessage() {
return message;
}
}
新建 ErrorController
@RestController
public class ErrorController {
@RequestMapping("/throw")
public String myThrow() throws MyException {
// Throw MyException
throw new MyException("Error", "Throw MyException");
}
@PostMapping("/user")
public String user(@RequestBody @Valid final User user) {
// 參數檢驗
return "參數檢驗通過";
}
}
運行項目,分別訪問不存在的路徑和上述路徑:例如用 Get 方法訪問 /user,會返回如下:
{
"timestamp": "2020-04-16T16:43:41.123+0000",
"status": 405,
"error": "Method Not Allowed",
"message": "Request method 'GET' not supported",
"path": "/user"
}
添加全局異常處理,@RestControllerAdvice
新建 ErrorRestControllerAdvice
@RestControllerAdvice
public class ErrorRestControllerAdvice {
/** 全局異常捕捉處理 返回 401 狀態 */
@ExceptionHandler(value = Exception.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public MyResponse errorHandler(Exception ex) {
return new MyResponse("ERROR", ex.getMessage());
}
/** 自定義異常捕獲,返回 500 狀態 */
@ExceptionHandler(value = MyException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public MyResponse myException(MyException e) {
return new MyResponse(e.getStatus(), e.getMessage());
}
/** Http Method 異常 返回 405 */
@ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public MyResponse httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
return new MyResponse("ERROR", e.getMessage());
}
/** 404異常,返回 404 NOT_FOUND 異常 */
@ExceptionHandler(value = NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public MyResponse noHandlerFoundException(NoHandlerFoundException e) {
return new MyResponse("ERROR", "資源不存在");
}
/** RequestBody 為空時返回此錯誤提醒,返回400 bad Request */
@ExceptionHandler(value = HttpMessageNotReadableException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public MyResponse httpMessageNotReadableException() {
return new MyResponse("ERROR", "請傳入參數");
}
/** RequestBody某個必須輸入的參數為空時 返回 400 Bad Request */
@ExceptionHandler(value = MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public MyResponse methodDtoNotValidException(Exception ex) {
MethodArgumentNotValidException c = (MethodArgumentNotValidException) ex;
List<ObjectError> errors = c.getBindingResult().getAllErrors();
StringBuffer errorMsg = new StringBuffer();
errors.forEach(x -> errorMsg.append(x.getDefaultMessage()).append(" "));
return new MyResponse("ERROR", errorMsg.toString());
}
}
代碼解析:
@RestControllerAdvice
:等于 @ResponseBody
+ @ControllerAdvice
,@ControllerAdvice
是 Spring 增強的 Controller 控制器,用于定義@ExceptionHandler
,@InitBinder
和@ModelAttribute
方法
@ExceptionHandler(value = Exception.class)
: 是 將 value 捕獲到的異常交由其注解的方法處理。如果是注解在 @Controller
中,僅僅會當前類中生效,而注解在 @ControllerAdvice
則是全局有效的。
@ResponseStatus(HttpStatus.BAD_REQUEST)
: 設置該異常的狀態返回碼。
重新運行項目,分別訪問不存在的路徑,?/throw,/user,觀察其前后的不同。例如通過 GET 訪問 /user,則會返回如下:
{
"status": "ERROR",
"message": "Request method 'GET' not supported"
}
Spring Boot 的微信登錄因為個人開發者無法申請,因此暫定不寫了。下一篇計劃是 Spring Boot 整合 Redis 緩存。
文章轉自微信公眾號@編程技術進階