P10 国际化及自定义MVC
i18n
i18n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称。在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件等)无需做大的改变就能够适应不同的语言和地区的需要。对程序来说,在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面。 在全球化的时代,国际化尤为重要,因为产品的潜在用户可能来自世界的各个角落。通常与i18n相关的还有L10n(“本地化”的简称)。
1.resources目录新建i8n文件夹,添加properties文件,格式如下
2.去Springboot配置文件配置spring.messages.basename为i18n目录下属性名前缀
3.自定义一个实现LocaleResolver的组件
4.在MVC配置器类中将其注入到Bean
5.前端页面(thymeleaf)使用#{ }添加信息;像这样
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
使用页面的中英文超链接进行实时切换
<a class="btn btn-sm" th:href="@{/index.html(lang='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(lang='en_US')}">English</a>
注:在标签外无法使用th:可使用[ [ ] ] (两层中括号)
<input type="checkbox" value="remember-me"> [[#{login.remember}]]
P11 登录拦截器
拦截器
1.实现HandlerInterceptor接口,覆盖preHandle()方法
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object loginUser = request.getSession().getAttribute("loginUser");
if(loginUser != null){
return true; //返回true放行!!!!!!
}else {
request.setAttribute("msg","权限不足!您还没有登录");
//记住这条请求转发语句
request.getRequestDispatcher("/index.html").forward(request, response);
return false; //返回false拦截!!!!!!
}
}
}
2.在MVC配置类覆盖addInterceptors()方法进行配置
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/")
.excludePathPatterns("/index.html")
.excludePathPatterns("/user/login")
.excludePathPatterns("/css/**")
.excludePathPatterns("/js/**")
.excludePathPatterns("/img/**");
}
展示员工列表
thymleaf片段
1.使用th:fragment 属性定义一个可复用的模板片段,引号内为这个片段的名字
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
2.使用片段表达式~{…}进行引入片段,注意中间有两个引号
<body>
... <div th:insert="~{footer :: copy}"></div> ...
</body>
footer为可复用的模板片段所在的html文件名,也可以不使用片段表达式,如下
<body>
... <div th:insert="footer :: copy"></div> ...
</body>
3.可以把所有的片段模板单独放在一个html文件中作为组件,方便统一管理
4.th : insert 与th : replace及th : include区别
- th:insert:保留自己的主标签,保留th:fragment的主标签。
- th:replace:不要自己的主标签,保留th:fragment的主标签。
- th:include:保留自己的主标签,不要th:fragment的主标签。(官方3.0后不推荐)
例如:
<!--1、比如抽取的公用代码片段如下-->
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
<!--2、采用如下三种方式进行引用-->
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>
<!--3、则三种引用方式的效果分别对应如下-->
<div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
<div>
© 2011 The Good Thymes Virtual Grocery
5.引入片段时进行传参,从而达到定制效果;如:
<div th:replace="~{commons/common::sideBar(active='list.html')}"></div>
在片段中加入判断
<a th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emp/getAllEmployees}">
6.foreach
<tbody >
<tr th:each="emp:${emps}">
<td th:text="${emp.getId()}"></td>
<td th:text="${emp.getName()}"></td>
<td th:text="${emp.getGender()==0?'女':'男'}"></td>
<td th:text="${emp.getDepartment().getDepartmentName()}"></td>
<td th:text="${#dates.format(emp.getBirthday(),'yyyy-MM-dd')}"></td>
<td th:text="${emp.getEmail()}"></td>
<td>
<button class="btn btn-sm btn-primary">编辑</button>
<button class="btn btn-sm btn-danger">删除</button>
</td>
</tr>
</tbody>
注:实体类中的Date类型传入时默认接收格式为使用斜杠分割,如:1998/6/18;如需更改需要在主配置文件中
class=“btn btn-sm btn-primary”>编辑
删除
注:实体类中的Date类型传入时默认接收格式为使用斜杠分割,如:1998/6/18;如需更改需要在主配置文件中