SpringBoot5_Web实战1

目标:开发一个spingboot的web项目,项目地址:点我

首先导入实体类和dao层,然后导入静态资源到static文件夹下,页面放入templates文件夹下,项目目录如下所示
在这里插入图片描述

1. 默认访问首页

我们想将login.html作为默认的首页,有两种方法

  1. 在控制类中使用RequestMapping("/login")构建视图映射
  2. 在配置类中添加视图控制器从而构建视图映射,springboot主要采取这种方法
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/santiago").setViewName("success");
    }

    //所有WebMvcConfigurer会一起起作用
    @Bean //将组件注册在容器中
    public WebMvcConfigurer webMvcConfigurer(){
        WebMvcConfigurer adapter = new WebMvcConfigurer() {
            @Override
            public void addViewControllers(ViewControllerRegistry registry) {
                registry.addViewController("/").setViewName("login");
                registry.addViewController("/index.html").setViewName("login");
            }
        };
        return adapter;
    }

}

然后配置login.html,使用thymeleaf语法
在这里插入图片描述

2. 国际化

如果在SpringMVC中要使用国际化,需要以下3步:

  1. 编写国际化配置文件
  2. 使用ResourceBundleMessageSource管理国际化资源文件
  3. 在页面使用fmt:message取出国际化内容

在SpringBoot中,步骤就简单多了

2.1 编写国际化配置文件

在resources根目录下新建一个文件夹i18n,在里面建立三个文件login.properties、login_zh_CN.properties、login_en_US.properties,分别代表默认,中文,英文显示的login页面。

接下来根据login页面中的元素,编写国际化文件

打开login_en_US.properties或者login_zh_CN.properties,切换到Resource Bundle视图,可以方便地编辑三个文件
在这里插入图片描述

2.2 管理国际化资源文件

这里springboot的MessageSourceAutoConfiguration已经帮我们配置好了

public class MessageSourceAutoConfiguration {
    @Bean
    @ConfigurationProperties(
        prefix = "spring.messages"
    )
    
    //设置国际化资源文件的基础名(去掉语言国家代码的)
    @Bean
    public MessageSource messageSource(MessageSourceProperties properties) {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        if (StringUtils.hasText(properties.getBasename())) {           	messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(StringUtils.trimAllWhitespace(properties.getBasename())));
        }
	......
    }
public class MessageSourceProperties {
    private String basename = "messages";

spingboot设置国际化配置文件的基础名为message,我们的国际化配置文件可以直接放在类路径下叫messages.properties ,但是根据第一步我们自己写的国际化配置文件,要重新制定国际化配置文件的基础名

在application.properties文件中添加如下代码

spring.messages.basename=i18n.login

2.3 去页面获取国际化的值

根据thymeleaf,获取国际化值的方法时使用#{*}
在这里插入图片描述

2.4 文件编码

最好按以下方式设置,相当于修改了项目的默认文件编码,包括当前项目
在这里插入图片描述
在这里插入图片描述

2.5 测试

使用Chrome浏览器,选择浏览器语言为中文,且移至首位。之所以将其放在第一个位置,是因为每发一个请求的时候,请求头里的Accept-Language属性的第一个值为zh_CN

首页显示如下

在这里插入图片描述
将Chrome浏览器的语言设置为英文(美国),且移到顶部
在这里插入图片描述
首页显示为
在这里插入图片描述

2.6 点击切换语言

页面底部有个中英文按钮,我们如何使用点击的方式来切换浏览器的语言呢,这就要了解一下国际化的原理。

国际化的配置主要是根据Locale(区域信息对象);LocaleResolver(获取区域信息对象)

WebMvcAutoConfiguration类中有以下方法可以获取locale值

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

这个locale值对应着请求头里的Accept-Language属性的第一个值,当项目中没有用户建立的LocaleResolver时会使用这个默认的LocaleResolver,于是我们创建一个自己的MyLocaleResolver,并将其添加进容器

public class MyLocaleResolver implements LocaleResolver {

    @Override
    public Locale resolveLocale(HttpServletRequest request) {
        String l = request.getParameter("l");
        Locale locale = Locale.getDefault();
        if(!StringUtils.isEmpty(l)){
            //从请求域中获取属性l的值,将其以"_"分开,split[0]代表语言,split[1]代表地区
            String[] split = l.split("_");
            locale = new Locale(split[0],split[1]);
        }
        return locale;
    }

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

    }
}

在配置类MyMvcConfig中将自己创建的LocaleResolver添加进容器,

    @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }

对login.html做如下修改,将l值传入请求域

	<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
	<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>

这样,点击页面上的中文或英文标签就能切换语言。

3. 配置登录页面

  1. 添加LoginController,设置admin以及123456分别为用户名和密码,添加错误登录信息提示

    @Controller
    public class LoginController {
    
        @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){
            if(!StringUtils.isEmpty(username) && "123456".equals(password)){
                //登录成功
                return "dashboard";
            }else{
                //登录失败
                map.put("msg", "用户名密码错误");
                return "login";
            }
        }
    
    }
    
  2. 开发期间模板引擎页面修改以后,要实时生效

    首先在application.properties禁用缓存

    # 禁用缓存
    spring.thymeleaf.cache=false
    

    每当页面重新编辑以后,按Ctrl+F9重新编译

  3. 在login.html中修改form表单中的action请求路径

    <form class="form-signin" th:action="@{/user/login}" th:method="post">
    
  4. 在login页面中添加a标签提示错误信息

    <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
    <!--			判断-->
    <p style="color:red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p>
    <label class="sr-only" th:text="#{login.username}">Username</label>
    

    如果msg为空,不显示错误信息。

  5. 登录成功后,进入dashboard.html,刷新页面的时候,浏览器会提示要重新提交表单。为了防止表单的重复提交,我们修改LoginController,重定向到dashboard页面,在配置类中添加请求映射“/main.html”

    MyMvcConfig.java

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

    LoginController

        public String login(@RequestParam("username") String username,
                            @RequestParam("password") String password,
                            Map<String, Object> map){
            if(!StringUtils.isEmpty(username) && "123456".equals(password)){
                //登录成功
                return "redirect:/main.html";
            }else{
                //登录失败
                map.put("msg", "用户名密码错误");
                return "login";
            }
    
  6. 上一步配置好以后,可以通过请求路径localhost:8080/main.html直接访问dashboard,这就失去了登录页面的意义。我们可以配置拦截器,拦截请求查看是否已经登录,如果已经登录可以通过localhost:8080/main.html直接访问dashboard。

    首先修改LoginController,往session添加已登录的用户名loginUser

        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);
                return "redirect:/main.html";
    //            return "dashboard";
            }else{
    

    创建拦截器component.LoginHandlerInterceptor做登录检查

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

    之后在配置类中把拦截器添加进去,拦截所有请求/**,然后把访问登录页面的请求//index.html/user/login排除掉。对于如css等静态资源的访问,SpringBoot已经做好了配置,我们不用管。

        @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");
                }
    
                //注册拦截器
                @Override
                public void addInterceptors(InterceptorRegistry registry) {
                    registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
                            .excludePathPatterns("/index.html", "/", "/user/login");
                }
            };
            return adapter;
        }
    
  7. 修改dashboard.html,使用[[${session.loginUser}]]在该页面显示登录的用户名

    <body>
    	<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0">
    		<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">[[${session.loginUser}]]</a>
    		<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
            ......
    
  8. 使用thymeleaf方式修改dashboard.html的代码。

发布了108 篇原创文章 · 获赞 22 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/GoSantiago/article/details/102892236