开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
配置
spring mvc提供了一个默认的Dispatcher,用于拦截所有的请求,并调度到对应的Servlet服务上;
使用时,需要在web.xml中注册该Servlet:
<servlet>
<servlet-name> springmvc </servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class>
<!-- 存在时,在应用程序启动时,即装载该Dispatcher,否则第一次请求时才加载 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name> springmvc </servlet-name>
<url-pattern> / </url-pattern>
</servlet-mapping>
另外,在初始化时,框架依赖一个xml配置文件:[servlet-name]-servlet.xml,如上配置,对应的xml如下:
springmvc-servlet.xml
默认加载位置在WEB-INF/springmvc-servlet.xml,如果放在其他位置,可在web.xml文件中添加如下配置:
<servlet>
<servlet-name> springmvc </servlet-name>
<servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class>
<!-- 存在时,在应用程序启动时,即装载该Dispatcher,否则第一次请求时才加载 -->
<load-on-startup>1</load-on-startup>
<!-- 以下自定义配置文件位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/config/springmvc-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name> springmvc </servlet-name>
<url-pattern> / </url-pattern>
</servlet-mapping>
springmvc-serlvet.xml 的作用,是用来配置bean信息,例如:<bean name="/login" class="controllers.LoginController"/>
当访问localhost/login时,会被Dispatcher拦截并解析,然后交给LoginController Servlet类处理请求。
类似servlet时代在web.xml中配置的servlet信息,其中url-pattern指定访问路由信息。
编写服务
编写服务(也可以理解是mvc中的controller)时,有两种方式:
-
继承Controller类,实现方法 handleRequest(...)函数,然后把该Controller.class配置到springmvc.xml中即可,但只能提供一个动作(即服务),不建议使用。
-
使用注解@Controller,一个类可以提供n个服务,重点介绍。
先看示例:
@Controller
public class LoginController{
@RequestBody
@RequestMapping("/login")
public String getInfo(){
return "logni controller info";
}
}
@RequestBody注解的作用是允许返回类型不是ViewAndModel,可以是String等;
@RequestMapping除了指定路由外,还可以指定Method等,如:
//如果只有一个Method,可以省略{...}花括号
@RequestMapping(value="/user",method={RequestMethod.POST,RequestMethod.GET}})
然后把这个服务注册到springmvc-servlet.xml中,让框架知道有这么个服务:
<bean name="/login" class="controllers.LoginController"/>
配置一下tomcat即可运行,框架需要依赖tomcat作为运行应用服务器宿主。
加载流程
应用程序启动时,tomcat会加载web.xml,并调用Dispather Servlet,然后根据加载springmvc-serlvet.xml文件中的beans(如果没有init-param,则默认在WEB-INF下),再通过配置中的class去反射类,根据@Controller注解去查找,如果找到对应的class,则加载的容器中等待调用,否则报错;状态类型时,会解析@Controller类中带有@RequestMapping注解的方法,并装载到容器内,等待调用:路由即@RequestMapping中定义的 /user。
高级知识
服务方法(即标记@RequsetMapping的方法),默认可以提供以下几个参数,框架会自动传值给服务方法:
搭建开发环境-注意事项
-
通过Add Framework Support ,IDE会协助搭建代码结构,比如创建各种xml和配置基本的Web.xml;
-
需要添加pom.xml,对mvc的依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
进阶
如果有n个服务,都在springmvc-servlet.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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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="main.java.services"></context:component-scan>
<mvc:annotation-driven />
<mvc:resources mapping="/css/*" location="/css/" />
</beans>
其中 中的 xsi:schemaLocation="" 这个很关键,比如指定的以下内容:
www.springframework.org/schema/cont… www.springframework.org/schema/cont…
框架会根据这个解析和验证xml配置是否正确,如果没有该内容,会报错。
另外,如果配置了,指定了扫描的包,就不再需要挨个指定bean了。
但是,如果有其他的文件怎么办,比如图片、css、js等,可以指定忽略:
<mvc:resources mapping="/css/*" location="/css/" />
如果使用 必须添加,否则会阻止所有控制器被调用。
其中,关于 的介绍比较见:
@Autowired @Component,@Service,@Controller,@Repository
其中 @Service,@Controller,@Repository和@Component其实是一样的,只是增加了语义上的增强。如果类型被标注了这几个注解,就可以使用@Autowired注入了,前提是在springmvc-servlet.xml中添加包扫描。