如何在Quarkus中为当前请求设置Locale并覆盖默认获取逻辑?
Quarkus默认通过Accept-Language请求头设置Locale,要覆盖这一行为,可通过以下两种方式实现:
方法一:使用请求拦截器(ContainerRequestFilter)
实现ContainerRequestFilter拦截所有请求,按优先级从查询参数、Cookie获取Locale,无匹配时fallback到默认逻辑。
import jakarta.ws.rs.container.ContainerRequestContext; import jakarta.ws.rs.container.ContainerRequestFilter; import jakarta.ws.rs.core.Cookie; import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.ext.Provider; import java.util.Locale; @Provider public class CustomLocaleFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) { // 1. 优先读取查询参数,例如 ?lang=zh-CN String langParam = requestContext.getUriInfo().getQueryParameters().getFirst("lang"); if (langParam != null && !langParam.isBlank()) { Locale locale = Locale.forLanguageTag(langParam); requestContext.setProperty(HttpHeaders.LOCALE, locale); return; } // 2. 查询参数不存在时,读取Cookie(键为locale) Cookie localeCookie = requestContext.getCookies().get("locale"); if (localeCookie != null && !localeCookie.getValue().isBlank()) { Locale locale = Locale.forLanguageTag(localeCookie.getValue()); requestContext.setProperty(HttpHeaders.LOCALE, locale); return; } // 3. 无匹配时保留默认逻辑(从Accept-Language获取) // 若需强制默认Locale,可替换为:requestContext.setProperty(HttpHeaders.LOCALE, Locale.US); } }
说明
@Provider注解会让Quarkus自动注册该过滤器,无需额外配置。- 可根据需求调整优先级(如将Cookie放在查询参数前)或添加其他Locale来源。
方法二:CDI生产者生成请求级Locale
通过CDI生产者在每个请求作用域中生成Locale实例,供后续代码注入使用,同时覆盖默认逻辑。
import jakarta.enterprise.context.RequestScoped; import jakarta.enterprise.inject.Produces; import jakarta.ws.rs.core.Cookie; import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.UriInfo; import java.util.Locale; @RequestScoped public class LocaleProducer { @Produces @RequestScoped public Locale produceLocale(UriInfo uriInfo, HttpHeaders headers) { // 1. 从查询参数获取 String langParam = uriInfo.getQueryParameters().getFirst("lang"); if (langParam != null && !langParam.isBlank()) { return Locale.forLanguageTag(langParam); } // 2. 从Cookie获取 Cookie localeCookie = headers.getCookies().get("locale"); if (localeCookie != null && !localeCookie.getValue().isBlank()) { return Locale.forLanguageTag(localeCookie.getValue()); } // 3. fallback到Accept-Language的第一个Locale,或系统默认Locale return headers.getAcceptableLanguages().stream() .findFirst() .orElse(Locale.getDefault()); } }
说明
- 后续可在REST资源或CDI bean中直接注入
Locale使用:import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import java.util.Locale; @Path("/demo") public class DemoResource { @Inject Locale currentLocale; @GET public String getLocale() { return "Current locale: " + currentLocale.toString(); } }
内容的提问来源于stack exchange,提问作者Dario Scoppelletti
相关产品推荐
相关产品推荐

