2021年1月18日 星期一

[SpringBoot 1.5] 國際化

1 在resources下面建一個資料夾i18n並產生properties檔案







2 在檔案左下方切換到ResourceBundle視圖模式, 並點左上方加號來新增屬性

並在屬性的右邊將屬性在各國語言下的值輸入進去













3 使用thymeleaf語法如下

th:text="#{login.tip}

完整的程式碼如下

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Signin Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<!--链接(URL@{…} /crud/asserts/css/bootstrap.min.css-->
<link th:href="@{/asserts/css/bootstrap.min.css}" href="asserts/css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link th:href="@{/asserts/css/signin.css}" href="asserts/css/signin.css" rel="stylesheet">
</head>
<body class="text-center">
<form class="form-signin" action="dashboard.html" th:action="@{/user/login}" method="post">
<img class="mb-4" src="asserts/img/bootstrap-solid.svg" alt="" width="72" height="72">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>

<label class="sr-only" th:text="#{login.username}">Username</label>
<input type="text" name="username" class="form-control" placeholder="Username" th:placeholder="#{login.username}" required="" autofocus="">
<label class="sr-only" th:text="#{login.password}">Password</label>
<input type="password" name="password" class="form-control" placeholder="Password" th:placeholder="#{login.password}" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> [[#{login.remember}]] <!--行内表达式-->
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
<a class="btn btn-sm" th:href="@{/index.html(l='zh_tw')}">[[#{login.chinese}]]</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">[[#{login.englist}]]</a>
</form>
</body>
</html>

這樣~瀏覽器就會依據你選擇最優先的語言來做顯示

----------------------------------------------

原碼分析

在我們的SpringBoot自動配置類別 WebMvcAutoConfiguration

我們可以找到以下程式碼

@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
if (this.mvcProperties
.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
}
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}

這段的意思是, 如果我們有找到固定的LocalResolver配置, 我們就使用固定的

不然我們就會使用new AcceptHeaderLocaleResolver()

其中有一個方法

@Override
public Locale resolveLocale(HttpServletRequest request) {
Locale defaultLocale = getDefaultLocale();
if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
return defaultLocale;
}
Locale requestLocale = request.getLocale();
if (isSupportedLocale(requestLocale)) {
return requestLocale;
}
Locale supportedLocale = findSupportedLocale(request);
if (supportedLocale != null) {
return supportedLocale;
}
return (defaultLocale != null ? defaultLocale : requestLocale);
}

他會從request中或取得locale訊息









----------------------------------------------------

客製化locale

現在要做一個能夠依照選擇來定語言的方式可以這樣做

造一個component.MylLocaleResolver去繼承LocaleResolver類別

繼承方法, 並如下寫

這個想法是, 他要接request的傳參數, 根據參數來做判斷

如果參數有值, 就拿參數值拆去產生locale物件來使用


public class MyLocaleResolver implements LocaleResolver{
@Override
public Locale resolveLocale(HttpServletRequest request) {
String l=request.getParameter("l");
Locale locale=Locale.getDefault();
if(!StringUtils.isEmpty(l)){
String[] split =l.split("_");
locale=new Locale(split[0],split[1]);
}
return locale;
}

@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

}
}


而畫面上的配合要寫成這樣 th:href="@{/index.html(l='zh_tw')}"

如下

<a class="btn btn-sm" th:href="@{/index.html(l='zh_tw')}">[[#{login.chinese}]]</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">[[#{login.englist}]]</a>


然後~有一點還要做的就是, 要在自定義的config檔案中載入Bean讓他可以使用


//使用WebMvcConfigurerAdapter 可以來擴展SpringMVC的功能
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
//control+O 可以找到父類所有可用方法

@Override
public void addViewControllers(ViewControllerRegistry registry) {
//super.addViewControllers(registry);
//瀏覽器發送/atguigu請求來到success
registry.addViewController("/atguigu").setViewName("success");
}

@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
WebMvcConfigurerAdapter adapter= new WebMvcConfigurerAdapter(){
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
}
};
return adapter;
}

@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}

}

第二個Bean的是做導頁, 也就是如果是"/"他會導到login, /index.html他也會導到login



沒有留言:

張貼留言

[leetcode] [KMP] KMP

ABCDABD... ABCDABF... 簡單的說, 傳統解兩字串匹配部分 可能會來個雙迴圈, 哀個比對, 當不匹配的時候, 會將下方列再後移1位 然後不匹配再後移 然而 如果像上放已經有4個屬於匹配的字串, 她就應該直接往後移四位來匹配, 而不是只移動1位 隱藏的思維是, 當...