美文网首页
Spring Boot Web MVC 核心

Spring Boot Web MVC 核心

作者: gringotts | 来源:发表于2018-10-24 17:39 被阅读0次

理解Spring Web MVC架构

基础架构:Servlet


  • 特点
    • 请求/响应式(Request/Response)
    • 屏蔽网络通讯细节
  • API特性
    • 面向HTTP协议
    • 完整生命周期
  • 职责
  • 处理请求
  • 资源管理(数据库连接、消息连接、其他)
  • 视图渲染

核心架构:前端控制器(Front Controller)

Spring Web MVC 架构

认识Spring Web MVC

Spring Framework时代的一般认识

实现Controller

@Controller
public class HelloWorldController {
    @RequestMapping("")
    public String index() {
        return "index";
    }
}

配置 Web MVC 组件

 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.imooc.web"/>
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

部署DispatchServlet

<web-app>
    <servlet>
    <servlet-name>app</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/app-context.xml</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>app</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

使用可执行 Tomcat Maven 插件

 
<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.1</version>
    <executions>
        <execution>
            <id>tomcat-run</id>
            <goals>
                <goal>exec-war-only</goal>
            </goals>
            <phase>package</phase>
            <configuration>
                <!-- ServletContext path -->
                <path>/</path>
            </configuration>
        </execution>
    </executions>
</plugin>

Spring Framework时代的重新认识

Web MVC 核心组件

组件 Bean 类型 说明
HandlerMapping 映射请求(Request)到处理器(Handler)加上其关联的拦截器 (HandlerInterceptor)列表,其映射关系基于不同的 HandlerMapping 实现的一些 标准细节。其中两种主要 HandlerMapping 实现, RequestMappingHandlerMapping 支持标注 @RequestMapping 的方法, SimpleUrlHandlerMapping 维护精确的URI 路径与处理器的映射。
HandlerAdapter 帮助 DispatcherServlet 调用请求处理器(Handler),无需关注其中实际的调用 细节。比如,调用注解实现的 Controller 需要解析其关联的注解. HandlerAdapter 的主要目的是为了屏蔽与 DispatcherServlet 之间的诸多细节。
HandlerExceptionResolver 解析异常,可能策略是将异常处理映射到其他处理器(Handlers) 、或到某个 HTML 错误页面,或者其他。
ViewResolver 从处理器(Handler)返回字符类型的逻辑视图名称解析出实际的 View 对象,该对 象将渲染后的内容输出到HTTP 响应中。
LocaleResolver, LocaleContextResolver 从客户端解析出 Locale ,为其实现国际化视图。
MultipartResolver 解析多部分请求(如 Web 浏览器文件上传)的抽象实现

交互流程

MVC 注解驱动

  • 版本依赖

    • Spring Framework3.1+
  • 基本配置步骤

    • 注解配置:@Configuration(Spring 范氏注解)
    • 组件激活:@EnableWebMvc (Spring模块装配)
    • 自定义组件:WebMvcConfigurer(Spring Bean)
  • 重构代码:

@ComponentScan(basePackages = "com.imooc.web")
public class DispatchServletConfig {

}
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
    @Bean
    public ViewResolver viewResolver(){
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                System.out.println("拦截中....");
                return true;
            }
        });
    }

}
  • 常用注解
    • 注册模型属性:@ModelAttribute
    • 读取请求头:@RequestHeader
    • 读取Cookie:@CookieValue
    • 校验参数:@Valid@Validated
@Controller
public class HelloWorldController {
    @RequestMapping
    public String index(@RequestHeader("Accept-Language")String acceptLanguage,@CookieValue("JSESSIONID")String jsessionId, Model model){
//        model.addAttribute("acceptLanguage",acceptLanguage);
//        model.addAttribute("jsessionId",jsessionId);
//        model.addAttribute("message","hello,world");
        return "index";
    }
}
@ControllerAdvice(assignableTypes = HelloWorldController.class)
public class HelloWorldControllerAdvice {
    @ModelAttribute("acceptLanguage")
    public String acceptLanguage(@RequestHeader("Accept-Language")String acceptLanguage){
        return acceptLanguage;
    }

    @ModelAttribute("jsessionId")
    public String jsessionId(@CookieValue("JSESSIONID")String jsessionId){
        return jsessionId;
    }

    @ModelAttribute("message")
    public String message(){
        return "hello,world";
    }
    @ExceptionHandler(Throwable.class)
    public ResponseEntity<String> onException(Throwable throwable){
        return ResponseEntity.ok(throwable.getMessage());
    }
}

自动装配

  • 版本依赖
    • Spring Framework3.1+
    • Servlet 3.0+

Servlet SPI

  • ServletContainerInitializer,参考Servlet3.0 规范
  • 配合 @HandlesTypes

Spring 适配

org.springframework.web.SpringServletContainerInitializer

Spring SPI

  • 基础接口:org.springframework.web.WebApplicationInitializer
  • 编程驱动:org.springframework.web.servlet.support.AbstractDispatcherServletInitializer
  • 注解驱动:org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer
public class DefaultAnnotationConfigDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    //web.xml
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }
    //dispatchServlet
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{DispatchServletConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

Spring Boot 时代简化Spring Web MVC

完全自动装配

  • 自动装配DispatcherServletorg.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
    • 装配条件:
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
@EnableConfigurationProperties(ServerProperties.class)
  • 替换@EnableWebMvcorg.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
    • 装配条件:
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
        ValidationAutoConfiguration.class })
  • Servlet 容器:org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration

理解自动装配顺序性

  • 绝对顺序:@AutoConfigureOrder
  • 相对顺序:@AutoConfigureAfter

装配条件

Web类型判断(@ConditionalOnWebApplication
  • WebApplicationType
    • Servlet类型:WebApplicationType.SERVLET
API判断(@ConditionalOnClass
  • Servlet
    • Servlet
  • Spring Web MVC
    • org.springframework.web.servlet.DispatcherServlet
    • org.springframework.web.servlet.config.annotation.WebMvcConfigurer
Bean判断(@ConditionalOnMissingBean@ConditionalOnBean

org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport

外部化配置

Web MVC配置

org.springframework.boot.autoconfigure.web.servlet.WebMvcProperties

spring.mvc.view.prefix = /WEB-INF/jsp/
spring.mvc.view.suffix = .jsp

Spring Boot JSP依赖

 <!-- Provided -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>

相关文章

网友评论

      本文标题:Spring Boot Web MVC 核心

      本文链接:https://www.haomeiwen.com/subject/ajpxtqtx.html