搜尋
首頁Javajava教程在 Spring Boot 中處理異常訊息本地化的最佳方法

Best Way to Handle Localization For Exception Messages in Spring Boot

隨著應用程式不斷發展以服務全球受眾,在地化成為軟體開發的重要方面。在地化允許應用程式適應不同的語言和地區,提供用戶友好的體驗。 

在本文中,我將分享我最喜歡的在 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());
  }
}
</errorresponse>

特定於語言的屬性文件

要管理本地化訊息,請為每種支援的語言建立屬性文件,例如英文的 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_FOUNDFORBIDDEN.

您可以透過以下方式使用這些輔助方法:

// 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());
  }
}
</errorresponse>

如何在異常訊息中使用動態值

這種處理異常的方法非常有用,特別是您必須為異常訊息設定動態值。例如,

// 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 參數放在最後以傳遞多個動態參數,而無需每次都建立新方法。

我有一篇關於具有動態值的消息的專門文章。

從哪裡取得使用者的區域設定?

我有兩種取得語言環境的方法:

  1. 根據 UI 首選項儲存在資料庫中的使用者區域設定。

  2. 一些控制器方法接受可選的 lang 請求參數。當前端開發人員想要查看 UI 在不同語言中的表現時,這對於測試可能很有用。因為每種語言的句子長度都不一樣。

結論

今天就到此為止。我希望你喜歡。

原始程式碼可在我的 GitHub 帳戶的儲存庫中找到。

如果您有任何疑問,請隨時透過 LinkedIn 與我聯繫。

以上是在 Spring Boot 中處理異常訊息本地化的最佳方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
在Java應用程序中緩解平台特定問題的策略是什麼?在Java應用程序中緩解平台特定問題的策略是什麼?May 01, 2025 am 12:20 AM

Java如何緩解平台特定的問題? Java通過JVM和標準庫來實現平台無關性。 1)使用字節碼和JVM抽像操作系統差異;2)標準庫提供跨平台API,如Paths類處理文件路徑,Charset類處理字符編碼;3)實際項目中使用配置文件和多平台測試來優化和調試。

Java的平台獨立性與微服務體系結構之間有什麼關係?Java的平台獨立性與微服務體系結構之間有什麼關係?May 01, 2025 am 12:16 AM

java'splatformentenceenhancesenhancesmicroservicesharchitecture byferingDeploymentFlexible,一致性,可伸縮性和便攜性。 1)DeploymentFlexibilityAllowsibilityAllowsOllowsOllowSorlowsOllowsOllowsOllowSeStorunonAnyPlatformwithajvM.2)penterencyCrossServAccAcrossServAcrossServiCessImplifififiesDeevelopmentandeDe

GRAALVM與Java的平台獨立目標有何關係?GRAALVM與Java的平台獨立目標有何關係?May 01, 2025 am 12:14 AM

GraalVM通過三種方式增強了Java的平台獨立性:1.跨語言互操作,允許Java與其他語言無縫互操作;2.獨立的運行時環境,通過GraalVMNativeImage將Java程序編譯成本地可執行文件;3.性能優化,Graal編譯器生成高效的機器碼,提升Java程序的性能和一致性。

您如何測試Java應用程序的平台兼容性?您如何測試Java應用程序的平台兼容性?May 01, 2025 am 12:09 AM

效率testjavaapplicationsforplatformcompatibility oftheSesteps:1)setUpautomatedTestingTestingActingAcrossMultPlatFormSusingCitoolSlikeSlikeJenkinSorgithUbactions.2)contuctualtemualtemalualTesteTESTENRETESTINGINREALHARTWARETOLEALHARDOELHARDOLEATOCATCHISSUSESUSEUSENINCIENVIRENTMENTS.3)schictcross.3)schoscross.3)

Java編譯器(Javac)在實現平台獨立性中的作用是什麼?Java編譯器(Javac)在實現平台獨立性中的作用是什麼?May 01, 2025 am 12:06 AM

Java編譯器通過將源代碼轉換為平台無關的字節碼,實現了Java的平台獨立性,使得Java程序可以在任何安裝了JVM的操作系統上運行。

在平台獨立性的平台獨立性上使用字節碼優於本機代碼的優點是什麼?在平台獨立性的平台獨立性上使用字節碼優於本機代碼的優點是什麼?Apr 30, 2025 am 12:24 AM

ByteCodeachievesPlatFormIndenceByByByByByByExecutedBoviratualMachine(VM),允許CodetorunonanyplatformwithTheApprepreprepvm.Forexample,Javabytecodecodecodecodecanrunonanydevicewithajvm

Java真的100%獨立於平台嗎?為什麼或為什麼不呢?Java真的100%獨立於平台嗎?為什麼或為什麼不呢?Apr 30, 2025 am 12:18 AM

Java不能做到100%的平台獨立性,但其平台獨立性通過JVM和字節碼實現,確保代碼在不同平台上運行。具體實現包括:1.編譯成字節碼;2.JVM的解釋執行;3.標準庫的一致性。然而,JVM實現差異、操作系統和硬件差異以及第三方庫的兼容性可能影響其平台獨立性。

Java的平台獨立性如何支持代碼可維護性?Java的平台獨立性如何支持代碼可維護性?Apr 30, 2025 am 12:15 AM

Java通過“一次編寫,到處運行”實現平台獨立性,提升代碼可維護性:1.代碼重用性高,減少重複開發;2.維護成本低,只需一處修改;3.團隊協作效率高,方便知識共享。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)