SpringBoot グローバル例外処理 - 404/500 を解決
SpringBoot Spring Boot アプリケーションで HTTP 404 および 500 エラーをグローバルに処理するには、例外ハンドラー クラスをカスタマイズし、@ControllerAdvice
注釈@ExceptionHandler
これらの例外をインターセプトして処理します。
解決
以下は可能な実装です。これは、パラメーター タイプの不一致、パラメーター形式エラー、およびHTTP GET リクエスト内のPathVariable
他のすべての未処理の例外をキャッチし、エラー コードとエラー メッセージを含む Map オブジェクトを返します。
@ControllerAdvice
public class GlobalExceptionHandler {
// 捕获 PathVariable 参数类型不匹配或格式错误的异常,并返回错误信息
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public Map<String, Object> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException ex) {
return createErrorResponse(HttpStatus.BAD_REQUEST.value(), "请求参数有误: " + ex.getMessage());
}
// 捕获其他未处理的异常,并返回错误信息
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public Map<String, Object> handleUncaughtException(Exception ex) {
return createErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统内部错误: " + ex.getMessage());
}
// 创建包含错误码和错误消息的 Map 对象
private Map<String, Object> createErrorResponse(int code, String message) {
Map<String, Object> errorResponse = new HashMap<>();
errorResponse.put("code", code);
errorResponse.put("message", message);
return errorResponse;
}
}
説明します:
この例では:
@ControllerAdvice
および@ExceptionHandler
注釈は、このクラスをグローバル例外ハンドラーとして識別し、MethodArgumentTypeMismatchException
その他。@ResponseStatus(HttpStatus.BAD_REQUEST)
および を使用して、@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
例外の HTTP 応答ステータス コードを指定します。- アノテーションを使用して、
@ResponseBody
テンプレート エンジンでレンダリングされたビューをレンダリングするのではなく、具体的なレスポンス ボディ オブジェクトを返すことを Spring Boot アプリケーションに伝えます。
createErrorResponse()
メソッドは、エラー コードとエラー メッセージを含む Map オブジェクトを作成して返します。
一般的なグローバル例外処理
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 处理 HTTP 404 错误
*/
@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ApiError handleNotFound(HttpServletRequest req, Exception ex) {
return new ApiError(HttpStatus.NOT_FOUND.value(), "无该资源: " + req.getRequestURI());
}
/**
* 处理 HTTP 500 错误
*/
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ApiError handleInternalServerError(HttpServletRequest req, Exception ex) {
return new ApiError(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器内部错误: " + ex.getMessage());
}
/**
* 处理用户登录异常
*/
@ExceptionHandler(UserLoginException.class)
@ResponseStatus(HttpStatus.UNAUTHORIZED)
@ResponseBody
public ApiError handleUserLoginException(HttpServletRequest req, UserLoginException ex) {
return new ApiError(HttpStatus.UNAUTHORIZED.value(), "用户登录失败: " + ex.getMessage());
}
/**
* 处理其他所有未处理的异常
*/
@ExceptionHandler(Throwable.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ApiError handleOtherExceptions(HttpServletRequest req, Throwable ex) {
return new ApiError(HttpStatus.INTERNAL_SERVER_ERROR.value(), "系统内部错误: " + ex.getMessage());
}
}
トリガー例外
コントローラーでユーザー ログインの失敗シナリオをシミュレートし、UserLoginException をスローします。
@RestController
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/login")
public String login(@RequestBody LoginForm form) {
// 验证用户名和密码
if (!userService.validate(form.getUsername(), form.getPassword())) {
// 用户不存在或密码错误,抛出 UserLoginException 异常
throw new UserLoginException("用户名或密码不正确");
}
// 登录成功,返回 token 或用户信息
// ......
}
}