SpringBoot4-Web4-国际化

国际化

  • 编辑国际化配置文件
  • 使用ResourceBundleMessageSource管理国际化资源文件
  • 在页面使用fmt:message取出国际化内容 ### 创建resources/i18n 然后创建login_zh_CN.properties 选择Resouerce Bundle SpringBoot自动创建了管理国际化资源文件的组件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnMissingBean(name = AbstractApplicationContext.MESSAGE_SOURCE_BEAN_NAME, search = SearchStrategy.CURRENT)
    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
    @Conditional(ResourceBundleCondition.class)
    @EnableConfigurationProperties
    public class MessageSourceAutoConfiguration {

    private static final Resource[] NO_RESOURCES = {};

    @Bean
    @ConfigurationProperties(prefix = "spring.messages")
    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;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /**
    * Configuration properties for Message Source.
    *
    * @author Stephane Nicoll
    * @author Kedar Joshi
    * @since 2.0.0
    * /
    public class MessageSourceProperties {

    /**
    * Comma-separated list of basenames (essentially a fully-qualified classpath
    * location), each following the ResourceBundle convention with relaxed support for
    * slash based locations. If it doesn't contain a package qualifier (such as
    * "org.mypackage"), it will be resolved from the classpath root.
    */
    private String basename = "messages";

    1
    spring.messages.basename = i18n.login
    ### thymeleaf 取国际化信息 使用#{}
    1
    <h1 class="..." th:text="#{login.tip}">Please sign in</h1>
    ### 解决乱码 setting - editor - fileEncoding - utf8 - 自动转阿斯克码 ### 测试 在浏览器中选择浏览器默认的语言就可以了,即他可以根据浏览器的语言信息设置语言了 ### 如何实现点按钮实现不同语言呢 #### 国际化原理 locale: LocaleResolver 根据请求头的区域信息来进行国际化
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
    public LocaleResolver localeResolver() {
    if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
    return new FixedLocaleResolver(this.mvcProperties.getLocale());
    }
    AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
    localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
    return localeResolver;
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    @Override
    public Locale resolveLocale(HttpServletRequest request) {
    Locale defaultLocale = getDefaultLocale();
    if (defaultLocale != null && request.getHeader("Accept-Language") == null) {
    return defaultLocale;
    }
    Locale requestLocale = request.getLocale();
    List<Locale> supportedLocales = getSupportedLocales();
    if (supportedLocales.isEmpty() || supportedLocales.contains(requestLocale)) {
    return requestLocale;
    }
    Locale supportedLocale = findSupportedLocale(request, supportedLocales);
    if (supportedLocale != null) {
    return supportedLocale;
    }
    return (defaultLocale != null ? defaultLocale : requestLocale);
    }
    先写个链接把区域信息加上去
    1
    2
    <a class="..." th:href="@{/index.html(l='zh_CN')}">中文</a>
    <a class="..." th:href="@{/index.html(l='en_US')}">English</a>
    然后自己实现区域信息解析器
    1
    2
    3
    4
    @Bean
    public LocaleResolver localeResolver(){
    return new MyLocaleResolver();
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package com.wsx.springboothelloworld.component;

    import org.springframework.cglib.core.Local;
    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 request) {
    String l = request.getParameter("l");
    if(!StringUtils.isEmpty(l)) {
    String[] split = l.split("_");
    return new Locale(split[0], split[1]);
    }
    return Locale.getDefault();
    }

    @Override
    public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {

    }
    }

处理post

1
2
3
4
5
6
7
8
9
10
11
12
package com.wsx.springboothelloworld.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

public class LoginController {
@RequestMapping(value="",method= RequestMethod.POST)
public String login(){
return "dashborad";
}
}

简化写法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.wsx.springboothelloworld.controller;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;


public class LoginController {
// @RequestMapping(value="",method= RequestMethod.POST)
@PostMapping("")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password){
return "dashborad";
}
}


如果成功就进入dashborad,否则就提示用户名密码错误, 考虑使用map实现 这一步后我们可能会碰到一些问题,这是缓存导致的,加入下面的配置
1
spring.thymeleaf.cache=false
然后ctrl+f9手动加载html到编译的文件中,这不必重新开启Spring了

做一个判断来决定标签是否生效

1
<p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>

表单重复提交问题。需要用重定向、视图、拦截器解决,重定向加视图能确保没有重复提交,但是会导致直接跳过登陆的问题,

拦截器

创建拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.wsx.springboothelloworld.component;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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;
}
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

}
}

将登陆成功的用户放入seesion
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class LoginController {
// @RequestMapping(value="",method= RequestMethod.POST)
@PostMapping("")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
Map<String, Object> map,
HttpSession httpSession) {
if (password.endsWith("123456")) {
httpSession.setAttribute("loginUser", username);
return "dashborad";
} else {
return "404";
}
}
}

springboot已经做好了静态资源,不用管他们,不会被拦截, 注意addPathPatterns.excludePathPatterns可以一直搞下去,拦截所有的页面,放行两个html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
return new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/wsx2").setViewName("templates_hello");
registry.addViewController("/wsx3").setViewName("templates_hello");
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
//
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html","/user/login");
}
};
}