1. SpringMVC框架简介
MVC = Model(数据模型) + View(视图) + Controller(控制器)
SpringMVC框架主要解决了VC之间的交互问题!在SpringMVC框架中,并不关心M的问题!
在传统的Java EE开发模式下,是使用Servlet组件作为项目的控制器,假设项目中有“用户注册”的功能,则可能需要创建UserRegServlet
,如果还有“用户登录”功能,则可能需要创建UserLoginServlet
,以此类推,每增加1个新的功能,就需要开发一个新的Servlet,如果某个项目中有100个功能,就需要开发100个Servlet,如果有500个功能,就需要开发500个Servlet!而且,每个Servlet可能还需要添加相关的配置,所以,一旦Servlet的数量过多,就会不利于管理和维护,并且,在服务器运行时,需要创建很多Servlet类的对象,会消耗较多的内存空间。
另外,Java EE的许多API并不简洁,在使用时并不是那么方便!
使用SpringMVC框架,以上问题都可以被解决!
2. SpringMVC核心组件
- DispatcherServlet:前端控制器,用于接收所有请求;
- HandlerMapping:用于配置请求路径与Controller组件的对应关系;
- Controller:控制器,具体处理请求的组件;
- ModelAndView:Controller组件处理完请求后得到的结果,由数据与视图名称组成;
- ViewResolver:视图解析器,可根据视图名称确定需要使用的视图组件。
[外链图片转存失败,源站可能有防盗链机制,建议将
3. SpringMVC HelloWorld
3.1. 案例目标
当项目启动后,打开浏览器,输入http://localhost:8080/项目名称/hello.do
网址,可以在浏览器中显示指定的内容!
3.2. 创建项目
创建Maven Project,在创建过程中,勾选Create a simple project,Group Id值为cn.tedu
,Artifact Id为springmvc01
,Packging必须选择war
。
创建好项目后,首先需要生成web.xml,然后,在pom.xml中添加spring-webmvc
依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.6.RELEASE</version>
</dependency>
在使用
spring-webmvc
时,推荐使用4.2或以上版本。
由于SpringMVC框架是基于Spring框架的,所以,需要从前序项目中复制spring.xml文件到当前项目中,并删除原有的配置。
3.3. 配置DispatcherSerlvet
为了保证DispatcherServlet
能正常工作,首先,需要在web.xml中添加配置:
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
由于SpringMVC框架是基于Spring框架的,就需要加载Spring的配置文件,在DispatcherServlet
类的父类FrameworkServlet
类中,定义了名为contextConfigLocation
属性,该属性的值就应该是Spring配置文件的路径,一旦指定了该属性值,当DispatcherServlet
被创建时,就会自动读取所配置的文件!
所以,需要在<servlet>
中补充配置以上contextConfigLocation
属性的值:
<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.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
这个spring.xml还应该在项目启动时就被读取,使得项目启动就加载Spring的环境,所以,还应该将这个DispatcherServlet
配置为启动即初始化:
<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.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
经过配置后,由于存在<load-on-startup>1</load-on-startup>
,所以,当Tomcat启动时,就会初始化DispatcherServlet
,由于配置了初始化参数(<init-param>
系列节点),所以,初始化后就会立即加载spring.xml文件!
接下来,可以检验以上配置是否正确。先在spring.xml中添加组件扫描:
<context:component-scan base-package="cn.tedu.spring" />
然后,在组件扫描的包中创建任意类,并在类的构造方法中添加输出语句:
package cn.tedu.spring;
import org.springframework.stereotype.Component;
@Component
public class User {
public User() {
System.out.println("User.User()");
}
}
因为Tomcat启动时,会加载spring.xml,就会执行组件扫描,在扫描的包中找到User
类,同时,因为User
添加了@Component
注解,所以,Spring框架就会创建User
类的对象,导致User
类的构造方法被执行,其中的输出语句就会被执行!
简单来说,就是Tomcat启动时,可以看到以上构造方法中输出的内容!
3.4. 使用Controller处理客户端提交的请求
先在组件扫描的cn.tedu.spring
包下创建HelloController
控制类(该类的名称没有特殊要求,也不需要继承自指定的父类,或实现特定的接口):
package cn.tedu.spring;
public class HelloController {
}
控制器类必须添加@Controller
注解!注意:不可以使用@Compontent
、@Service
、@Repository
注解!即:
package cn.tedu.spring;
import org.springframework.stereotype.Controller;
@Controller
public class HelloController {
}
然后,应该在类中添加处理请求的方法!关于方法的声明原则:
- 应该使用
public
权限; - 暂时使用
String
作为返回值类型; - 方法的名称可以自定义;
- 方法的参数列表暂时留空。
所以,可以在以上控制器类中添加方法:
package cn.tedu.spring;
import org.springframework.stereotype.Controller;
@Controller
public class HelloController {
public String showHello() {
System.out.println("HelloController.showHello()");
return null; // 暂且返回null值,避免代码持续报错
}
}
最后,在处理请求的方法之前,使用@RequestMapping
注解配置请求路径,以绑定请求路径与方法的对应关系:
package cn.tedu.spring;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("hello.do")
public String showHello() {
System.out.println("HelloController.showHello()");
return null; // 暂且返回null值,避免代码持续报错
}
}
完成后,重新启动Tomcat,在浏览器中输入http://localhost:8080/springmvc01/hello.do
进行访问,在浏览器的窗口将无法正常显示页面,在Eclipse的控制台中可以看到以上方法输出的内容,并且,如果在浏览器中刷新,将会提交多次请求,则Eclipse的控制台可以看到多次输出内容!
3.5. 显示页面
在SpringMVC中,响应给客户端的View可以是多种,例如JSP、Thymeleaf中的HTML模版页面等……首先,应该确定所使用的页面技术,例如本次将使用Thymeleaf,则需要先在pom.xml中添加thymeleaf
和thymeleaf-spring4
的依赖:
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.7.RELEASE</version>
</dependency>
然后,在项目中,创建一个HTML页面,作为最终显示给客户端的页面,作为Thymeleaf的模版页面,应该放在**/webapp/WEB-INF/下,或者,放在src/main/resorces/下,本次选择将HTML模版页面放在src/main/resources/下,所以,先在src/main/resources/下创建名为templates的文件夹,并在该文件夹中创建helloworld.html**页面,并且自定义页面的内容!例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello, SpringMVC!!!</title>
</head>
<body>
<h1>欢迎使用SpringMVC框架!</h1>
</body>
</html>
然后,打开HelloController
控制器类,处理请求的方法的返回值改为"helloworld"
,也就是这个页面文件的文件名,但不包含.html
,即:
package cn.tedu.spring;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("hello.do")
public String showHello() {
System.out.println("HelloController.showHello()");
return "helloworld"; // 此处返回的就是HTML页面的文件名
}
}
接下来,需要在spirng.xml中补充一系列配置:
<!-- 配置模版解析器 -->
<!-- 当使用ClassLoaderTemplateResolver时,将以src/main/resources作为根文件夹 -->
<!-- 当使用ServletContextTemplateResovler时,将以webapp作为根文件夹 -->
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ClassLoaderTemplateResolver">
<property name="characterEncoding" value="utf-8" />
<property name="templateMode" value="HTML" />
<property name="cacheable" value="false" />
<property name="prefix" value="/templates/" />
<property name="suffix" value=".html" />
</bean>
<!-- 配置模版引擎 -->
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
</bean>
<!-- 配置视图解析器 -->
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="characterEncoding" value="utf-8" />
<property name="templateEngine" ref="templateEngine" />
</bean>