Rumah  >  Artikel  >  Java  >  Cara Terbaik untuk Mengendalikan Penyetempatan Untuk Mesej Pengecualian dalam Spring Boot

Cara Terbaik untuk Mengendalikan Penyetempatan Untuk Mesej Pengecualian dalam Spring Boot

WBOY
WBOYasal
2024-09-06 06:03:02453semak imbas

Best Way to Handle Localization For Exception Messages in Spring Boot

Apabila aplikasi berkembang untuk melayani khalayak global, penyetempatan menjadi aspek penting dalam pembangunan perisian. Penyetempatan membolehkan aplikasi menyesuaikan diri dengan bahasa dan wilayah yang berbeza, memberikan pengalaman yang mesra pengguna. 

Dalam artikel ini, saya akan berkongsi cara kegemaran saya untuk mengendalikan pengecualian setempat dalam aplikasi Spring Boot.

Mengapa Kami Memerlukan Penyetempatan untuk Mesej Pengecualian?

Penyetempatan mesej pengecualian di bahagian belakang adalah penting untuk mencipta pengalaman pengguna yang lancar, terutamanya dalam aplikasi yang menyasarkan khalayak global. 

Dengan menyetempatkan mesej ini pada bahagian belakang dan menghantarnya terus ke bahagian hadapan, kami boleh mengambil tanggungjawab untuk menguruskan berbilang bahasa di luar bahu pembangun bahagian hadapan. Pendekatan ini memastikan bahawa mesej ralat adalah konsisten merentas semua platform dan bahasa, membolehkan pembangun bahagian hadapan menumpukan pada memaparkan mesej ini dengan cara yang mesra pengguna, seperti dalam roti bakar ralat. 

Akibatnya, bahagian hadapan tidak perlu mengendalikan mesej pengecualian tersuai untuk setiap bahasa, mengurangkan pertindihan usaha dan potensi ralat serta memastikan semua pengguna menerima maklum balas yang jelas dan berkaitan dalam bahasa pilihan mereka.

Bagaimana untuk Mencapai Matlamat kami di Backend dengan Mudah?

Ikuti langkah di bawah untuk mencapai matlamat kami. 

Kelas Pengecualian Am

Mulakan dengan mencipta kelas yang menjangkau daripada RuntimeException dan namakannya ResponseException. Pengecualian tersuai ini akan membolehkan anda mengendalikan ralat khusus aplikasi dengan cara yang lebih terkawal.

public class ResponseException extends RuntimeException {

}

Kelas Ralat Balasan

Buat kelas berasingan yang akan dikembalikan dalam respons apabila pengecualian berlaku. Kelas ini boleh mengandungi medan seperti mesej, cap masa, kod ralat dan sebarang maklumat lain yang berkaitan yang anda ingin hantar ke bahagian hadapan.

public record ErrorResponse(int status, String message) {

}

Pengendali Pengecualian Global

Laksanakan GlobalExceptionHandler menggunakan anotasi @ControllerAdvice Spring. Dalam kelas ini, anda boleh menangkap ResponseException dan memetakannya kepada mesej setempat yang sesuai berdasarkan tempat pengguna.

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

Fail Harta Khusus Bahasa

Untuk mengurus mesej setempat, buat fail sifat untuk setiap bahasa yang disokong, seperti messages_en.properties untuk bahasa Inggeris, messages_az.properties untuk Azerbaijan dan sebagainya. Fail ini akan mengandungi pasangan nilai kunci untuk setiap mesej pengecualian, membolehkan Spring menyelesaikan mesej yang betul secara automatik berdasarkan tempat pengguna.

Buat fail hartanah tersebut dalam folder src/main/resources.

err.username_already_exists.msg=User with username: {0} is already exists.

Laksanakan Bahagian Penyetempatan

Saya telah mencipta minimum untuk mengendalikan pengecualian dalam Spring Boot. Saya andaikan anda sudah biasa dengan perkara di atas. Mari teruskan menambah bahagian terjemahan.

Ubah suai kelas 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);
  }  
}

Cipta kaedah pembantu untuk kod HttpStatus yang kerap digunakan seperti TIDAK_DAPAT, DILARANG.

Anda boleh menggunakan kaedah pembantu ini dengan cara berikut:

// some code parts omitted ...
userService.findByUsername(username)
  .orElseThrow(() -> ResponseException.notFound("user_not_found", locale))

Buat templat mesej user_not_found dalam semua fail harta anda.

// file: messages_en.properties
user_not_found=User not found

// file: messages_az.properties
user_not_found=İsdifadəçi tapılmadı

Untuk menggantikannya secara automatik sebelum kembali ke bahagian hadapan, kaedah kemas kini dalam kelas 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());
  }
}

Cara Menggunakan Nilai Dinamik dalam Mesej Pengecualian

Cara pengendalian pengecualian ini berguna terutamanya anda perlu menetapkan nilai dinamik untuk mesej pengecualian anda. Contohnya,

// file: messages_en.properties
err.invalid_phone_number.msg=The phone: {0} is invalid

Untuk menggantikan {0} dengan nilai dinamik.

public static ResponseException badRequest(
      String messageTemplate, 
      Locale locale,
      String... params
) {
  return new ResponseException(
        HttpStatus.BAD_REQUEST, 
        messageTemplate, 
        params, 
        locale
  );
}

Saya telah meletakkan parameter varargs di penghujung untuk menghantar berbilang parameter dinamik tanpa membuat kaedah baharu setiap kali.

Saya mempunyai artikel khusus tentang Mesej dengan nilai Dinamik.

Di mana untuk Mendapatkan Tempat Pengguna?

Saya mempunyai dua pendekatan untuk mendapatkan tempat:

  1. Tempat pengguna yang disimpan pada pangkalan data berdasarkan pilihan UI.

  2. Sesetengah kaedah pengawal menerima parameter permintaan bahasa pilihan. Ini mungkin berguna untuk ujian apabila pembangun bahagian hadapan ingin melihat bagaimana UI akan berada dalam bahasa yang berbeza. Kerana panjang ayat dalam setiap bahasa tidak sama.

Kesimpulan

Itu sahaja untuk hari ini. Saya harap anda menikmati.

Kod sumber tersedia pada repositori dalam akaun GitHub saya.

Jika anda mempunyai sebarang pertanyaan, sila hubungi saya melalui LinkedIn.

Atas ialah kandungan terperinci Cara Terbaik untuk Mengendalikan Penyetempatan Untuk Mesej Pengecualian dalam Spring Boot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn