@[toc]
一、概述
该项目只有thymeleaf+SpringBoot,该项目就是为了练习词条国际化进行【中文/英文】之间切换,使用起来非常简单,只需点击【中文/English】的a标签就可实现词条中英文切换。
二、页面效果展示
默认和点击“中文”效果
点击“English”效果
三、注意事项
注意点1:默认进入就是中文,因为lang值没穿,后台解析调用login.properties配置文件词条,而点击【中文/English】标签就会向后端传lang=zh_CN的值,后端去判断中英文词条显示
注意点2:thymeleaf前端框架,标签中使用#{}来获取此条配置文件的内容,
比如:<label th:text="#{login.username}"></label>
注意点3:前端页面internationalization.html中注意中英文转换的a标签,注意这里,一定要写/internationalization(lang='zh_CN'),不要写成/internationalization.html(lang='zh_CN'),区别就在加了“.html” 后缀后跳转就会失败。另外下面这种写法就相当于get请求的url后面拼接参数,具体可看图片url
th:href="@{
/internationalization(lang='zh_CN')}
th:href="@{
/internationalization(lang='en_US')}
注意点4:有的人博客写的是加后缀“.html”,好像也实现了跳转中英文切换,但是我不知道为啥,可能Controller代码和配置文件写法不一致吧,这个需要你去自己琢磨,至少我这种写法是可行的
th:href="@{
/internationalization.html(lang='zh_CN')}
th:href="@{
/internationalization.html(lang='en_US')}
注意点5:IDEA设置编码要统一,不然会出现乱码
四、准备工作
第1步:引入pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.6.7</version>
</dependency>
第2步:创建thymeleaf页面
<!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>登录首页</title>
</head>
<body class="text-center">
<form class="form-signin" action="dashboard.html">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
<label th:text="#{login.username}"></label>
<input type="text" class="form-control" th:placeholder="#{login.username}" required="" autofocus=""><br>
<label th:text="#{login.password}"></label>
<input type="password" class="form-control" th:placeholder="#{login.password}" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me" th:text="#{login.remember}">
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.btn}">Sign in</button>
<a class="btn btn-sm" th:href="@{/internationalization(lang='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/internationalization(lang='en_US')}">English</a>
</form>
</body>
</html>
第3步:创建2个配置类
MyLocaleResolver,用于解析页面传过来的lang语言类型
package com.example.demo.config;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
//获取请求中的语言参数
String language = httpServletRequest.getParameter("lang");
System.out.println("DeBug===>"+language);
Locale locale= Locale.getDefault(); //如果没有就使用默认的(根据主机的语言环境生成一个 Locale )。
//如果请求的链接中携带了 国际化的参数
if (!StringUtils.isEmpty(language)){
//zh_CN
String[] s = language.split("_");
//国家,地区
locale=new Locale(s[0],s[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
MyMvcConfig,注入Bean
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
@Configuration
public class MyMvcConfig {
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
第4步:创建Controller
package com.example.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class Controller {
//首页
@GetMapping(value = "/internationalization")
public String internationalization2() {
return "internationalization";
}
}
第5步:创建词条
login.properties
login.btn=登录
login.password=密码
login.remember=记住我
login.tip=请登录
login.username=用户名
login_en_US.properties
login.btn=Sign in
login.password=Password
login.remember=Remember me
login.tip=Please sign in
login.username=Username
login_zh_CN.properties
login.btn=登录
login.password=密码
login.remember=记住我
login.tip=请登录
login.username=用户名
第6步:设置配置文件.properties
server.port=8888
# 缓存
spring.thymeleaf.cache=false
#设置thymeleaf模板引擎的前后缀(可写可不写) 一般都是默认的
spring.thymeleaf.prefix=classpath:/templates/
spring.mvc.view.suffix=.html
spring.messages.basename=i18n.login
五、容易碰到的问题
问题1:返回页面名称的字符串,而不是返回跳转页面内容
原因
:@Controller和RestController和ModelAndView用混了。
解决方案
:
Error resolving template [excel/readExcel], template might not exist or might not be accessible by
问题2:请求页面跳转了,但是页面报错如图
分析原因
:出现这个异常说明了跳转页面的url无对应的值
可能导致的原因1
:Application启动类的位置不对.要将Application类放在最外侧,即包含所有子包 。而我的controller则放在了最外层的包里面。导致找不到页面。
解决方案1
:移动Application启动类的位置到最外层就可以了
解决方案2
:添加@SpringBootApplication(scanBasePackages="controller")
在你的启动的Demo01Application类中,添加注释,指定你的controller的位置,就可以指定加载,成功解决问题。
package com.hh.demo01;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages="controller")
public class Demo01Application {
public static void main(String[] args) {
SpringApplication.run(Demo01Application.class, args);
}
}
可能导致的原因2
:控制器的URL路径书写问题 @RequestMapping(“xxxxxxxxxxxxxx”) 实际访问的路径与”xxx”不符合。
可能导致的原因3
:如果pom文件下配置了spring-boot-starter-paren时,当spring-boot-starter-paren版本高/版本低时,配置文件配置格式有问题
解决方案
:
prefix和suffix 用来配置前缀和后缀,举例如图代码
当pom文件下的spring-boot-starter-parent版本高时配置:
spring.mvc.view.prefix/spring.mvc.view.suffix
当pom文件下的spring-boot-starter-parent版本低时配置:
spring.view.prefix/spring.view.suffix
问题3:Circular view path [hello]: would dispatch back to the current handler URL [/springmvc_01/hello] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
HTTP Status 500 – Internal Server Error
Type Exception Report
Message Circular view path [hello]: would dispatch back to the current handler URL [/springmvc_01/hello] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
javax.servlet.ServletException: Circular view path [hello]: would dispatch back to the current handler URL [/springmvc_01/hello] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
org.springframework.web.servlet.view.InternalResourceView.prepareForRendering(InternalResourceView.java:205)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:145)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1286)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1041)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:984)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Note The full stack trace of the root cause is available in the server logs.
Apache Tomcat/7.0.93
错误解释
:该报错是指url对应的页面未找到,或者自己循环调用导致报错
可能导致的原因1
:导入的ModelAndView导包导错了解决方案
:有问题导入包import org.springframework.web.portlet.ModelAndView;,正确导入本应该是import org.springframework.web.servlet.ModelAndView;
可能导致的原因2
:你的view name和你的path是相同的字符串解决方案
:问题在于如果你的view name和你的path是相同的字符串,根据Spring的转发规则,就等于让自己转发给自己,会陷入死循环。所以Spring会检查到这种情况,于是抛出Circular view path异常。把调用路径和视图页面的名称换成不重名的就可以。