概述:SpringMvc是一个基于java是实现MVC模型的轻量级Web框架
入门操作
1.创建web工程
2.导入坐标
<--!tomcat服务器-->
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
<--!SpringMVC和Servlet-->
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
3.定义处理请求的功能类
//定义表现层控制器Bean
@Controller
public class UseController {
//设置映射路径
@RequestMapping("/save")
//设置当前操作返回值为指定的json数据
@ResponseBody
public String save(){
System.out.println("save");
return "ok";
}
}
4.编写SpringMVC配置类,加载出请求的Bean
//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan("com.cyf.controller")
public class SpringMvcConfig {
}
5.加载SpringMVC配置并且设置请求拦截路径,两种方式
继承AbstractAnnotationConfigDispatcherServletInitializer
public class ControllerConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
继承AbstractDispatcherServletInitializer
public class ControllerConfig extends AbstractDispatcherServletInitializer {
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置由springmvc控制器处理的请求响应体
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring配置类
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
在ControllerConfig配置类中需要配置过滤器,用来解决post请求乱码
//配置过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("utf-8");
return new Filter[]{characterEncodingFilter};
}
如果是get请求乱码,那么就需要在到坐标时加上<uriEncoding>utf-8</uriEncoding>
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port><!--tomcat端口号-->
<path>/</path> <!--虚拟目录-->
<uriEncoding>utf-8</uriEncoding><!--访问路径编解码字符集-->
</configuration>
</plugin>
</plugins>
</build>
注解和解析
@Controller 设置表现层Bean
@Controller
public class UseController {
}
@RequestMapping注解 设置当前控制器方法请求访问路径
@RequestMapping("/save")
public void save(){
System.out.println("user save ...");
}
@ResponseBody注解 设置当前控制器方法响应内容为当前返回值,无需解析
@RequestMapping("/save")
@ResponseBody//设置当前操作返回值为指定的json数据
public String save(){
System.out.println("user save ...");
return "{'info':'springmvc'}";
}
AbstractDispatcherServletInitializer类
//加载springmvc配置类,产生springmvc容器(本质还是spring容器)
protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext对象
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
//加载指定配置类
ctx.register(SpringMvcConfig.class);
return ctx;
}
//在创建servlet容器时,加载SpringMVC对应的Bean并放入WebApplicationContext对象范围中
//WebApplicationContext的作用范围是ServletContext范围,也就是整个web容器范围
//设置由springmvc控制器处理的请求映射路径
protected String[] getServletMappings() {
return new String[]{"/"};
}
//指定那些路径需要装入SpringMVC进行处理
//加载spring配置类
protected WebApplicationContext createRootApplicationContext() {
return null;
}
//如果创建Servlet容器时需要加载非SpringMVC对应的bean,使用当前方法进行,使用方式同createServletApplicationContext()
避免Spring错误加载到SpringMVC的Bean
方法一:在SpringConfig包扫描的时候排除掉controller包内的bean
@Configuration
@ComponentScan(value = "com.itheima",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
excludeFilters:排除扫描路径中加载的bean,需要指定类别(type)与具体项(classes)
includeFilters:加载指定的bean,需要指定类别(type)与具体项(classes)
方法二:Spring包扫描的时候设置精准范围
方法三:不区分Spring与SpringMVC的环境,加载到同一个环境中
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
请求与响应
@RequestMapping 设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀
@Controller
//类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径
@RequestMapping("/use")
public class UseController {
//请求路径映射
@RequestMapping("/save") //此时save方法的访问路径是:/use/save
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
}
五种请求参数获取
普通参数使用@RequestParam绑定参数关系
//普通参数:请求参数名与形参名不同时,使用@RequestParam注解关联请求参数名称与形参名称之间的关系
@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestParam("name") String userName , int age){
System.out.println("普通参数传递 userName ==> "+userName);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param different name'}";
@RequestParam 表单提交数据,指定请求参数名称
POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数
//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/save2")
@ResponseBody
public void save2(User user){
System.out.println(user);
}
//请求参数key的名称要和POJO中属性的名称一致,否则无法封装
POJO对象中包含POJO对象
//嵌套属性按照层次结构设定名称即可完成参数传递
@RequestMapping("/save2")
@ResponseBody
public void save2(@RequestBody User user){
System.out.println(user);
}
数组参数类型
//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
@RequestMapping("/arrayParam")
@ResponseBody
public void arrayParam(String[] likes){
System.out.println(Arrays.toString(likes));
}
集合参数类型
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public void listParam(@RequestParam List<String> likes){
System.out.println(likes);
}
//@RequestBody会将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
@RequestMapping("/save4")
@ResponseBody
public void save4(@RequestBody List<User> likes){
System.out.println(likes);
}
json参数传递
需要导入json数据转换相关坐标
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
在SpringMVC配置类中开启自动转换
//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan({"com.cyf.controller","com.cyf.config"})
@EnableWebMvc//开启json数据类型自动转换
public class SpringMvcConfig {
}
@EnableWebMvc注解:作用:开启SpringMVC多项辅助功能功能强大,该注解整合了多个功能,此处仅使用其中一部分功能,即json数据进行自动类型转换
Controller中编写方法接收json参数
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public void listParam(@RequestBody List<String> likes){
System.out.println(likes);
}
@RequestBody 前端在请求体中传递json字符串,使用该注解把json字符串封装成java对象,此注解一个处理器方法只能使用一次
传递json对象数组
//@RequestBody会将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
@RequestMapping("/save4")
@ResponseBody
public void save4(@RequestBody List<User> likes){
System.out.println(likes);
}
日期类型参数传递
//日期参数 http://localhost:80/dataParam?date=2088/08/08&date1=2088-08-18&date2=2088/08/28 8:08:08
//使用@DateTimeFormat注解设置日期类型数据格式,默认格式yyyy/MM/dd
@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}`
属性:pattern:指定日期时间格式字符串
传递日期类数据必须在配置类上使用
响应
响应页面
//响应页面/跳转页面
//返回值为String类型,设置返回值为页面名称,即可实现页面跳转
@RequestMapping("save7")
public String save7(){
return "page.jsp";
}
//只要不在方法上配置@ResponseBody就可以实现页面跳转
//如果配置@ResponseBody那就是文本响应
响应对象
//响应POJO对象
//返回值为实体类对象,设置返回值为实体类类型
@RequestMapping("/save5")
@ResponseBody
public User save5(){
User user = new User();
user.setUsername("zhangsan");
user.setPassword("1234");
return user;
}
响应集合对象
//响应POJO集合对象
//返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据
@RequestMapping("save6")
@ResponseBody
public List<User> save6(){
User user = new User();
user.setUsername("zhangsan");
user.setPassword("1234");
User user1 = new User();
user1.setUsername("lisi");
user1.setPassword("1234");
List<User> list = new ArrayList<User>();
list.add(user);
list.add(user1);
return list;
}
REST风格
表现形态转换,也就是在访问路径上可以不用指定到精确路径,而是可以直接从请求方法和参数进行判断,从而进行访问
优点:隐藏了资源访问路径 ,无法通过地址得知操作
四种主要的请求方法
method = RequestMethod.POST post请求 对应添加操作
method = RequestMethod.DELETE delete请求 对应删除操作
method = RequestMethod.PUT put请求 对应修改操作
method = RequestMethod.GET get请求 对应查询操作
举例
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
//设置当前请求方法,如果要携带参数就在访问路径后在加一个{对应的参数名称}
//@PathVariable指定方法形参对应路径占位符
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
注意:路径占位符的名称要与方法形参名称相同
@RequestBody、@RequestParam、@PathVariable区别
@RequestBody:用于接收json数据
@RequestParam:用于接收url地址传递参数或者表单传参
@PathVariable:用于接收路径参数,使用{参数名称}描述路径参
REST快速开发
在方法上定义简便的请求方法
method = RequestMethod.POST --> @PostMapping()
method = RequestMethod.DELETE --> @DeleteMapping("/{参数名称}"),如果方法需要传参,就需要在括号中加入占位符
method = RequestMethod.PUT --> @PutMapping()
RequestMethod.GET --> @GetMapping()
在Controller类上使用@RestController等同于使用了@Controller和@ResponseBody两个注解