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的代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章