多语字段前端处理方案

网站多语,后台返回字段包含了规定的命名规范。可以用此方法覆盖原字段的值来赋值。

场景:   

后台返回data为

data = {
    "status":1,
    "data":{
        "labelGroups":[
            {
                "labelGroupName":"领域",
                "labelGroupNameExt0":"Field",
                "labelGroupNameExt1":"領域",
                "labels":[
                    {
                        "labelName":"数字化建模",
                        "labelNameExt0":"Digital Modeling",
                        "labelNameExt1":"數位化建模",
                        "labelNameExt2":null,
                        "labelNameExt3":null,
                        "labelNameExt4":null,
                        "labelNameExt5":null
                    }
                ]
            },
            {
                "labelGroupName":"类别",
                "labelGroupNameExt0":"Category",
                "labelGroupNameExt1":"類別",
                "labels":[
                    {
                        "labelName":"社交沟通",
                        "labelNameExt0":"Social Communication",
                        "labelNameExt1":"社交溝通",
                        "labelNameExt2":null,
                        "labelNameExt3":null,
                        "labelNameExt4":null,
                        "labelNameExt5":null,
                    }
                ]
            }
        ],
        "applications":[
            {
                "applicationName":"文库",
                "applicationNameExt0":"Library",
                "applicationNameExt1":"文庫",
            }
        ]
    }
}

可以看出来  约定好的多语字段后边增加Ext+${index}     

前端处理方案 :  因为共用了同一个请求的Function ,所以在请求返回值 统一处理。

const _diff = (_index, _data, _Ext) => {
  const loop = (data) => {
    if (typeof data === "object" && Array.isArray(data) && data.length) {
      data.forEach(item => {
        if (typeof item === "object" && (item.length !== 0 || Object.keys(item).length)) {
          loop(item);
        }
      });
    } else if (typeof data === "object" && Object.keys(data).length) {
      // 获取 JSON VALUE  数组   [a,a1,b,c]
      const dataKeys = Object.keys(data);
      dataKeys.forEach((item, index) => {
        const curKey = item + _Ext + _index;
        if (dataKeys.includes(curKey)) {
          const currItem = data[curKey];
          if(currItem){
            data[item] = currItem;
          }
        }
        const currData = data[item];
        if (!currData) return;
        if (typeof currData === "object" && (currData.length !== 0 || Object.keys(currData).length)) {
          loop(currData);
        }
      });
    }
  }
  loop(_data);
}

_diff   方法中有三个参数。 

第一个参数为  我们知道当前语种对应的index,

_data 为result返回的值,

_Ext 为多语字段区分的变量。

调用方法 : _diff(0, data, 'Ext');

<think>我们参考用户提供的引用内容,特别是引用[3]中提到的通过浏览器Network查看请求头信息的方法,以及引用[4]中关于从请求中获取信息的两种方式(request和session)。用户的问题是如何在后端获取HTTP请求头中的字段。根据引用[3],我们知道HTTP请求的Header信息可以在浏览器的Network面板中查看。那么,在后台代码中,我们也应该能够从HTTP请求对象中获取Header信息。引用[4]提到了在Java Web开发中,可以通过request对象来获取信息。具体来说,有两种方式:1.通过request.getSession()获取session,然后设置或获取属性(跨请求)2.通过request.setAttribute()和request.getAttribute()在当前请求中设置和获取属性(仅当前请求)但是,这里我们需要获取的是HTTP请求头(Header)中的信息,而HTTP请求头是每次请求都会携带的。因此,我们应该使用request对象直接获取Header。在Java Servlet中,我们可以通过HttpServletRequest对象的getHeader方法获取请求头字段的值。具体步骤:1.在控制器方法中,注入HttpServletRequest对象(或者使用Spring框架提供的@RequestHeader注解)。2.调用request.getHeader("字段名")获取对应的值。另外,常见的字段在HTTP请求头中通常是"Accept-Language",但有时前端应用也会自定义一个Header字段(如"X-Language")来传递言信息。因此,我们需要明确前端传递言信息的字段名。如果前端按照标准传递,则使用"Accept-Language";如果是自定义字段,则需要知道该字段名。下面提供两种常见的实现方式:方式一:直接通过HttpServletRequest对象获取```java@GetMapping("/some-endpoint")public ResponseEntity<?>someMethod(HttpServletRequestrequest){String languageHeader= request.getHeader("Accept-Language");//或者如果是自定义字段,比如"X-Language"// StringlanguageHeader =request.getHeader("X-Language");//处理言信息...}```方式二:使用Spring MVC的@RequestHeader注解(推荐,更简洁)```java@GetMapping("/some-endpoint")publicResponseEntity<?> someMethod(@RequestHeader("Accept-Language") StringacceptLanguage) {//直接使用acceptLanguage变量//或者如果是自定义字段// @RequestHeader("X-Language") StringcustomLanguage}```注意:如果请求头中可能没有该字段,我们可以设置required属性为false,并提供一个默认值:```java@RequestHeader(value= "X-Language", required= false, defaultValue= "en")String language```另外,引用[2]提到了JSON数据格式层嵌套的问题,虽然与当前问题不直接相关,但提醒我们在处理请求数据时要注意数据结构。综上所述,获取请求头中的字段,主要使用HttpServletRequest的getHeader方法或使用@RequestHeader注解。下面我们给出一个完整的示例代码:示例1:使用HttpServletRequest```javaimport javax.servlet.http.HttpServletRequest;@RestControllerpublic classLanguageController {@GetMapping("/greet")public Stringgreet(HttpServletRequest request) {Stringlanguage =request.getHeader("Accept-Language");//默认言if(language== null|| language.isEmpty()){language ="en";}//根据言返回不同的问候if (language.startsWith("zh")){return "你好";}else {return"Hello";}}}```示例2:使用@RequestHeader```java@RestControllerpublicclass LanguageController {@GetMapping("/greet")public Stringgreet(@RequestHeader(value ="Accept-Language", defaultValue= "en")String language) {if(language.startsWith("zh")) {return"你好";} else{return "Hello";}}}```在实际开发中,我们可能还需要解析Accept-Language头,因为它可能包含言选项和权重(例如:zh-CN,zh;q=0.9,en;q=0.8)。我们可以使用Spring框架提供的LocaleResolver(例如:AcceptHeaderLocaleResolver)来处理国际化。但是,如果只需要简单的获取,直接取第一个言即可(注意:Accept-Language的值可能有个,用逗号分隔,并且带有权重)。我们可以使用以下方法解析:```java//解析Accept-Language头,取第一个言String firstLanguage =language.split(",")[0];```总结:后台获取HTTP请求头中的字段,可以通过注入HttpServletRequest对象并调用getHeader方法,或者使用@RequestHeader注解。推荐使用注解方式,更加简洁。注意:如果前端传递的是自定义的言头(比如X-Language),那么需要确保前后端约定的字段名一致。最后,我们参考引用[1]中提到的请求方式,这是一个GET请求,但获取言头的方法同样适用于其他HTTP方法(POST、PUT等)。</think>在后端获取 HTTP 请求头中的言信息是处理多语言系统的关键步骤。以下是具体实现方法和最佳实践: ### 一、核心实现方法 #### 1. Java Servlet API (原生方式) ```java // 在控制器方法中获取请求头 public ResponseEntity<?> yourEndpoint(HttpServletRequest request) { // 获取Accept-Language头 String acceptLanguage = request.getHeader("Accept-Language"); // 获取自定义头(如X-Language) String customLanguage = request.getHeader("X-Language"); // 处理言逻辑... } ``` #### 2. Spring Boot 注解方式(推荐) ```java @GetMapping("/your-endpoint") public ResponseEntity<?> yourMethod( @RequestHeader(value = "Accept-Language", defaultValue = "en-US") String acceptLanguage, @RequestHeader(value = "X-Language", required = false) String customLanguage) { // 优先使用自定义头,没有则用标准头 String lang = customLanguage != null ? customLanguage : acceptLanguage; // 处理逻辑... } ``` #### 3. Spring MVC 拦截器(统一处理) ```java @Component public class LanguageInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 从请求头获取言 String language = request.getHeader("X-Language"); // 存储到请求作用域 request.setAttribute("userLanguage", parseLanguage(language)); return true; } private Locale parseLanguage(String langHeader) { if(langHeader == null || langHeader.isEmpty()) { return Locale.ENGLISH; // 默认言 } return Locale.forLanguageTag(langHeader); } } // 注册拦截器 @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LanguageInterceptor()); } } ``` ### 二、最佳实践建议 1. **优先级策略**: ```java // 获取言的优先级:自定义头 > 标准头 > 默认值 String lang = request.getHeader("X-Language"); if(lang == null) lang = request.getHeader("Accept-Language"); if(lang == null) lang = "en-US"; // 默认言 ``` 2. **言解析与标准化**: ```java // 使用Java Locale处理 Locale userLocale = Locale.forLanguageTag( lang.replace("_", "-") // 统一分隔符 ); // 获取基础言代码(如zh-CN -> zh) String baseLang = userLocale.getLanguage(); ``` 3. **会话存储**(参考引用[4]): ```java // 将言设置到session request.getSession().setAttribute("userLanguage", lang); // 后续请求中获取 String sessionLang = (String) request.getSession().getAttribute("userLanguage"); ``` ### 三、调试与验证方法 1. **Postman测试**(参考引用[2]): ```json GET /your-endpoint Headers: X-Language: zh-CN Accept-Language: fr-FR,en;q=0.9 ``` 2. **浏览器检查**(参考引用[3]): - Chrome开发者工具 → Network → 选择请求 → Headers 标签页 - 查看 `Request Headers` 中的 `Accept-Language` 和自定义头 3. **日志记录**: ```java @GetMapping("/endpoint") public void logHeaders(@RequestHeader Map<String, String> headers) { headers.forEach((key, value) -> logger.info("Header {} = {}", key, value)); } ``` ### 四、注意事项 1. **安全过滤**: ```java // 防止头部注入攻击 if(lang != null && !lang.matches("[a-zA-Z]{2}(-[a-zA-Z]{2})?")) { throw new InvalidHeaderException("Invalid language format"); } ``` 2. **多语言处理框架集成**: ```java // Spring的LocaleResolver @Bean public LocaleResolver localeResolver() { SessionLocaleResolver slr = new SessionLocaleResolver(); slr.setDefaultLocale(Locale.US); return slr; } @Bean public LocaleChangeInterceptor localeChangeInterceptor() { LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); lci.setParamName("lang"); // 同时支持header和参数 return lci; } ``` 3. **默认值策略**: - 在 `@RequestHeader` 注解中使用 `defaultValue` - 通过配置中心设置系统默认言 - 根据用户地理位置自动回退(需额外服务) > **关键点**:始终优先使用自定义头(如`X-Language`),因为`Accept-Language`是浏览器自动发送的,可能无法准确反映用户实际选择的言[^3]。 --- ### 常见问题解决方案 **问题:获取的头信息为null** ```java // 1. 检查请求是否包含该头部 // 2. 使用required=false防止报错 @RequestHeader(value = "X-Language", required = false) // 3. 在拦截器中添加默认值 if(request.getHeader("X-Language") == null) { request.setAttribute("lang", "en"); } ``` **问题:言代码格式不一致** ```java // 统一转换格式 String normalizeLang(String lang) { return lang.replace("_", "-") // zh_CN → zh-CN .split(",")[0] // 取第一个 .split(";")[0] // 去掉权重 .toLowerCase(); // EN → en } ``` [^1]: 前端请求示例 [^2]: Postman测试方法 [^3]: 浏览器调试技巧 [^4]: 会话存储机制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值