Spring Boot 六個web實用功能

所用Spring Boot源碼版本爲2.2.6

0x01.默認訪問首頁

  • 達到沒有具體制定資源的情況下,默認訪問首頁。

1.Spring MVC方式:

  • 在控制器類中,做一個資源映射:
@RequestMapping({"/","/index.html"})
public String index(){
    return "login";
}

2.Spring Boot方式:

  • 在自定義的配置類中,增加一個視圖解析器。
  • 細節:在2.x版本的Spring Boot中mvc的配置類去實現WebMvcConfigurer接口,Spring Boot會自動將其中的解析器加入到容器中。
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry){
        registry.addViewController("/").setViewName("login");
        registry.addViewController("/login.html").setViewName("login");
    }
}

0x02.引用jar包中的靜態資源

  • 使用thymeleaf表達式中的@{}修改相應標籤的href屬性,指向webjars中相應的資源。
<link  th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}">

在這裏插入圖片描述

  • 也可以使用static文件夾中的靜態資源。
<img class="mb" src="../asserts/img/bootstrap-solid.svg" 
th:href="@{/asserts/img/bootstrap-solid.svg}" >

在這裏插入圖片描述


0x03.實現國際化

1.國際化配置文件:

  • 抽取頁面中需要使用國際化的信息,寫在配置文件中。
    在這裏插入圖片描述

在這裏插入圖片描述

2.使用ResourceBundleMessageSource管理國際化資源文件:

  • SpringBoot自動配置好了管理國際化資源文件的組件。
  • 差看國際化組件的自動配置類MessageSourceAutoConfiguration源碼:
    在這裏插入圖片描述在這裏插入圖片描述
  • 說明,國際化配置文件的基礎名是messages,如果我們的配置文件直接放在類路徑下叫messages.properties,那麼Spring Boot就會自動幫我們配置,不需要自己進行配置。
  • 如果自己進行配置,只需要Spring Boot的配置文件中指明就可以了。
    在這裏插入圖片描述

3.頁面獲取國際化信息的值:

  • 使用thymeleaf中的#{}語法獲取國際化的值。
Message Expressions: #{...}

在這裏插入圖片描述

  • input輸入框不能使用th:text取值,text是標籤裏面的內容,input輸入框是字節數,沒有標籤體,需要使用 thymeleaf的行內表達式,雙中括號裏面寫表達式。
<p>Hello, [[${session.user.name}]]!</p>

在這裏插入圖片描述

  • 這樣瀏覽器會根據語言信息進行解析。

4.解決亂碼:

  • 全局設置默認自動轉碼。

在這裏插入圖片描述

5.點擊鏈接實現國際化:

  • Spring Boot默認的是根據請求頭帶來的區域信息獲取Locale進行國際化。
  • 如果需要達到點擊鏈接實現國際化,那麼我們不能使用Spring Boot的默認配置,需要自己進行配置,我們可以自定義一個區域信息解析器,並實現LocaleResolver接口。
  • 在按鈕處添加請求:
<a class="btn btn-sm" th:href="@{/(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/(l='en_US')}">English</a>
//可以在鏈接上面攜帶區域信息
public class MyLocaleResolver implements LocaleResolver {
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        String l = httpServletRequest.getParameter("l");
        // 獲取系統默認的區域信息
        Locale locale = Locale.getDefault();
        // 如果參數帶了區域信息,則使用參數的
        if (!StringUtils.isEmpty(l)) {
            String[] s = l.split("_");
            locale = new Locale(s[0], s[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {

    }
}
  • 在mvc的配置類裏面添加一個組件:
@Bean
public LocaleResolver localeResolver() {
	return new MyLocaleResolver();
}
  • 查看一下效果:
    在這裏插入圖片描述在這裏插入圖片描述在這裏插入圖片描述

0x04.登錄攔截器

1.登錄Controller:

  • 如果登錄成功,將用戶信息存入session。
@Controller
public class LoginController {
    @PostMapping(value = "/user/login")
    public String login(@RequestParam("username") String username,
                        @RequestParam("password") String password,
                        Map<String,Object> map, HttpSession session){
        if(!StringUtils.isEmpty(username)&&"atfwus".equals(password)){
            //登錄成功,信息存入session
            session.setAttribute("loginUser", username);
            return "redirect:/main.html";
        }else{
            //登錄失敗
            map.put("msg","用戶名或密碼錯誤!!!");
            return "login";
        }
    }
}

2.編寫一個攔截器類:

  • 編寫一個普通類實現HandlerInterceptor接口
  • 我們需要在接口調用之前攔截請求判斷用戶是否登陸,所以這裏需要使用 preHandle 方法,在裏面編寫寫驗證邏輯,最後返回 true 或者 false,確定請求是否合法。
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("/login.html").forward(request,response);
        } else {
            // 如果session裏有user,表示該用戶已經登陸,放行請求
            return true;
        }
        return false;
    }

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

    }
}

3.配置攔截器類:

  • 在mvc配置類中註冊自定義攔截器,添加攔截路徑和排除攔截路徑。
  • addPathPatterns("/**") 攔截所有的請求 excludePathPatterns(“xxx”) 排除不需要攔截的請求。
//註冊攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
        .excludePathPatterns("/login.html","/","/asserts/**","/webjars/**","/user/login");
}
  • 在這裏,攔截了除了登錄頁面login.html,默認頁面/,靜態資源/asserts/**/webjars/**的所有頁面。
  • 我們可以測試到,在沒有登錄的情況下,直接訪問其它頁面會被攔截。
    在這裏插入圖片描述

0x05.公共頁面元素抽取

  • 利用thymeleaf對頁面的公共進行抽取。

1.抽取公共頁面:

  • 使用th:fragment=""聲明被抽取的部分。
<div th:fragment="headr">
	<div>//...
</div>

2.引入公共片段

  • th:insert:將公共片段整個插入到聲明引入的元素中。

    • ~{templatename::fragmentname}:模板名::片段名。
    • ~{templatename::selector}:模板名::選擇器。
    • insert的公共片段在div標籤中,如果使用th:insert等屬性進行引入,可以不用寫~{},行內寫法可以加上:[[~{}]];[(~{})]
  • th:replace:將聲明引入的元素替換爲公共片段。

  • th:include:將被引入的片段的內容包含進這個標籤中。

<footer th:fragment="headr">
ATFWUS
</footer>

引入方式
<div th:insert="footer :: headr"></div>
<div th:replace="footer :: headr"></div>
<div th:include="footer :: headr"></div>

效果1
<div>
    <footer>
    ATFWUS
    </footer>
</div>

效果2
<footer>
ATFWUS
</footer>

效果3
<div>
ATFWUS
</div>

0x06.錯誤處理

1.Spring Boot 默認處理錯誤的機制

  • Spring Boot遇到錯誤時返回一個默認的錯誤頁面,這個頁面包含了這些信息:

在這裏插入圖片描述

  • ErrorMvcAutoConfiguration類中,進行了錯誤的自動配置,往容器中添加了以下組件。

    • DefaultErrorAttributes組件:幫我們在頁面共享信息;
    • BasicErrorController組件:處理默認/error請求;
    • ErrorPageCustomizer組件:出現錯誤以後來到error請求進行處理;
    • DefaultErrorViewResolver組件:一但系統出現4xx或者5xx之類的錯誤;ErrorPageCustomizer就會生效(定製錯誤的響應規則);就會來到/error請求;就會被BasicErrorController處理;響應頁面,具體去哪個頁面是由DefaultErrorViewResolver解析得到的;

2.定製錯誤頁面:

  • 有模板引擎的情況下;error/狀態碼; 【將錯誤頁面命名爲 錯誤狀態碼.html 放在模板引擎文件夾裏面的 error文件夾下】,發生此狀態碼的錯誤就會來到 對應的頁面;
    • 我們可以使用4xx和5xx作爲錯誤頁面的文件名來匹配這種類型的所有錯誤,精確優先(優先尋找精確的狀態碼.html);

    • 頁面能獲取的信息;

      • timestamp:時間戳
      • status:狀態碼
      • error:錯誤提示
      • exception:異常對象
      • message:異常消息
      • errors:JSR303數據校驗的錯誤都在這裏
  • 沒有模板引擎(模板引擎找不到這個錯誤頁面),靜態資源文件夾下找;
  • 以上都沒有錯誤頁面,就是默認來到SpringBoot默認的錯誤提示頁面;
    在這裏插入圖片描述

3.定製錯誤的json數據:

  • 將數據轉發到/error進行自適應響應效果處理。
    @ExceptionHandler(UserNotExistException.class)//自定義異常
    public String handleException(Exception e, HttpServletRequest request){
        Map<String,Object> map = new HashMap<>();
        //傳入我們自己的錯誤狀態碼  4xx 5xx
        request.setAttribute("javax.servlet.error.status_code",500);
        map.put("code","user.notexist");
        map.put("message","出錯了!!!");

        request.setAttribute("ext",map);
        //轉發到/error
        return "forward:/error";
    }

  • 出現錯誤以後,會來到/error請求,會被BasicErrorController處理,響應出去可以獲取的數據是由getErrorAttributes得到的(是AbstractErrorController(ErrorController)規定的方法);
  • 如果我們要將數據攜帶出去,可以編寫一個ErrorController的實現類(或者編寫AbstractErrorController的子類),放到容器中,頁面上能用的數據,或者是json返回能用的數據都是通過errorAttributes.getErrorAttributes得到;容器中DefaultErrorAttributes.getErrorAttributes();默認進行數據處理的;
//給容器中加入我們自己定義的ErrorAttributes
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {

    @Override
    public Map<String, Object> getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
        Map<String, Object> map = super.getErrorAttributes(requestAttributes, includeStackTrace);
        map.put("msg2","信息");
        return map;
    }
}

ATFWUS --Writing By 2020–04-28

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