本文是學習 Spring Boot 的一些準備知識.html
以下圖所示, 基於 Servlet 的 Spring Web MVC 啓動時會建立兩個上下文, 即 Servlet WebApplicationContext
和 Root WebApplicationContext
.前端
前者是 DispatcherServlet
引導建立的, 後者由 ServletContextListener
建立, 包含服務,數據庫操做等非 Web 相關的組件.java
DispatcherServlet
是前端控制器, Spring MVC 遵循前端控制器模式(具體參看
Controller
等應用控制器類.
Servlet規範中描述了 Servlet 和 Filter 的 URL 匹配模式. 以下;spring
/index
*.jsp
/hive/
優先級按精確匹配 > 最長路徑匹配 > 擴展名匹配.數據庫
HandlerMapping
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 = "/"; }
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
規範中定義了異常處理相關的返回信息應該包含什麼內容. 如: javax.servlet.error.stauts_code
定義了錯誤碼; javax.servlet.error.message
定義了錯誤信息; javax.servlet.error.exception
定義了異常.
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..."); } }
經過 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; } }
經過實現 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
定義了一個 void render(@Nullable Map<String, ?> var1, HttpServletRequest var2, HttpServletResponse var3) throws Exception;
方法, 用來渲染視圖.
接口 ViewReslover
定義解析視圖名稱的方法 @Nullable View resolveViewName(String var1, Locale var2) throws Exception;
用來尋找對應的view對象名稱.
view 名稱: prefix + viewname + suffix
前綴 prefix 和 後綴 suffix 一樣能夠配置
spring.mvc.view.suffix=.jsp
ThymeleafAutoConfiguration
一樣能夠找到對應的配置類 ThymeleafProperties
.
ContentNegotiationViewResolver
內容協調處理器, 處理多個 viewResolver 的狀況.MessageSource
抽象.