mirror of https://github.com/halo-dev/halo
Simplify ThemeLocaleContextResolver (#6651)
#### What type of PR is this? /kind improvement /area theme /milestone 2.20.x #### What this PR does / why we need it: This PR simplifies ThemeLocaleContextResolver by removing unused attributes. In another PR <https://github.com/halo-dev/halo/pull/6647>, fixed locale resolution for query parameter `language`. This PR fixes locale resolution for cookie `language` as well. Please see the results below: ```bash http https://www.halo.run/ Cookie:language=zh-CN -p h HTTP/1.1 200 OK Content-Language: und ``` ```bash http http://localhost:8090 Cookie:language=zh-CN -p h HTTP/1.1 200 OK Content-Language: zh-CN ``` #### Does this PR introduce a user-facing change? ```release-note None ```pull/6656/head^2
parent
25eec1ec4f
commit
8ab8a440b6
|
@ -1,15 +1,15 @@
|
|||
package run.halo.app.theme;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.TimeZone;
|
||||
import java.util.function.Function;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.i18n.LocaleContext;
|
||||
import org.springframework.context.i18n.SimpleTimeZoneAwareLocaleContext;
|
||||
import org.springframework.http.HttpCookie;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
|
||||
|
@ -22,71 +22,45 @@ import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver;
|
|||
@Slf4j
|
||||
@Component(WebHttpHandlerBuilder.LOCALE_CONTEXT_RESOLVER_BEAN_NAME)
|
||||
public class ThemeLocaleContextResolver extends AcceptHeaderLocaleContextResolver {
|
||||
public static final String TIME_ZONE_REQUEST_ATTRIBUTE_NAME =
|
||||
ThemeLocaleContextResolver.class.getName() + ".TIME_ZONE";
|
||||
public static final String LOCALE_REQUEST_ATTRIBUTE_NAME =
|
||||
ThemeLocaleContextResolver.class.getName() + ".LOCALE";
|
||||
|
||||
public static final String DEFAULT_PARAMETER_NAME = "language";
|
||||
public static final String LANGUAGE_PARAMETER_NAME = "language";
|
||||
|
||||
public static final String LANGUAGE_COOKIE_NAME = LANGUAGE_PARAMETER_NAME;
|
||||
|
||||
public static final String TIME_ZONE_COOKIE_NAME = "time_zone";
|
||||
|
||||
private final Function<ServerWebExchange, TimeZone> defaultTimeZoneFunction =
|
||||
exchange -> getDefaultTimeZone();
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public LocaleContext resolveLocaleContext(@NonNull ServerWebExchange exchange) {
|
||||
parseLocaleCookieIfNecessary(exchange);
|
||||
var request = exchange.getRequest();
|
||||
var locale = getLocaleFromQueryParameter(request)
|
||||
.or(() -> getLocaleFromCookie(request))
|
||||
.orElseGet(() -> super.resolveLocaleContext(exchange).getLocale());
|
||||
|
||||
Locale locale = getLocale(exchange);
|
||||
var timeZone = getTimeZoneFromCookie(request)
|
||||
.orElseGet(TimeZone::getDefault);
|
||||
|
||||
return new SimpleTimeZoneAwareLocaleContext(locale,
|
||||
exchange.getAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME));
|
||||
return new SimpleTimeZoneAwareLocaleContext(locale, timeZone);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Locale getLocale(ServerWebExchange exchange) {
|
||||
String language = exchange.getRequest().getQueryParams()
|
||||
.getFirst(DEFAULT_PARAMETER_NAME);
|
||||
|
||||
Locale locale;
|
||||
if (StringUtils.isNotBlank(language)) {
|
||||
locale = Locale.forLanguageTag(language);
|
||||
} else if (exchange.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) != null) {
|
||||
locale = exchange.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME);
|
||||
} else {
|
||||
locale = super.resolveLocaleContext(exchange).getLocale();
|
||||
}
|
||||
return locale;
|
||||
private Optional<Locale> getLocaleFromCookie(ServerHttpRequest request) {
|
||||
return Optional.ofNullable(request.getCookies().getFirst(LANGUAGE_COOKIE_NAME))
|
||||
.map(HttpCookie::getValue)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.map(Locale::forLanguageTag);
|
||||
}
|
||||
|
||||
private TimeZone getDefaultTimeZone() {
|
||||
return TimeZone.getDefault();
|
||||
private Optional<Locale> getLocaleFromQueryParameter(ServerHttpRequest request) {
|
||||
return Optional.ofNullable(request.getQueryParams().getFirst(LANGUAGE_PARAMETER_NAME))
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.map(Locale::forLanguageTag);
|
||||
}
|
||||
|
||||
private void parseLocaleCookieIfNecessary(ServerWebExchange exchange) {
|
||||
if (exchange.getAttribute(TIME_ZONE_REQUEST_ATTRIBUTE_NAME) == null) {
|
||||
TimeZone timeZone = null;
|
||||
HttpCookie cookie = exchange.getRequest()
|
||||
.getCookies()
|
||||
.getFirst(TIME_ZONE_COOKIE_NAME);
|
||||
if (cookie != null) {
|
||||
String value = cookie.getValue();
|
||||
timeZone = TimeZone.getTimeZone(value);
|
||||
}
|
||||
exchange.getAttributes().put(TIME_ZONE_REQUEST_ATTRIBUTE_NAME,
|
||||
(timeZone != null ? timeZone : this.defaultTimeZoneFunction.apply(exchange)));
|
||||
}
|
||||
|
||||
if (exchange.getAttribute(LOCALE_REQUEST_ATTRIBUTE_NAME) == null) {
|
||||
HttpCookie cookie = exchange.getRequest()
|
||||
.getCookies()
|
||||
.getFirst(DEFAULT_PARAMETER_NAME);
|
||||
if (cookie != null) {
|
||||
String value = cookie.getValue();
|
||||
exchange.getAttributes()
|
||||
.put(LOCALE_REQUEST_ATTRIBUTE_NAME, new Locale(value));
|
||||
}
|
||||
}
|
||||
private Optional<TimeZone> getTimeZoneFromCookie(ServerHttpRequest request) {
|
||||
return Optional.ofNullable(request.getCookies().getFirst(TIME_ZONE_COOKIE_NAME))
|
||||
.map(HttpCookie::getValue)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.map(TimeZone::getTimeZone);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import static java.util.Locale.KOREA;
|
|||
import static java.util.Locale.UK;
|
||||
import static java.util.Locale.US;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static run.halo.app.theme.ThemeLocaleContextResolver.DEFAULT_PARAMETER_NAME;
|
||||
import static run.halo.app.theme.ThemeLocaleContextResolver.LANGUAGE_COOKIE_NAME;
|
||||
import static run.halo.app.theme.ThemeLocaleContextResolver.TIME_ZONE_COOKIE_NAME;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -187,7 +187,7 @@ class ThemeLocaleContextResolverTest {
|
|||
return MockServerWebExchange.from(
|
||||
MockServerHttpRequest.get("").acceptLanguageAsLocales(locales)
|
||||
.cookie(new HttpCookie(TIME_ZONE_COOKIE_NAME, "America/Adak"))
|
||||
.cookie(new HttpCookie(DEFAULT_PARAMETER_NAME, "en")));
|
||||
.cookie(new HttpCookie(LANGUAGE_COOKIE_NAME, "en")));
|
||||
}
|
||||
|
||||
private ServerWebExchange exchangeForParam(String language) {
|
||||
|
|
Loading…
Reference in New Issue