springmvc请求处理流程
- 用户发送请求至前端控制器DispatcherServlet
- DispatcherServlet收到请求调用HandlerMapping
- HandlerMapping根据请求Url找到具体的Handler(后端控制器),生成处理器对象及处理器拦截器(如果有则生成)⼀并返回DispatcherServlet
- DispatcherServlet调用HandlerAdapter(处理器适配器)去调用Handler
- HandlerAdapter执行Handler
- Handler执行完成给处理器适配器返回ModelAndView
- HandlerAdapter向DispatcherServlet返回 ModelAndView,ModelAndView 是SpringMVC 框架的⼀个底层对 象,包括 Model 和 View
- DispatcherServlet请求视图解析器去进行视图解析,根据逻辑视图名来解析真正的视图。
- 视图解析器向前端控制器返回View
- 前端控制器进行视图渲染,就是将模型数据(在 ModelAndView 对象中)填充到 request 域
- DispatcherServlet向用户响应结果
配置文件
1、web.xml
<!--配置spring IOC配置文件路径,如果有多个文件可以用逗号将他们分隔开,默认值是/WEB-INF/applicationContext.xml-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/applicationContext.xml
</param-value>
</context-param>
<!--配置ContextLoaderListener用以初始化SpringIOC容器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!--springmvc会根据servlet-name找到对应的配置文件,默认情况下的路径为/WEB-INF/springMvc-servlet.xml,
也可以通过下面的init-param指定,如src/main/resources下创建/spring/spring-mvc.xml-->
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/spring/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
配置DispatcherServlet时推荐使用/,/*会拦截jsp,但是/会拦截静态资源,怎么处理呢?
在springmvc配置文件中添加如下配置
<mvc:default-servlet-handler/>
原理:该标签相当于在springmvc中定义一个DefaultServletHttpRequestHandler对象,对进入DispatcherServlet的url进行过滤,如果发现静态资源,由默认的DefaultServlet来处理。局限在于静态资源只能放在根目录webapp下。
2、spring-mvc.xml
<!-- 使用annotation 自动注册bean,并保证@Required,@Autowired的属性被注入 -->
<context:annotation-config/>
<!--表示使用注解驱动SpringMvc-->
<mvc:annotation-driven/>
<!--它有一个use-default-filters属性,该属性默认为true,扫描并装载指定包下的bean-->
<context:component-scan base-package="com.changhf"/>
<!-- 定义受环境影响易变的变量 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreResourceNotFound" value="false"/>
<property name="locations">
<list>
<value>classpath*:/config.properties</value>
</list>
</property>
</bean>
<!-- 处理静态资源请求,由web应用服务器处理 -->
<mvc:default-servlet-handler/>
<!--mapping静态资源约定地址,location约定的静态资源分发上下文,表示以/resources开头的请求会定位到上下文/下-->
<mvc:resources location="classpath:/" mapping="/resources/**"/>
<!--定义视图解析器,如果前后端分离,可以不加该解析器-->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/view/" p:suffix=".jsp"/>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的最大尺寸为1MB -->
<property name="maxUploadSize">
<value>2097152</value>
</property>
</bean>
<mvc:annotation-driven/>
该注解一定要配置,不然无法装载bean。
mapping静态资源约定地址,location约定的静态资源分发上下文,表示以/resources开头的请求会定位到上下文/下
<mvc:resources location="classpath:/" mapping="/resources/**"/>
视图经常需要返回处理过的日期字符串,这就需要增加日期转换器,可在springmvc中添加如下配置
<!--注册⾃定义类型转换器并注册-->
<bean id="conversionServiceBean" class="org.springframework.format.support.FormattingConversionServiceF
actoryBean">
<property name="converters">
<set>
<bean class="com.lagou.edu.converter.DateConverter">
</bean>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionServiceBean"/>
3、DemoController.java
@Controller
@RequestMapping("/demo")
public class DemoController {
@RequestMapping("/index")
@ResponseBody
public String index() {
return "hello world";
}
@RequestMapping("/home")
public ModelAndView home() {
ModelAndView mv = new ModelAndView();
mv.setViewName("home");
return mv;
}
}
这里测试时index()没有采用相应的任何逻辑视图,而是直接返回一个字符串,所以需要加上@ResponseBody
,home()返回"/WEB-INF/view/home.jsp"。