SpringBoot_实现国际化/拦截器进行登陆检查
默认访问首页:
//实现 WebMvcConfigurer 可以来扩展 SpringMVC 的功能
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
/**
* 所有的WebMvcConfigurerAdapter组件都会一起起作用
* 使用 @Bean注解将组件注册在容器
*/
@Bean
public WebMvcConfigurer webMvcConfigurer(){
WebMvcConfigurer adapter = new WebMvcConfigurer() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
registry.addViewController("/main.html").setViewName("dashboard");
}
return adapter;
}
}
实现国际化:
利用浏览器语言,或者页面中的中英文切换,将页面的文字在其他语言和中文进行切换
编写国际化配置文件:
在 application.properties 中添加配置参数,使我们的配置生效:
spring.messages.basename=i18n.login
SpringBoot 自动配置好了管理国际化资源文件的组件:
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnMissingBean(
name = {"messageSource"},
search = SearchStrategy.CURRENT
)
@AutoConfigureOrder(-2147483648)
@Conditional({MessageSourceAutoConfiguration.ResourceBundleCondition.class})
@EnableConfigurationProperties
public class MessageSourceAutoConfiguration {
private static final Resource[] NO_RESOURCES = new Resource[0];
public MessageSourceAutoConfiguration() {
}
@Bean
@ConfigurationProperties(
prefix = "spring.messages"
)
/**
* 配置文件可以命名为:messages.properties ,直接放在类路径下;
* 这样不需要再做其他的任何配置,我们的国际化配置文件就会生效 ;
*/
public MessageSourceProperties messageSourceProperties() {
return new MessageSourceProperties();
}
@Bean
public MessageSource messageSource(MessageSourceProperties properties) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
if (StringUtils.hasText(properties.getBasename())) {
//设置国际化资源文件的基础名 去掉语言国家代码的
messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));
}
if (properties.getEncoding() != null) {
messageSource.setDefaultEncoding(properties.getEncoding().name());
}
messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
Duration cacheDuration = properties.getCacheDuration();
if (cacheDuration != null) {
messageSource.setCacheMillis(cacheDuration.toMillis());
}
messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
return messageSource;
}
...
}
页面获取国际化的值:
在 html 的参数中加上这句 xmlns,使Thymeleaf模板生效:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
...
</html>
在 html 页面使用 #{ } 来取国际化信息 :
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
...
<body class="text-center">
<form class="form-signin" action="dashboard.html">
<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" class="form-control" th:placeholder="#{login.username}" placeholder="Username" required="" autofocus="">
<label class="sr-only" th:text="#{login.password}">Password</label>
<input type="password" class="form-control" th:placeholder="#{login.password}" placeholder="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">© 2020-2021</p>
<a class="btn btn-sm">中文</a>
<a class="btn btn-sm">English</a>
</form>
</body>
</html>
注意点: 此时页面根据浏览器语言设置的信息切换国际化;
点击链接切换国际化:
页面添加超链接,请求参数上携带国际化信息:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
...
<a class="btn btn-sm" th:href="@{/index.html(language='zn_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(language='en_US')}">English</a>
...
</html>
自定义国际化解析器,实现 LocaleResolver 接口 :
public class MyLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
String l = httpServletRequest.getParameter("l");
Locale locale = Locale.getDefault();
if(!StringUtils.isEmpty(language)){
String[] split = l.split("_");
locale = new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
在编写的配置类中,使用 @Bean 注解将 MyLocaleResolver 注入到 SpringBoot 容器中,使配置生效:
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
原理分析:
Locale(区域信息对象);LocaleResolver(获取区域信息对象);
当进行 HTTP请求 访问时,在这个 HTTP 请求头中有 Accept-Language 参数信息,会封装成 Locale 对象,LocaleResolver 国际化解析器 获取 Locale 对象来实现国际化。
SpringBoot 在 WebMvcAutoConfiguration 自动配置类中给容器添加了 LocaleResolver 国际化解析器组件,而且该组件上有 @ConditionalOnMissingBean 注解,表示如果没有自定义 LocaleResolver 就使用 SpringBoot 提供默认的 AcceptHeaderLocaleResolver,否则使用我们自定义的 MyLocaleResolver ;
@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 localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
}
效果图:
默认页面/中文页面
英文页面
拦截器进行登陆检查:
实现 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){
//未登陆,返回登陆页面
request.setAttribute("msg","没有权限请先登录");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else{
return true;
}
}
...
}
在自己编写的配置类中,注册拦截器:
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
...
@Bean
public WebMvcConfigurer webMvcConfigurer(){
WebMvcConfigurer adapter = new WebMvcConfigurer() {
...
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//*.css , *.js等静态资源 ,SpringBoot已经做好了静态资源映射
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login");
}
};
return adapter;
}
...
}