1、cf-gateway locale透传修复;2、LocaleResolver修改为全局web服务配置;

This commit is contained in:
gaoqr
2026-05-13 11:45:03 +08:00
parent db2e31680c
commit 8438563147
5 changed files with 45 additions and 34 deletions
@@ -4,6 +4,8 @@ import com.cf.imes.framework.common.exception.enums.ServiceErrorCodeRange;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Locale;
/**
* 业务逻辑异常 Exception
*/
@@ -22,6 +24,8 @@ public final class ServiceException extends RuntimeException {
*/
private String message;
private Locale locale;
/**
* 占位参数
*/
@@ -44,6 +48,19 @@ public final class ServiceException extends RuntimeException {
this.message = message;
}
public ServiceException(ErrorCode errorCode, Locale locale, Object... args) {
this.code = errorCode.getCode();
this.locale = locale;
this.message = errorCode.getMsg();
this.args = args;
}
public ServiceException(Integer code, Locale locale, String message) {
this.code = code;
this.locale = locale;
this.message = message;
}
public Integer getCode() {
return code;
}
@@ -24,11 +24,15 @@ import org.springframework.web.client.RestTemplate;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import jakarta.annotation.Resource;
import jakarta.servlet.Filter;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import java.util.Locale;
@AutoConfiguration
@EnableConfigurationProperties(WebProperties.class)
@@ -60,6 +64,13 @@ public class ChenfengWebAutoConfiguration implements WebMvcConfigurer {
&& antPathMatcher.match(api.getController(), clazz.getPackage().getName())); // 仅仅匹配 controller 包
}
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
return resolver;
}
@Bean
public I18nUtils i18nUtils(MessageSource messageSource) {
return new I18nUtils(messageSource);
@@ -17,7 +17,6 @@ import jakarta.annotation.Resource;
import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
@@ -83,14 +82,6 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
// 移除 login-user 的请求头,避免伪造模拟
SecurityFrameworkUtils.removeLoginUser(exchange);
String Language = exchange.getRequest()
.getHeaders()
.getFirst("Accept-Language");
if (StrUtil.isEmpty(Language)) {
Language = Locale.CHINA.getLanguage();
}
LocaleContextHolder.setLocale(Locale.forLanguageTag(Language));
// 情况一,如果没有 Token 令牌,则直接继续 filter
String token = SecurityFrameworkUtils.obtainAuthorization(exchange);
if (CharSequenceUtil.isEmpty(token)) {
@@ -114,8 +105,6 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
return chain.filter(exchange);
}
System.out.println("Accept-Language BEFORE = "
+ exchange.getRequest().getHeaders().getFirst("Accept-Language"));
// 情况二,如果有 Token 令牌,则解析对应 userId、userType、organId 等字段,并通过 通过 Header 转发给服务
// 重要说明:defaultIfEmpty 作用,保证 Mono.empty() 情况,可以继续执行 `flatMap 的 chain.filter(exchange)` 逻辑,避免返回给前端空的 Response!!
@@ -140,9 +129,14 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
// 用token从checktoken api中获取当前用户
Long organId = WebFrameworkUtils.getOrganId(exchange);
return checkAccessToken(organId, token).flatMap((Function<String, Mono<LoginUser>>) body -> {
System.out.println("Accept-Language CHECKTOKEN = "
+ exchange.getRequest().getHeaders().getFirst("Accept-Language"));
LoginUser remoteUser = buildUser(body);
String language = exchange.getRequest().getHeaders().getFirst("Accept-Language");
Locale locale;
if(StrUtil.isEmpty(language)) {
locale = Locale.CHINA;
} else {
locale = Locale.forLanguageTag(language);
}
LoginUser remoteUser = buildUser(body, locale);
if (remoteUser != null) {
return Mono.just(remoteUser);
}
@@ -162,7 +156,7 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
.retrieve().bodyToMono(String.class);
}
private LoginUser buildUser(String body) {
private LoginUser buildUser(String body, Locale locale) {
CommonResult commonResult = JsonUtils.parseObject(body, TOKEN_RESULT);
if(commonResult != null) {
@@ -171,15 +165,15 @@ public class TokenAuthenticationFilter implements GlobalFilter, Ordered {
Object[] args = commonResult.getArgs();
if(code != 0) {
if (TOKEN_TIME_IS_EXPIRES.getCode().equals(code)) {
throw new ServiceException(TOKEN_TIME_IS_EXPIRES);
throw new ServiceException(TOKEN_TIME_IS_EXPIRES, locale);
} else if (TOKEN_CONFIG_NOT_EXISTS.getCode().equals(code)) {
throw new ServiceException(TOKEN_CONFIG_NOT_EXISTS);
throw new ServiceException(TOKEN_CONFIG_NOT_EXISTS, locale);
} else if (ORGAN_NOT_EXISTS.getCode().equals(code)) {
throw new ServiceException(ORGAN_NOT_EXISTS);
throw new ServiceException(ORGAN_NOT_EXISTS, locale);
} else if (ORGAN_DISABLE.getCode().equals(code)) {
throw new ServiceException(new ErrorCode(code, msg), args);
throw new ServiceException(new ErrorCode(code, msg), locale, args);
} else if (ORGAN_EXPIRE.getCode().equals(code)) {
throw new ServiceException(new ErrorCode(code, msg), args);
throw new ServiceException(new ErrorCode(code, msg), locale, args);
}
}
}
@@ -7,7 +7,6 @@ import com.cf.imes.framework.common.util.i18n.core.util.ResourceBundleUtils;
import com.cf.imes.gateway.util.WebFrameworkUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.annotation.Order;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
@@ -70,17 +69,17 @@ public class GlobalExceptionHandler implements ErrorWebExceptionHandler {
*/
@ExceptionHandler(value = Exception.class)
public CommonResult defaultExceptionHandler(ServerWebExchange exchange,
Throwable ex) {
Throwable ex) {
ServerHttpRequest request = exchange.getRequest();
log.error("[defaultExceptionHandler][uri({}/{}) 发生异常]", request.getURI(), request.getMethod(), ex);
// TODO 晨丰:是否要插入异常日志呢?
// 返回 ERROR CommonResult
return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ERROR_PATH, INTERNAL_SERVER_ERROR.getMsg(), null, LocaleContextHolder.getLocale(), null));
return CommonResult.error(INTERNAL_SERVER_ERROR.getCode(), ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ERROR_PATH, INTERNAL_SERVER_ERROR.getMsg(), null, exchange.getLocaleContext().getLocale(), null));
}
@ExceptionHandler(value = ServiceException.class)
public CommonResult serviceExceptionHandler(ServiceException ex) {
String errMsg = ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ERROR_PATH, ex.getMessage(), null, LocaleContextHolder.getLocale(), null);
String errMsg = ResourceBundleUtils.getMessage(ResourceBundleConstants.MESSAGE_ERROR_PATH, ex.getMessage(), null, ex.getLocale(), null);
// 系统异常输出堆栈
if (INTERNAL_SERVER_ERROR.getCode().equals(ex.getCode())) {
log.info("[serviceExceptionHandler]", ex);
@@ -3,20 +3,10 @@ package com.cf.imes.module.system.framework.trans.config;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
import java.util.Locale;
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(TransProperties.class)
public class TransConfiguration {
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
return resolver;
}
@Bean
public TransApi transApi(TransProperties transProperties) {