Spring Web MVC 的两个Context

  Spring Web MVC 的两个Context
  
  如下图所示, 基于 Servlet 的 Spring Web MVC 启动时会创建两个上下文, 即 Servlet WebApplicationContext 和 Root WebApplicationContext.
  
  前者是 DispatcherServlet引导创建的, 后者由 ServletContextListener 创建, 包含服务,数据库操作等非 Web 相关的组件.
  
  DispatcherServlet
  
  DispatcherServlet 是前端控制器, Spring MVC 遵循前端控制器模式(具体参看一书). 前端控制器是 MVC 模式中 C 的一部分, 除此之外, C 还包括我们定义的 Controller 等应用控制器类.
  
  HandlerMapping
  
  传统 Servlet 的请求 url 模式
  
  Servlet规范中描述了 Servlet 和 Filter 的 URL 匹配模式. 如下;
  
  精确匹配, 如 /index
  
  扩展名匹配, 如 *.jsp
  
  路径匹配, 如 /hive/
  
  优先级按精确匹配 > 最长路径匹配 > 扩展名匹配.
  
  Spring MVC 中的 HandlerMapping
  
  DispatcherServlet
  
  Spring boot 中使用自动装配来实例化和启动 DispatcherServlet. 类名为 DispatcherServletAutoConfiguration, 路径默认为 "" 或 "/" . 可以修改配置, 对应的配置类为 WebMvcProperties , 对应的配置为 spring.mvc.servlet.path=/
  
  从中可以看到 Spring 配置的一般规律, 其他的配置项也可以从配置类中找到依据.
  
  @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等.
  
  可以使用实现接口 HandlerInterceptor 拦截器来验证 handler 的本质. 其中一个方法的签名是 boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler). 注意 handler 定义的类型是 Object, 说明handler的类型可能不止是 HandlerMethod .
  
  异常处理
  
  参看Spring系列(七) Spring MVC 异常处理
  
  Servlet 规范
  
  规范中定义了异常处理相关的返回信息应该包含什么内容. 如: javax.servlet.error.stauts_code 定义了错误码; javax.servlet.error.message 定义了错误信息; javax.servlet.error.exception 定义了异常.
  
  Servlet 实现
  
  web.xml 的配置如下:
  
  
  
  PageNotFoundServlet
  
  com.xlx.servlet.PageNotFoundServlet
  
  

  
  
  
  PageNotFoundServlet
  
  /404.html
  
  

  
  
  
  404
  
  /404.html
  
  

  
  PageNotFoundServlet 实现:
  
  public class PageNotFoundServlet extends HttpServlet{
  
  public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,Exception{
  
  // 此处验证request中设置的错误码.
  
  request.getAttribute(www.yaxingyulpt.com"javax.servlet.error.stauts_code");
  
  response.setCharacterEncoding("UTF-8");
  
  response.setContentType(www.baihuiyulep.cn"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 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 www.tfyL365.com  implements ErrorPageRegistrar{
  
  @Override
  
  public void registerErrorPages(ErrorPageRegistry registry){
  
  registry.addErrorPages(new ErrorPage(www.mmingyLgw.com HttpStatus.NOT_FOUND,"404.html"));
  
  }
  
  }
  
  ....
  
  @GetMapping("/404.html")
  
  public Object handle404(){
  
  // 实现错误处理
  
  }
  
  更多参看相关的那篇文章.
  
  视图
  
  View
  
  接口 View 定义了一个 void render(@Nullable Map var1, HttpServletRequest var2, HttpServletResponse var3) throws Exception; 方法, 用来渲染视图.
  
  ViewReslover
  
  接口 ViewReslover 定义解析视图名称的方法 @Nullable View resolveViewName(baihuiyulegw.com String var1, Locale var2) throws Exception; 用来寻找对应的view对象名称.
  
  view 名称: prefix + viewname + suffix
  
  前缀 prefix 和 后缀 suffix 同样可以配置
  
  spring.mvc.view.suffix=.jsp
  
  Thymeleaf
  
  ThymeleafAutoConfiguration 同样可以找到对应的配置类 ThymeleafProperties.
  
  ContentNegotiationViewResolver 内容协调处理器, 处理多个 viewResolver 的情况.

你可能感兴趣的:(Spring Web MVC 的两个Context)