首先,我们要知道Spring-MVC主要是表示层的一个框架,所以这里的时候我们要创建的是一个Web项目了,整合Tomcat在里面而不是之前Spring框架那样,主要集中在数据层和业务层。
首先第一步:在Web.xml文件里面配置DispatcherServlet,其实这一步的配置方法是和普通的配置Servlet是相同的,但是配置的参数有所不同,且用途是有所不同的。
<servlet>
<!--与普通的Servlet不同,这里我们使用的是DispatcherServlet-->
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--我们这里要告诉他如何初始化我们的DispatcherServlet,就是去读取spring-mvc.xml的文件,该文件确保了哪些类可以作为Bean被扫描到-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--“/”意味着就是任何路径都会触发这个Servlet-->
<url-pattern>/</url-pattern>
</servlet-mapping>
从上面的代码我们可以很轻易的看出,<url-pattern>/</url-pattern>
这意味着所有的请求都要经过这里,所以这其实是个总的负责调度的Servlet(核心控制器),他可以根据请求行来将请求转给其他的不同的Servlet,这是如何做到的呢?看下面一步
第二步:首先要转发给其他的Servlet,那么要先知道有哪些Servlet,这个总的Servlet是如何知道他下面有哪些Servlet的呢?我们可以看到上面的代码里面写了
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-mvc.xml</param-value>
</init-param>
这个contextConfigLocation上下文配置,告诉我们要去读取classpath*:spring-mvc.xml文件,那么这个文件里是什么呢?很简单,就一句话
<!--扫描加载所有的控制类类-->
<context:component-scan base-package="com.sun"/>
扫描com.sun包下所有的Bean呀,只要你使用了@Component,或者什么@Controller @Service,那你就会被当作Bean放到IoC容器中,由Spring来管理啦。
第三步:但是扫描到是个Bean,不代表你是个Servlet呀,所以这里就要使用另一个注解@RequestMapping(“Path”),这样就可以让DispatcherServlet定位到你的path,把请求转给你了,但是这里也要注意,我们这个方法执行了要返回一个页面,不能就这么执行完就好了,所以返回一个String(你要返回的页面的名字)才可以。
//设置当前类为Spring的控制器类
@Controller//其实也就是Component
public class UserController {
//设定当前方法的访问映射地址
@RequestMapping("/save")
//设置当前方法返回值类型为String,用于指定请求完成后跳转的页面
public String save(){
System.out.println("user mvc controller is running ...");
//设定具体跳转的页面
return "success.jsp";
}
}
这种跳转等价于Servlet的这种跳转:
到这里,我们简单的理一下思路:
- 配置DispatcherServlet,拦截所有请求
- 告知DispatcherServlet所有的Bean
- 在Bean中加上注释(参数为请求地址)需要作为Servlet的方法。
进阶:
同时,我们为了避免SpringMVC扫描到Spring的Bean,我们可以在配置文件里让他只扫描到特定的文件,不添加Spring的那些Bean。
<context:component-scan base-package="com.itheima">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
还有,因为我们的核心控制器拦截了所有的请求,那么包括,你请求什么图片这类静态资源的时候,也会被拦截,所以为了避免这种请求资源也要被拦截的情况出现,我们可以使用以下配置:
<!--将某个目录声明为资源,访问该资源路径的请求不会被核心控制器拦截,mapping为请求路径,location为实际文件夹路径-->
<mvc:resources mapping="/img/**" location="/img/"/>
当然这种静态资源实在是太多了,你一个个目录写太麻烦了,所以聪明的开发者也帮你写好了。
<!--这里其实就是先定义一个default-servlet对请求进行一个筛查,直接放行那些静态资源的请求,但是注意他对RequestMapping是没用的,他会筛掉RequestMapping修饰的-->
<mvc:default-servlet-handler/>
<!-- 为了防止RequestMapping修饰的Servlet被筛掉,我们这里加入注解驱动的配置,使得他可以通过-->
<mvc:annotation-driven/>
加上这两句就好了,放行全部静态资源