Spring Boot系列(一) Spring Boot準備知識

本文是學習 Spring Boot 的一些準備知識.html

Spring Web MVC

Spring Web MVC 的兩個Context

以下圖所示, 基於 Servlet 的 Spring Web MVC 啓動時會建立兩個上下文, 即 Servlet WebApplicationContextRoot WebApplicationContext.前端

前者是 DispatcherServlet引導建立的, 後者由 ServletContextListener 建立, 包含服務,數據庫操做等非 Web 相關的組件.java

DispatcherServlet

DispatcherServlet 是前端控制器, Spring MVC 遵循前端控制器模式(具體參看 一書). 前端控制器是 MVC 模式中 C 的一部分, 除此以外, C 還包括咱們定義的 Controller 等應用控制器類. web

HandlerMapping

  • 傳統 Servlet 的請求 url 模式

Servlet規範中描述了 Servlet 和 Filter 的 URL 匹配模式. 以下;spring

  1. 精確匹配, 如 /index
  2. 擴展名匹配, 如 *.jsp
  3. 路徑匹配, 如 /hive/

優先級按精確匹配 > 最長路徑匹配 > 擴展名匹配.數據庫

  • Spring MVC 中的 HandlerMapping
  1. DispatcherServlet

Spring boot 中使用自動裝配來實例化和啓動 DispatcherServlet. 類名爲 DispatcherServletAutoConfiguration, 路徑默認爲 "" 或 "/" . 能夠修改配置, 對應的配置類爲 WebMvcProperties , 對應的配置爲 spring.mvc.servlet.path=/mvc

從中能夠看到 Spring 配置的通常規律, 其餘的配置項也能夠從配置類中找到依據.app

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
    ...
    @Configuration
    @Conditional(DefaultDispatcherServletCondition.class)
    @ConditionalOnClass(ServletRegistration.class)
    @EnableConfigurationProperties({ HttpProperties.class, WebMvcProperties.class })
    protected static class DispatcherServletConfiguration {
    }
}
@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
    ...
    private final Servlet servlet = new Servlet();
    ...
}
public static class Servlet {

        /**
         * Path of the dispatcher servlet.
         */
        private String path = "/";
}
  1. HandlerMapping

用來找到 URL 匹配的 Handler 方法, 這些方法正是咱們定義的 Controller 中的方法. 這些方法被 @RequestMapping 標記. 這個註解還有一些變體(CRUD): GetMapping , PostMapping, PutMapping, DeleteMapping等.jsp

能夠使用實現接口 HandlerInterceptor 攔截器來驗證 handler 的本質. 其中一個方法的簽名是 boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler). 注意 handler 定義的類型是 Object, 說明handler的類型可能不止是 HandlerMethod .ide

異常處理

參看Spring系列(七) Spring MVC 異常處理

Servlet 規範

規範中定義了異常處理相關的返回信息應該包含什麼內容. 如: javax.servlet.error.stauts_code 定義了錯誤碼; javax.servlet.error.message 定義了錯誤信息; javax.servlet.error.exception 定義了異常.

Servlet 實現

web.xml 的配置以下:

<servlet>
    <servlet-name>PageNotFoundServlet</servlet-name>
    <servlet-class>com.xlx.servlet.PageNotFoundServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>PageNotFoundServlet</servlet-name>
    <url-pattern>/404.html</url-pattern>
</servlet-mapping>

<error-page>
    <error-code>404</error-code>
    <location>/404.html</location>
</error-page>

PageNotFoundServlet 實現:

public class PageNotFoundServlet extends HttpServlet{

    public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,Exception{

        // 此處驗證request中設置的錯誤碼.
        request.getAttribute("javax.servlet.error.stauts_code");

        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();
        writer.println("page not found...");
    }
}

MVC 實現

經過 RestControllerAdvicer.

@RestConstrollerAdvice
public class RestControllerAdvicer{

    @ExceptionHandler(NohandlerFoundException.class)
    public Object pageNotFound(HttpStatus status,HttpServletRequest request,Throwable throwable){
        Map<String,Object> errors = new HashMap<>();
        errors.put("stauts_code",request.getAttribute("javax.servlet.error.stauts_code"));
         errors.put("stauts_uri",request.getAttribute("javax.servlet.error.request_uri"));

         return error;
    }
}

Spring Boot 實現

經過實現 ErrorPageRegistrar 註冊錯誤頁面.

public class Application implements ErrorPageRegistrar{

    @Override
    public void registerErrorPages(ErrorPageRegistry registry){
        registry.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND,"404.html"));
    }
}

....

@GetMapping("/404.html")
public Object handle404(){
    // 實現錯誤處理
}

更多參看相關的那篇文章.

視圖

View

接口 View 定義了一個 void render(@Nullable Map<String, ?> var1, HttpServletRequest var2, HttpServletResponse var3) throws Exception; 方法, 用來渲染視圖.

ViewReslover

接口 ViewReslover 定義解析視圖名稱的方法 @Nullable View resolveViewName(String var1, Locale var2) throws Exception; 用來尋找對應的view對象名稱.

view 名稱: prefix + viewname + suffix

前綴 prefix 和 後綴 suffix 一樣能夠配置

spring.mvc.view.suffix=.jsp

Thymeleaf

ThymeleafAutoConfiguration 一樣能夠找到對應的配置類 ThymeleafProperties.

  • ContentNegotiationViewResolver 內容協調處理器, 處理多個 viewResolver 的狀況.

國際化(i18n)

  • 理解 MessageSource 抽象.
相關文章
相關標籤/搜索