一緒に書く習慣をつけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して10日目です。クリックしてイベントの詳細をご覧ください。
1. SpringMVCは、注釈に基づく国際化を使用します
日常業務において、異なる言語圏の人々が当社のウェブサイトを閲覧する必要がある場合、国際化の基本的な操作を使用する必要があります。springmvcの国際化操作は比較的簡単です。
まず、国際化のための簡単なページを作成しましょう
1-1.ログインページを作成する
まず、springmvcフレームワークを構築する必要があります。構築について質問がある場合は、前の記事を読むことができます。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<% request.setAttribute("basePath",request.getContextPath());%>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
<meta name="generator" content="Hugo 0.88.1">
<title>国际化--i18n</title>
<link rel="canonical" href="https://getbootstrap.com/docs/5.1/examples/sign-in/">
<!-- Bootstrap core CSS -->
<link href="${basePath}/assets/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
<!-- Custom styles for this template -->
<link href="${basePath}/assets/dist/css/signin.css" rel="stylesheet">
</head>
<body class="text-center">
<main class="form-signin">
<form>
<img class="mb-4" src="${basePath}/assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
<div class="form-floating">
<input type="email" class="form-control" id="floatingInput" placeholder="[email protected]">
<label for="floatingInput">Email address</label>
</div>
<div class="form-floating">
<input type="password" class="form-control" id="floatingPassword" placeholder="Password">
<label for="floatingPassword">Password</label>
</div>
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017–2021</p>
</form>
</main>
</body>
</html>
复制代码
次のようにページにアクセスします。
1-2.国際化を実現する方法
考えてみてください。どうすれば国際化を実現できますか?一般に、国際化は2つ以上の言語と互換性がある必要があります。この場合、国際化を実現するには2つの方法があります。
1. Nセットのビューページを作成し、さまざまな言語に対応するページを作成します
2.ページを作成し、ブラウザの言語に応じてさまざまな言語パックファイルをロードします
最初のソリューションは、異なる言語のページにカスタマイズの要件が異なる場合を除いて、通常は使用されません。したがって、一般的に使用される国際化では、2番目のスキームが使用されます。
1-3。国際化は、ブラウザで言語を設定することによって実現されます
1-3-1.言語パックを作成する
1.言語パックを作成するには、en_US.properties / zn_CH.propertiesのように、同じファイル内のすべてのビューページにテキストを配置できるため、2つの言語パックがあります。2. login / login_en_US.properties; login / login_zn_CH.properties
など、ビューごとに異なる言語パッケージを作成します。
この2つのスキームは、プロジェクトの実際の状況に応じて選択できます。この記事では、2番目のスキームを採用して説明します。
国際化された言語パックの操作を容易にするために、IDEA用のプラグイン「ResourceBundlerEditor」をインストールする必要があります
最終的に作成される言語パックは次のとおりです。
创建了中文和英文语言包。为了后期维护及方便,我们文件的命名需要按照i18N方式来命名,具体可以搜一下i18n对照表。
1-3-2、创建对应语言
点击+好,新增一个txt文字key,这个key可以随便写,但是为了语义化建议还是写英文含义。
之后就挨个语言包创建对应的文字信息
1-3-3、在spring-mvc文件中进行配置
<!--设置国际化支持,配置国际化属性资源文件-->
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
<property name="basenames">
<array>
<value>i18N.login</value>
</array>
</property>
</bean>
复制代码
如果有很多资源文件,可以在array中再添加即可。
1-3-4、视图层实现国际化
在springMVC中,视图层实现国际化,可以通过两种方案,一种是JSTL标签,另外一种是spring标签库
1-3-4-1、jslt标签实现国际化
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>....<body>
<!-- <fmt:setLocale value="${param.setLocale}"/> 区域语言的值从传过来的参数中得到 -->
<fmt:setLocale value="en_US"/> <!--指定区域语言-->
<fmt:bundle basename="login"> <!-- 指定使用basename为login的资源文件,也即资源文件第一个单词为login-->
<center>
<table>
<tr>
<td><fmt:message key="email"/></td>
<td><input type="text" name="email"></td>
</tr>
</table>
</center>
</fmt:bundle>
</body>
复制代码
1-3-4-2、使用spring标签库
1、需要先导入spring的标签库
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
复制代码
2、使用spring:message 标签替换文字,如下替换原文密码
<spring:message code="txt_password">
复制代码
3、最终替换完之后,我们的login.jsp页面为:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<% request.setAttribute("basePath",request.getContextPath());%>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
<meta name="generator" content="Hugo 0.88.1">
<title>国际化--i18n</title>
<link rel="canonical" href="https://getbootstrap.com/docs/5.1/examples/sign-in/">
<!-- Bootstrap core CSS -->
<link href="${basePath}/assets/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
<!-- Custom styles for this template -->
<link href="${basePath}/assets/dist/css/signin.css" rel="stylesheet">
</head>
<body class="text-center">
<main class="form-signin">
<form>
<img class="mb-4" src="${basePath}/assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">
<h1 class="h3 mb-3 fw-normal"><spring:message code="txt_plase_login"/></h1>
<div class="form-floating">
<input type="email" class="form-control" id="floatingInput" placeholder="[email protected]">
<label for="floatingInput"><spring:message code="txt_email"></label>
</div>
<div class="form-floating">
<input type="password" class="form-control" id="floatingPassword" placeholder="Password">
<label for="floatingPassword"><spring:message code="txt_password"></label>
</div>
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> <spring:message code="txt_remember_me">
</label>
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit"><spring:message code="txt_login"></button>
<p class="mt-5 mb-3 text-muted">© 2017–2021</p>
</form>
</main>
</body>
</html>
复制代码
1-3-4-3、测试
最终访问控制器发现这个错误、看错误是没找到key,最后发现使用idea在添加资源文件之后,并没有实时编译,删除历史编译文件,重新编译再次访问
这次出现了中文乱码的问题,接着处理,如下
重启服务再次访问
设置浏览器语言为英文、再次访问如下:
1-3-5、实现原理
其实SpringMVC中国际化的处理非常简单,就是按照浏览器所带来的语言信息决定的。默认情况下,SpringMVC 根据Accept-Language参数判断客户端的本地化类型。
当接受到请求时,SpringMVC 会在上下文中查找-一个本地化解析器(LocalResolver) ,找到后使用它获取请求所对应的本地化类型信息:Locale locale =request.getLocale();//获取浏览器的区域信息
1-4、通过自定义解析器,设置国际化
上面案例主要通过修改浏览器的语言,然后在请求的时候,通过request请求头中携带语言设置,让springmvc通过使用AcceptHandlerLocaleResolver来进行解析。
我们自己实现实际也是通过覆盖AcceptHandlerLocaleResolver来实现,然后在请求中携带语言标记
1-4-1、将SessionLocaleResolver注入到spring
这么做的目的是,页面在切换的时候,我们就语言保存到SessionLocaleResolver中,这样后面的页面再次访问就可以按照设置的语言显示了
<!--使用SessionLocaleResolver保持Local状态,会存session中获取Local对象-->
<bean class="org.springframework.web.servlet.i18n.SessionLocaleResolver" id="localeResolver"></bean>
复制代码
1-4-2、编写控制器保存语言设置
/**
* 保持语言设置
* @param local 页面传过来的语言
* @param localeResolver 将SessionLocaleResolver 注入到方法中
* @param request
* @param response
* @return
*/
@RequestMapping("/i18n/{local}")
public String changeLocal(@PathVariable String local, @Autowired SessionLocaleResolver localeResolver,
HttpServletRequest request, HttpServletResponse response){
Locale locale=new Locale(local.split("_")[0],local.split("_")[1]);
localeResolver.setLocale(request,response,locale);
return "login";
}
复制代码
1-4-3、修改login页面添加中英文切换
<div class="row">
<a class="col-6" href="${basePath}/i18n/zh_CN">中文</a>
<a class="col-6" href="${basePath}/i18n/en_US">Englis h</a>
</div>
复制代码
这样就可以完成语言切换了
1-5、使用springmvc拦截器设置国际化
1-5-1、在spring-mvc中添加拦截器
<!--使用springmvc提供的拦截器,接收locale参数,设置到session中-->
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"></bean>
</mvc:interceptors>
复制代码
查看LocaleChangeinterceptor源码中的preHandle方法如下:
可以发现第一步通过locale获得页面传的参数,然后将此参数设置到LocaleResolver中,实际处理方式和上面,自己实现的方式基本一致。
1-5-2、login.jsp修改国际化支持
<div class="row">
使用拦截器设置locale<p></p>
<a class="col-6" href="?locale=zh_CN">中文</a>
<a class="col-6" href="?locale=en_US">English</a>
</div>
复制代码
二、小结
2-1、基于浏览器设置的语言切换国际化
1.新建jsp对应的国际化属性资源文件:
login.properties
login_en_US.properties
login_zh_CN.properties
2.配置springmvc, 将国际化资源文件注入到springmvc中
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
<property name="basenames">
<array>
<value>i18n/login</value>
</array>
</property>
</bean>
复制代码
3. 在页面来调用属性资源文件
< spring:message> </spring:message>
2-2、使用超链接的方式切换语言
1.更改默认本地化语言解析器LocaleResolver 改成SessionLocaleResolver
方式1: 创建一个请求方法,接收local参数(en_US、zh_CN) 设置session中去
方式2: 使用springmvc提供的拦截器,接收local参数(en_US、zh_CN) 设置session中去
复制代码
三、java中错误信息国际化处理。
3-1、spring form标签使用JSR303返回错误信息
3-1-1、修改跳转login页面的控制器方法
使用spring formb标签显示错误信息,必须从控制器进行跳转,因为需要加一个Model,图中加了User,会自动添加到Model中,主要为了给jsp页面form标签中的modelAttribute赋值。这个是必须步骤
3-1-2、修改登录页面
1、添加spring form标签
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
复制代码
2、将form标签改为spring form标签 下面代码中的modelAttribute="user",即为上面跳转页面控制器中的变量名
<form:form action="${basePath}/login" method="post" modelAttribute="user">
复制代码
3、添加错误信息显示标签 错误信息同样使用spring form标签,path的值,需要和user bean中的属性保持一致。
<form:errors path="email"></form:errors>
复制代码
<form:errors path="password"></form:errors>
复制代码
3-2-3、使用maven添加validator包
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>
</dependency>
复制代码
3-2-4、添加User Bean,并设置JSR303注解
分别给email和password设置了相关验证注解
3-2-5、添加登录提交方法
使用JSR303,在方法参数中一定要添加BindingResult
3-2-6、测试
这样虽然错误信息显示出来了,但是如果页面切换到英文,错误信息依然是中文,这样就有问题了。因此我们还需要给后台相关信息做国际化操作。
3-2、国际化代码中的的内容
3-2-1、使用MessageSource设置国际化
3-2-1-1、在控制器中注入MessageSource
使用MessageSource获得属性key的值,因为已经通过过滤器/SessionLocaleResolver设置了国际化的语言,因此这边通过MessageSource.getMessage(),传入对应的错误信息key 以及Locale就可以自动获取资源文件中配置的信息了。 可以看到在getMessage方法中第二个参数,目前传null,这个地方是一个object[] 可以传递相关参数,如我们修改资源文件login_err:
次に、コントローラーを次のように変更します。
テストは次のとおりです。
3-2-2-2.テスト
あなたは以下を見ることができます、電子メールまたはパスワードエラーは英語で表示されました
以下は中国語です
3-3.国際化されたJSR303アノテーションエラーメッセージ
3-3-1、methodInvocation:処理メソッドを呼び出すときのSpringMVCエラー
リソースファイルを構成するときのJSR303エラーメッセージの形式は次のとおりです
。キーのプレフィックスはannotation.object.attributeです。例:
NotEmpty.user.email=メールを空にすることはできません
3-3-1-1、ユーザーの検証注釈情報を処理します
認証情報はユーザーから削除できます
3-3-1-2.テスト検証
3-3-2、typeMismatch:データ型の不一致がデータバインディング中に発生します
これは、誕生日などのデータ型検証の形式です
キープレフィックス:typeMismatch.object.propertytypeMismatch.user.birthday
=誕生日の日付形式エラー
3-3-2-1、属性エラー情報を追加
3-3-2-2、jspページを変更します
3-3-2-3.テスト検証
この時点で、国際化プロセスは完了です。