最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot接口國(guó)際化異常信息的完整實(shí)現(xiàn)方案

 更新時(shí)間:2025年12月15日 08:57:16   作者:哈哈哈笑什么  
要實(shí)現(xiàn)Java后端接口根據(jù)請(qǐng)求頭的語(yǔ)言字段返回對(duì)應(yīng)語(yǔ)言的異常信息,核心思路是國(guó)際化配置 + 全局異常處理 + 請(qǐng)求頭語(yǔ)言解析,以下是基于Spring Boot的完整實(shí)現(xiàn)方案,需要的朋友可以參考下

一、整體方案設(shè)計(jì)

  1. 語(yǔ)言標(biāo)識(shí)約定:請(qǐng)求頭中自定義lang字段(或復(fù)用Accept-Language),值如zh-CN(中文)、en-US(英文),默認(rèn)值zh-CN。
  2. 國(guó)際化資源文件:存放不同語(yǔ)言的錯(cuò)誤信息模板。
  3. 自定義異常類:攜帶錯(cuò)誤碼和參數(shù),便于匹配國(guó)際化信息。
  4. 語(yǔ)言解析工具:從請(qǐng)求頭提取語(yǔ)言標(biāo)識(shí),轉(zhuǎn)換為Locale對(duì)象。
  5. 全局異常處理器:捕獲異常后,根據(jù)語(yǔ)言解析結(jié)果加載對(duì)應(yīng)語(yǔ)言的錯(cuò)誤信息并返回。
  6. MessageSource配置:加載國(guó)際化資源文件,支持參數(shù)替換。

二、具體實(shí)現(xiàn)步驟

1. 配置國(guó)際化資源文件

src/main/resources下創(chuàng)建i18n目錄,存放多語(yǔ)言配置文件:

messages_zh_CN.properties(中文)

# 業(yè)務(wù)異常
error.user.not.found=用戶不存在,用戶ID:{0}
error.param.invalid=參數(shù)無(wú)效,參數(shù)名:{0}
# 系統(tǒng)異常
error.system.error=系統(tǒng)內(nèi)部錯(cuò)誤,請(qǐng)稍后重試

messages_en_US.properties(英文)

# 業(yè)務(wù)異常
error.user.not.found=User not found, User ID: {0}
error.param.invalid=Invalid parameter, Parameter name: {0}
# 系統(tǒng)異常
error.system.error=System internal error, please try again later

2. 自定義業(yè)務(wù)異常類

創(chuàng)建BusinessException,用于拋出業(yè)務(wù)相關(guān)異常,攜帶錯(cuò)誤碼和參數(shù):

package com.example.demo.exception;

import lombok.Getter;

/**
 * 自定義業(yè)務(wù)異常
 */
@Getter
public class BusinessException extends RuntimeException {
    // 錯(cuò)誤碼(對(duì)應(yīng)國(guó)際化配置文件的key)
    private final String errorCode;
    // 錯(cuò)誤信息參數(shù)(用于替換國(guó)際化模板中的占位符)
    private final Object[] args;

    public BusinessException(String errorCode) {
        this(errorCode, null);
    }

    public BusinessException(String errorCode, Object... args) {
        super(errorCode);
        this.errorCode = errorCode;
        this.args = args;
    }
}

3. 語(yǔ)言解析工具類

創(chuàng)建LocaleUtils,從Http請(qǐng)求頭解析語(yǔ)言標(biāo)識(shí),轉(zhuǎn)換為Locale

package com.example.demo.utils;

import jakarta.servlet.http.HttpServletRequest;
import java.util.Locale;

/**
 * 語(yǔ)言解析工具類
 */
public class LocaleUtils {
    // 請(qǐng)求頭中語(yǔ)言字段名(自定義,也可復(fù)用Accept-Language)
    private static final String LANG_HEADER = "lang";
    // 默認(rèn)語(yǔ)言
    private static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;

    /**
     * 從請(qǐng)求頭解析Locale
     */
    public static Locale getLocaleFromRequest(HttpServletRequest request) {
        if (request == null) {
            return DEFAULT_LOCALE;
        }
        // 獲取請(qǐng)求頭中的lang值
        String lang = request.getHeader(LANG_HEADER);
        if (lang == null || lang.trim().isEmpty()) {
            return DEFAULT_LOCALE;
        }
        // 解析lang值(支持zh-CN、en-US、zh、en等格式)
        String[] langParts = lang.split("-");
        return switch (langParts.length) {
            case 1 -> new Locale(langParts[0]); // 如zh -> Locale("zh")
            case 2 -> new Locale(langParts[0], langParts[1]); // 如zh-CN -> Locale("zh", "CN")
            default -> DEFAULT_LOCALE;
        };
    }
}

4. 配置MessageSource(加載國(guó)際化資源)

在Spring Boot配置類中注冊(cè)MessageSource Bean,加載國(guó)際化資源文件:

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;

import java.nio.charset.StandardCharsets;
import java.util.Locale;

/**
 * 國(guó)際化配置
 */
@Configuration
public class I18nConfig {

    /**
     * 配置MessageSource,加載國(guó)際化資源文件
     */
    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        // 指定資源文件基礎(chǔ)名(i18n目錄下的messages)
        messageSource.setBasename("i18n/messages");
        // 設(shè)置編碼,避免中文亂碼
        messageSource.setDefaultEncoding(StandardCharsets.UTF_8.name());
        // 默認(rèn)語(yǔ)言
        messageSource.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
        // 緩存時(shí)間(秒),開發(fā)時(shí)設(shè)為0,生產(chǎn)可設(shè)為3600
        messageSource.setCacheSeconds(0);
        return messageSource;
    }

    /**
     * 配置LocaleResolver(可選,復(fù)用Accept-Language時(shí)生效)
     */
    @Bean
    public LocaleResolver localeResolver() {
        AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
        resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
        return resolver;
    }
}

5. 全局異常處理器

創(chuàng)建GlobalExceptionHandler,捕獲異常并返回對(duì)應(yīng)語(yǔ)言的錯(cuò)誤信息:

package com.example.demo.exception;

import com.example.demo.utils.LocaleUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Locale;

/**
 * 全局異常處理器
 */
@RestControllerAdvice
@AllArgsConstructor
public class GlobalExceptionHandler {

    // 注入國(guó)際化消息源
    private final MessageSource messageSource;

    /**
     * 處理業(yè)務(wù)異常
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result<?> handleBusinessException(BusinessException e, HttpServletRequest request) {
        // 解析請(qǐng)求頭的語(yǔ)言
        Locale locale = LocaleUtils.getLocaleFromRequest(request);
        // 從國(guó)際化配置中獲取對(duì)應(yīng)語(yǔ)言的錯(cuò)誤信息
        String errorMessage = messageSource.getMessage(
                e.getErrorCode(), // 錯(cuò)誤碼(對(duì)應(yīng)配置文件的key)
                e.getArgs(),      // 占位符參數(shù)
                e.getErrorCode(), // 默認(rèn)值(配置文件無(wú)該key時(shí)使用)
                locale            // 語(yǔ)言
        );
        return Result.fail(HttpStatus.BAD_REQUEST.value(), errorMessage);
    }

    /**
     * 處理系統(tǒng)異常
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result<?> handleSystemException(Exception e, HttpServletRequest request) {
        Locale locale = LocaleUtils.getLocaleFromRequest(request);
        String errorMessage = messageSource.getMessage(
                "error.system.error",
                null,
                "System internal error",
                locale
        );
        // 打印系統(tǒng)異常棧(生產(chǎn)環(huán)境可接入日志框架)
        e.printStackTrace();
        return Result.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), errorMessage);
    }

    /**
     * 統(tǒng)一返回結(jié)果封裝
     */
    @Data
    @AllArgsConstructor
    public static class Result<T> {
        private int code;       // 狀態(tài)碼
        private String message; // 錯(cuò)誤信息
        private T data;         // 數(shù)據(jù)(異常時(shí)為null)

        public static <T> Result<T> fail(int code, String message) {
            return new Result<>(code, message, null);
        }
    }
}

6. 接口示例(測(cè)試異常返回)

創(chuàng)建UserController,模擬查詢用戶接口,不存在時(shí)拋業(yè)務(wù)異常:

package com.example.demo.controller;

import com.example.demo.exception.BusinessException;
import com.example.demo.exception.GlobalExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 測(cè)試接口
 */
@RestController
@RequestMapping("/users")
public class UserController {

    /**
     * 根據(jù)用戶ID查詢用戶
     */
    @GetMapping("/{userId}")
    public GlobalExceptionHandler.Result<?> getUser(@PathVariable Long userId) {
        // 模擬用戶不存在的場(chǎng)景
        if (userId <= 0) {
            // 拋業(yè)務(wù)異常,攜帶錯(cuò)誤碼和參數(shù)(用戶ID)
            throw new BusinessException("error.user.not.found", userId);
        }
        return new GlobalExceptionHandler.Result<>(200, "success", "用戶信息:" + userId);
    }
}

三、測(cè)試驗(yàn)證

使用Postman/Curl調(diào)用接口,通過(guò)請(qǐng)求頭lang指定語(yǔ)言:

1. 測(cè)試中文返回(lang=zh-CN)

請(qǐng)求:

GET http://localhost:8080/users/-1
Header: lang=zh-CN

響應(yīng):

{
  "code": 400,
  "message": "用戶不存在,用戶ID:-1",
  "data": null
}

2. 測(cè)試英文返回(lang=en-US)

請(qǐng)求:

GET http://localhost:8080/users/-1
Header: lang=en-US

響應(yīng):

{
  "code": 400,
  "message": "User not found, User ID: -1",
  "data": null
}

3. 測(cè)試默認(rèn)語(yǔ)言(不傳遞lang)

請(qǐng)求:

GET http://localhost:8080/users/-1

響應(yīng):

{
  "code": 400,
  "message": "用戶不存在,用戶ID:-1",
  "data": null
}

四、擴(kuò)展說(shuō)明

復(fù)用Accept-Language:若想復(fù)用HTTP標(biāo)準(zhǔn)頭Accept-Language,只需修改LocaleUtils中的LANG_HEADERAccept-Language,并適配解析邏輯(Accept-Language格式如zh-CN,zh;q=0.9,en;q=0.8)。

更多語(yǔ)言支持:新增messages_ja_JP.properties(日語(yǔ))等配置文件,即可支持更多語(yǔ)言,無(wú)需修改代碼。

錯(cuò)誤碼規(guī)范:建議將錯(cuò)誤碼枚舉化(如ErrorCode.USER_NOT_FOUND),避免硬編碼。

生產(chǎn)環(huán)境優(yōu)化

  1. 異常棧信息不要返回給前端,僅打印到日志;
  2. MessageSourcecacheSeconds設(shè)為3600,提升性能;
  3. 接入日志框架(如Logback/Log4j2)記錄異常詳情。

五、核心依賴(pom.xml)

確保Spring Boot基礎(chǔ)依賴已引入:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

該方案實(shí)現(xiàn)了異常信息的國(guó)際化,符合RESTful接口設(shè)計(jì)規(guī)范,且易于擴(kuò)展和維護(hù)。

以上就是SpringBoot接口國(guó)際化異常信息的完整實(shí)現(xiàn)方案的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot接口國(guó)際化異常信息的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 純Java實(shí)現(xiàn)高效MP3音頻合并的詳細(xì)方案

    純Java實(shí)現(xiàn)高效MP3音頻合并的詳細(xì)方案

    在 Java 音頻處理中,MP3 格式的合并一直是一項(xiàng)技術(shù)難點(diǎn),大多數(shù)開發(fā)者默認(rèn)使用 FFmpeg 命令行來(lái)完成任務(wù),但會(huì)帶來(lái)許多問(wèn)題,所以本文將介紹一種 純 Java 實(shí)現(xiàn)的 MP3 合并方法,需要的朋友可以參考下
    2025-11-11
  • Java中為什么start方法不能重復(fù)調(diào)用而run方法可以?

    Java中為什么start方法不能重復(fù)調(diào)用而run方法可以?

    這篇文章主要介紹了Java中為什么start方法不能重復(fù)調(diào)用而run方法可以?帶著疑問(wèn)一起學(xué)習(xí)下面文章的詳細(xì)內(nèi)容吧
    2022-05-05
  • MyBatis一對(duì)多關(guān)系使用@Many注解的實(shí)現(xiàn)

    MyBatis一對(duì)多關(guān)系使用@Many注解的實(shí)現(xiàn)

    本文介紹了在MyBatis中實(shí)現(xiàn)一對(duì)多查詢的方法,包括數(shù)據(jù)表和數(shù)據(jù)類的設(shè)計(jì),以及使用@Many注解進(jìn)行查詢,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-11-11
  • 使用IDEA如何打包發(fā)布SpringBoot并部署到云服務(wù)器

    使用IDEA如何打包發(fā)布SpringBoot并部署到云服務(wù)器

    這篇文章主要介紹了使用IDEA如何打包發(fā)布SpringBoot并部署到云服務(wù)器問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • SpringCloud?微服務(wù)框架詳解

    SpringCloud?微服務(wù)框架詳解

    本文詳細(xì)介紹了單體架構(gòu)、垂直架構(gòu)、分布式架構(gòu)和微服務(wù)架構(gòu)的特點(diǎn)和優(yōu)缺點(diǎn),重點(diǎn)講解了微服務(wù)架構(gòu)的四個(gè)原則,最后介紹了如何使用Nacos進(jìn)行配置中心管理,并實(shí)現(xiàn)了配置的熱更新,感興趣的朋友跟隨小編一起看看吧
    2025-11-11
  • Java使用FFmpeg提取音頻的詳細(xì)指南

    Java使用FFmpeg提取音頻的詳細(xì)指南

    FFmpeg 是一個(gè)開源的多媒體處理工具,支持視頻、音頻的編碼、解碼、轉(zhuǎn)換等多種功能,本文將詳細(xì)講解如何使用 FFmpeg 提取音頻,包括常見(jiàn)的音頻格式提取、音頻質(zhì)量調(diào)整、高級(jí)處理操作等,內(nèi)容淺顯易懂,適合初學(xué)者快速掌握,需要的朋友可以參考下
    2024-11-11
  • java泛型中占位符T和?有什么區(qū)別

    java泛型中占位符T和?有什么區(qū)別

    泛型中占位符T和?有什么區(qū)別?有的人可能弄不清楚,本文主要介紹了java泛型中占位符T和?有什么區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2022-05-05
  • Java獲取當(dāng)前時(shí)間并轉(zhuǎn)化為yyyy-MM-dd?HH:mm:ss格式的多種方式

    Java獲取當(dāng)前時(shí)間并轉(zhuǎn)化為yyyy-MM-dd?HH:mm:ss格式的多種方式

    這篇文章主要介紹了Java獲取當(dāng)前時(shí)間并轉(zhuǎn)化為yyyy-MM-dd?HH:mm:ss格式的多種方式,每種方式結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • 淺談MyBatisPlus注解@EnumValue避坑

    淺談MyBatisPlus注解@EnumValue避坑

    本文介紹如何使用MyBatisPlus的注解@EnumValue聲明枚舉類,同時(shí)指出需要避開的幾個(gè)常見(jiàn)坑點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09
  • Java中類與對(duì)象全面解析(附實(shí)例代碼)

    Java中類與對(duì)象全面解析(附實(shí)例代碼)

    這篇文章主要介紹了Java中類與對(duì)象的相關(guān)資料,重點(diǎn)講解了封裝的概念,通過(guò)private關(guān)鍵字和getter/setter方法來(lái)保護(hù)和操作對(duì)象的成員變量,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-05-05

最新評(píng)論

大邑县| 潢川县| 甘肃省| 阿合奇县| 犍为县| 内乡县| 卫辉市| 金门县| 卫辉市| 延安市| 百色市| 沅陵县| 司法| 隆子县| 光山县| 来凤县| 南城县| 遵化市| 利辛县| 大邑县| 勐海县| 邵东县| 澄迈县| 格尔木市| 龙游县| 稷山县| 弥渡县| 措勤县| 阿勒泰市| 新河县| 宝兴县| 通州市| 体育| 台南县| 永清县| 若羌县| 台东县| 长泰县| 万山特区| 石棉县| 察哈|