随着应用程序不断发展以服务于全球受众,本地化成为软件开发的一个重要方面。本地化允许应用程序适应不同的语言和地区,提供用户友好的体验。
在本文中,我将分享我最喜欢的在 Spring Boot 应用程序中处理本地化异常的方法。
后端异常消息的本地化对于创建无缝的用户体验至关重要,尤其是在面向全球受众的应用程序中。
通过在后端本地化这些消息并将它们直接发送到前端,我们可以从前端开发人员的肩上承担管理多种语言的责任。这种方法可确保错误消息在所有平台和语言中保持一致,从而使前端开发人员能够专注于以用户友好的方式(例如在错误 toast 中)显示这些消息。
因此,前端无需处理每种语言的自定义异常消息,从而减少了重复工作和潜在的错误,并确保所有用户都以其首选语言收到清晰且相关的反馈。
请按照以下步骤来实现我们的目标。
首先创建一个从 RuntimeException 扩展的类,并将其命名为 ResponseException。此自定义异常将允许您以更受控的方式处理特定于应用程序的错误。
public class ResponseException extends RuntimeException { }
创建一个单独的类,当发生异常时,该类将在响应中返回。此类可以包含消息、时间戳、错误代码等字段以及您想要传递给前端的任何其他相关信息。
public record ErrorResponse(int status, String message) { }
使用 Spring 的 @ControllerAdvice 注解实现 GlobalExceptionHandler。在此类中,您可以捕获 ResponseException 并根据用户的区域设置将其映射到适当的本地化消息。
@Slf4j @RestControllerAdvice @RequiredArgsConstructor public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler(value = ResponseException.class) public ResponseEntity<ErrorResponse> handleResponseStatusException( ResponseException ex ) { log.error("ResponseException: {}", ex.getMessage()); String message = ex.getMessage(); var errorResponse = new ErrorResponse(ex.getStatus().value(), message); return new ResponseEntity<>(errorResponse, ex.getStatus()); } }
要管理本地化消息,请为每种支持的语言创建属性文件,例如英语的 messages_en.properties、阿塞拜疆语的 messages_az.properties 等。这些文件将包含每个异常消息的键值对,允许 Spring 根据用户的区域设置自动解析正确的消息。
在 src/main/resources 文件夹中创建这些属性文件。
err.username_already_exists.msg=User with username: {0} is already exists.
我已经创建了在 Spring Boot 中处理异常的最低限度。我想你已经熟悉上面的内容了。我们继续添加翻译部分。
修改ResponseException类:
public class ResponseException extends RuntimeException { private final String messageTemplate; private final transient Object[] params; private final Locale locale; public static ResponseException notFound(String messageTemplate, Locale locale) { return new ResponseException(HttpStatus.NOT_FOUND, messageTemplate, null, locale); } public static ResponseException notFound(String messageTemplate, Object[] params, Locale locale) { return new ResponseException(HttpStatus.NOT_FOUND, messageTemplate, params, locale); } public static ResponseException forbidden(String messageTemplate, Locale locale) { return new ResponseException(HttpStatus.FORBIDDEN, messageTemplate, null, locale); } public static ResponseException forbidden(String messageTemplate, Object[] params, Locale locale) { return new ResponseException(HttpStatus.FORBIDDEN, messageTemplate, params, locale); } }
为常用的 HttpStatus 代码创建辅助方法,例如 NOT_FOUND、FORBIDDEN.
您可以通过以下方式使用这些辅助方法:
// some code parts omitted ... userService.findByUsername(username) .orElseThrow(() -> ResponseException.notFound("user_not_found", locale))
在所有属性文件中创建 user_not_found 消息模板。
// file: messages_en.properties user_not_found=User not found // file: messages_az.properties user_not_found=İsdifadəçi tapılmadı
为了在返回前端之前自动替换这些,请更新 GlobalExceptionHandler 类中的方法。
@Slf4j @RestControllerAdvice @RequiredArgsConstructor public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { private final MessageSource messageSource; @ExceptionHandler(value = ResponseException.class) public ResponseEntity<ErrorResponse> handleResponseStatusException( ResponseException ex ) { log.error("ResponseException: {}", ex.getMessage()); String message = ex.getMessage(); String messageTemplate = ex.getMessageTemplate(); if (StringUtils.isNotBlank(messageTemplate)) { message = messageSource.getMessage(messageTemplate, ex.getParams(), ex.getLocale()); } var errorResponse = new ErrorResponse(ex.getStatus().value(), message); return new ResponseEntity<>(errorResponse, ex.getStatus()); } }
这种处理异常的方法非常有用,特别是您必须为异常消息设置动态值。例如,
// file: messages_en.properties err.invalid_phone_number.msg=The phone: {0} is invalid
为了用动态值替换 {0}。
public static ResponseException badRequest( String messageTemplate, Locale locale, String... params ) { return new ResponseException( HttpStatus.BAD_REQUEST, messageTemplate, params, locale ); }
我将 varargs 参数放在最后以传递多个动态参数,而无需每次都创建新方法。
我有一篇关于具有动态值的消息的专门文章。
我有两种获取语言环境的方法:
根据 UI 首选项存储在数据库中的用户区域设置。
一些控制器方法接受可选的 lang 请求参数。当前端开发人员想要查看 UI 在不同语言中的表现时,这对于测试可能很有用。因为每种语言的句子长度都不一样。
今天就到此为止。我希望你喜欢。
源代码可在我的 GitHub 帐户的存储库中找到。
如果您有任何疑问,请随时通过 LinkedIn 与我联系。
以上是在 Spring Boot 中处理异常消息本地化的最佳方法的详细内容。更多信息请关注PHP中文网其他相关文章!