1.将首页添加到templates下,以启用thymeleaf模板
2.编写配置类实现WebMvcConfigurer接口,重写addViewControllers方法来添加自定义视图解析器,使“/”请求可以直接映射到首页(定义内部类时要添加@Bean注解)
@Configuration
//WebMvcConfigurer接口中有很多方法的对应的是以往Springmvc配置文件中的属性
//使用其来扩展SpringMVC的功能
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器发送/jiat请求来到 success
registry.addViewController("/jiat").setViewName("success");
}
//所有的WebMvcConfigurer组件都会一起起作用
@Bean
public WebMvcConfigurer webMvcConfigurer(){
WebMvcConfigurer webMvcConfigurer = new WebMvcConfigurer() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/login.html").setViewName("login");
}
};
return webMvcConfigurer;
}
现在的步骤:
编写国际化配置文件,抽取页面需要显示的国际化消息
三个文件:
login.properties 默认
login_en_US.properties 英文
login_zh_CN.properties 中文
login.btn=登录
login.password=密码
login.remrember=记住
login.tip=登录
login.username=用户名
SpringBoot自动配置好了管理国际化资源文件的组件
public class MessageSourceAutoConfiguration {
private static final Resource[] NO_RESOURCES = new Resource[0];
public MessageSourceAutoConfiguration() {
}
@Bean
@ConfigurationProperties(
prefix = "spring.messages"
)
public MessageSourceProperties messageSourceProperties() {
return new MessageSourceProperties();
}
@Bean
public MessageSource messageSource(MessageSourceProperties properties) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
//setBasenames 设置国际化资源文件的基础名(去掉语言国家代码的)
if (StringUtils.hasText(properties.getBasename())) {
messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));
}
public class MessageSourceProperties {
private String basename = "messages"; //说明不做任何配置时,配置文件可以直接放在类路径下叫messages.properties,也可以识别
private Charset encoding;
配置时只需要去到spring.messages.basename=“” 直接赋值基本名则在root路径下,如果有包路径则通过路径查找
spring.messages.basename=i18n.login
去页面获取国际化的值
th:text="#{login.tip}
效果:根据浏览器语言设置的信息切换了国际化信息
原理:
? 国际化Locale(区域信息对象);LocaleResolver(获取区域信息对象)
//springboot配置了一个解析区域信息的解析器
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(
prefix = "spring.mvc",
name = {"locale"}
)
public LocaleResolver localeResolver() {
if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
} else {
//没有指定使用定义的解析器,则使用AcceptHeaderLocaleResolver
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
}
//默认使用AcceptHeaderLocaleResolver,从请求头中获取区域信息(request.getLocale())
public class AcceptHeaderLocaleResolver implements LocaleResolver {
public Locale resolveLocale(HttpServletRequest request) {
Locale defaultLocale = this.getDefaultLocale();
if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
return defaultLocale;
} else {
Locale requestLocale = request.getLocale();
List<Locale> supportedLocales = this.getSupportedLocales();
if (!supportedLocales.isEmpty() && !supportedLocales.contains(requestLocale)) {
Locale supportedLocale = this.findSupportedLocale(request, supportedLocales);
点击链接切换国际化
链接携带上区域信息:zh_CN或者en_US
/**
* 能连接上携带区域信息的解析器
**/
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
String l = httpServletRequest.getParameter("l");
Locale locale=Locale.getDefault(); //注意要为locale设置默认,否则会报空指针,设置为request.getLocale()可以实现跟随浏览器语言改动
if (!StringUtils.isEmpty(l)){
String[] split = l.split("_");
locale = new Locale(split[0],split[1]);
}
return locale;
}
//WebMvcConfigurer配置类中
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
开发期间模板引擎页面修改以后, 要实时生效
#禁用缓存
spring.thymeleaf.cache=false
页面修改完成后ctrl+f9;重新编译
错误消息的显示:
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
登陆成功后重定向页面,因为页面需要通过模板引擎渲染,要添加到试图解析器的映射中
// springboot 有Rest风格的mapping注解代替原先的RequestMapping
// @DeleteMapping
// @PutMapping
// @GetMapping
@PostMapping(value = "/user/login")
// @RequestMapping(value = "/user/login", method = RequestMethod.POST)
public String login(@RequestParam("username") String username,
@RequestParam("password") String password, Map<String,Object> map, HttpSession session){
if (!StringUtils.isEmpty(username) && "123456".equals(password)){
session.setAttribute("loginUser",username); //登陆状态记录到session中
//防止表单重复提交
return "redirect:/main.html"; //不能有空格
}
map.put("msg","用户名密码错误");
return "login";
}
将重定向的/main.html在视图解析器中映射到实际的页面
registry.addViewController("/main.html").setViewName("dashboard");
防止直接通过/main.html请求越过登陆,所以要使用拦截器进行拦截检查
public class LoginHandlerInterceptor implements HandlerInterceptor {
//登陆检查
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//目标方法执行之前
Object user = request.getSession().getAttribute("loginUser");
if (user == null){
//未登录,返回登陆页面
request.setAttribute("msg","没有权限,请先登录");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else {
return true;
}
}
}
在实现WebMvcConfigurer的配置类中注册拦截器加入到容器中
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册登陆拦截器:排除掉去往登陆页面的请求,登陆请求也不能被拦截
//spring boot2.x 版本需要重新对静态资源放行,不然也会被拦截;
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html","/","/user/login","/assets/**");
}
};
原文:https://www.cnblogs.com/JIATCODE/p/13169981.html