MVC全称Model View Controller,是一种设计创建Web应用程序的模式。这三个单词分别代表Web应用程序的三个部分:
Model(模型):指数据模型。用于存储数据以及处理用户请求的业务逻辑。在Web应用中,JavaBean对象,业务模型等都属于Model。
View(视图):用于展示模型中的数据的,一般为jsp或html文件。
Controller(控制器):是应用程序中处理用户交互的部分。接受视图提出的请求,将数据交给模型处理,并将处理后的结果交给视图显示。
SpringMVC是一个基于MVC模式的轻量级Web框架,是Spring框架的一个模块,和Spring可以直接整合使用。SpringMVC代替了Servlet技术,它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。
接下来我们编写一个SpringMVC的入门案例
使用maven创建web项目,补齐包结构。
引入相关依赖和tomcat插件
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.12.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webartifactId>
<version>5.2.12.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.12.RELEASEversion>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>2.5version>
<scope>providedscope>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>jsp-apiartifactId>
<version>2.0version>
<scope>providedscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.mavengroupId>
<artifactId>tomcat7-maven-pluginartifactId>
<version>2.1version>
<configuration>
<port>8080port>
<path>/path>
<uriEncoding>UTF-8uriEncoding>
<server>tomcat7server>
<systemProperties>
<java.util.logging.SimpleFormatter.format>%1$tH:%1$tM:%1$tS %2$s%n%4$s: %5$s%6$s%n
java.util.logging.SimpleFormatter.format>
systemProperties>
configuration>
plugin>
plugins>
build>
在web.xml中配置前端控制器DispatcherServlet。
<web-app>
<display-name>Archetype Created Web Applicationdisplay-name>
<servlet>
<servlet-name>dispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:springmvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>dispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
web-app>
编写SpringMVC核心配置文件springmvc.xml,该文件和Spring配置文件写法一样。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.springMVC"/>
<mvc:annotation-driven/>
beans>
编写控制器
@Controller
public class MyController1 {
// 该方法的访问路径是/c1/hello1
@RequestMapping("/c1/hello1")
public void helloMVC(){
System.out.println("hello SpringMVC!");
}
}
使用tomcat插件启动项目,访问 http://localhost:8080/c1/hello1
在这里插入图片描述
在Servlet中我们通过request.getParameter(name)
获取请求参数。该方式存在两个问题:
而SpringMVC支持参数注入的方式用于获取请求数据,即将请求参数直接封装到方法的参数当中。用法如下:
编写控制器方法
// 获取简单类型参数
@RequestMapping("/c1/param1")
public void simpleParam(String username,int age){
System.out.println(username);
System.out.println(age);
}
访问该方法时,请求参数名和方法参数名相同,即可完成自动封装。
http://localhost:8080/c1/param1?username=bz&age=10
SpringMVC支持将参数直接封装为对象,写法如下:
编写实体类
public class Student {
private int id;
private String name;
private String sex;
// 省略getter/setter/tostring
}
编写控制器方法
// 获取对象类型参数
@RequestMapping("/c1/param2")
public void objParam(Student student){
System.out.println(student);
}
访问该方法时,请求参数名和方法参数的属性名相同,即可完成自动封装。
http://localhost:8080/c1/param2?id=1&name=bz&sex=female
编写实体类
public class Address {
private String info; //地址信息
private String postcode; //邮编
// 省略getter/setter/tostring
}
public class Student {
private int id;
private String name;
private String sex;
private Address address; // 地址对象
// 省略getter/setter/tostring
}
编写控制器方法
// 获取关联对象类型参数
@RequestMapping("/c1/param3")
public void objParam2(Student student){
System.out.println(student);
}
访问该方法时,请求参数名和方法参数的属性名相同,即可完成自动封装。
http://localhost:8080/c1/param3?id=1&name=bz&sex=female&address.info=beijing&address.postcode=030000
我们也可以使用表单发送带有参数的请求:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
表单提交
SpringMVC支持将参数封装为List或Map集合,写法如下:
封装为简单数据类型集合
编写控制器方法
// 绑定简单数据类型List参数,参数前必须添加@RequestParam注解
@RequestMapping("/c1/param4")
public void listParam(@RequestParam List<String> users){
System.out.println(users);
}
该方式也可以绑定数组类型:
@RequestMapping("/c1/param5") public void listParam2(@RequestParam String[] users){ System.out.println(users[0]); System.out.println(users[1]); }
请求的参数写法
http://localhost:8080/c1/param4?users=bj&users=springMVC
SpringMVC不支持将参数封装为对象类型的List集合,但可以封装到有List属性的对象中。
编写实体类
public class Student {
private int id;
private String name;
private String sex;
private List<Address> address; // 地址集合
// 省略getter/setter/tostring
}
编写控制器方法
// 对象中包含集合属性
@RequestMapping("/c1/param6")
public void listParam3(Student student){
System.out.println(student);
}
请求的参数写法
[http://localhost:8080/c1/param6?id=1&name=bz&sex=female&address0].info=bj&address[0].postcode=100010&address[1].info=sh&address[1].postcode=100011
同样,SpringMVC要封装Map集合,需要封装到有Map属性的对象中。
编写实体类
public class Student {
private int id;
private String name;
private String sex;
private Map<String,Address> address; // 地址集合
// 省略getter/setter/tostring
}
编写控制器方法
// 对象中包含Map属性
@RequestMapping("/c1/param7")
public void mapParam(Student student){
System.out.println(student);
}
请求的参数写法
[http://localhost:8080/c1/param7?id=1&name=bz&sex=female&address’one’].info=bj&address[‘one’].postcode=100010&address[‘two’].info=sh&address[‘two’].postcode=100011
SpringMVC也支持使用Servlet原生对象,在方法参数中定义HttpServletRequest
、HttpServletResponse
、HttpSession
等类型的参数即可直接在方法中使用。
// 使用Servlet原生对象
@RequestMapping("/c1/param8")
public void servletParam(HttpServletRequest request, HttpServletResponse response, HttpSession session){
// 原生对象获取参数
System.out.println(request.getParameter("name"));
System.out.println(response.getCharacterEncoding());
System.out.println(session.getId());
}
访问该方法即可:http://localhost:8080/c1/param8?name=zhangshan
一般情况下,在SpringMVC中都有对Servlet原生对象的方法的替代,推荐使用SpringMVC的方式代替Servlet原生对象。
前端传来的参数全部为字符串类型,SpringMVC使用自带的转换器将字符串参数转为需要的类型。如:
// 获取简单类型参数
@RequestMapping("/c1/param1")
public void simpleParam(String username,int age){
System.out.println(username);
System.out.println(age);
}
请求路径:http://localhost:8080/c1/param1?username=bz&age=10
但在某些情况下,无法将字符串转为需要的类型,如:
@RequestMapping("/c1/param9")
public void dateParam(Date birthday){
System.out.println(birthday);
}
由于日期数据有很多种格式,SpringMVC没办法把所有格式的字符串转换成日期类型。比如参数格式为birthday=2025-01-01
时,SpringMVC就无法解析参数。此时需要自定义参数类型转换器。
定义类型转换器类,实现Converter接口
// 类型转换器必须实现Converter接口,两个泛型代表转换前的类型,转换后的类型
public class DateConverter implements Converter<String, Date> {
/**
* 转换方法
* @param source 转换前的数据
* @return 转换后的数据
*/
@Override
public Date convert(String source) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = sdf.parse(source);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
注册类型转换器对象
<bean id="converterFactory" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.springMVC.converter.DateConverter">bean>
set>
property>
bean
<filter>
<filter-name>encFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>encFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>