1、Spring 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 浏览器文件上传)的抽象实现 |
2、交互流程
- Request ->DispatcherServlet
- DispatcherServlet->Handler Mapping
- DispatcherServlet->Handler Adapter
- Handler Adapter->Controller - - -> Service(Logic) <- - -> Repository <- - -> Database
- Controller-> View name->Handler Adapter
- DispatcherServlet->View Resolver
- DispatcherServlet->View
- View->Response
Demo
:
spring-webmvc
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── example
│ └── web
│ └── IndexController.java
├── resources
└── webapp
└── WEB-INF
├── app-context.xml
├── jsp
│ └── index.jsp
└── web.xml
app-context.xml
:
<?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.example.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>
web.xml
:
<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>
以注解方式
:
基本配置步骤:
注解配置: @Configuration ( Spring 范式注解 )
组件激活: @EnableWebMvc (Spring 模块装配)
自定义组件 : WebMvcConfigurer (Spring Bean)
1)、修改app-context.xml
文件中bean的:
<?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">
<!--这个不去掉,因为webmvcconfig配置类还需要通过扫描-->
<context:component-scan base-package="com.example.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>
2)、在package com.example.web.config新建WebMvcConfig
配置类:
package com.example.web.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
/**
* Spring web mvc 配置类
*/
@Configuration
@EnableWebMvc
public class WebMvcConfig {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
}
在项目根目录下执行:
mvn -Dmaven.test.skip -U clean package
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar target/spring-webmvc-0.1-SNAPSHOT-war-exec.jar
在浏览器地址localhost:8080,
运行结果和原来输出一样。
常用注解
:
注册模型属性 | @ModelAttribute |
读取请求头 | @RequestHeader |
读取 Cookie | @CookieValue |
校验参数 | @Valid 、 @Validated |
注解处理 | @ExceptionHandler |
切面通知 | @ControllerAdvice |
3、Spring Web MVC 注解驱动
版本依赖:
Spring Framework 3.1 +
支持。
springboot:
springboot1.0+ ->spring framework 4.0+
springboot2.0+ ->spring framework 5.0+
4、 Web MVC自动装配
版本依赖
:
Spring Framework 3.1 +
Servlet 3.0 +
Servlet SPI
:
Servlet SPI ServletContainerInitializer
,参考 Servlet 3.0 规范
配合 @HandlesTypes
Spring 适配
:
SpringServletContainerInitializer
Spring SPI
:
基础接口: WebApplicationInitializer
编程驱动: AbstractDispatcherServletInitializer
注解驱动: AbstractAnnotationConfigDispatcherServletInitializer
自定义:
新建一个类:DefaultAnnotationConfigDispatcherServletInitializer:
package com.example.web.servlet.support;
import com.example.web.config.DispatcherServletConfiguration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
* spring web mvc 自动装配:
*/
public class DefaultAnnotationConfigDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() { // web.xml
return new Class[0];
}
@Override
protected Class<?>[] getServletConfigClasses() { // DispatcherServlet
return new Class[] {DispatcherServletConfiguration.class};
}
@Override
protected String[] getServletMappings() { //
return new String[]{"/"};
}
}
新建一个配置类:DispatcherServletConfiguration
package com.example.web.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.servlet.DispatcherServlet;
/**
* {@link DispatcherServlet} 配置类
*/
@ComponentScan(basePackages = "com.example.web")
public class DispatcherServletConfiguration {
}
注释web.xml如下部分:
<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>
打包运行,在浏览器输入localhost:8080,正常输出。