SpringMVC概述
三层架构
servlet处理请求和数据的时候,存在的问题是一个servlet只能处理一个请求
因为是异步调用,所以后端不需要返回view视图,将其去除 前端如果通过异步调用的方式进行交互,后台就需要将返回的数据转换成json格式进行返回
SpringMVC主要负责的就是
controller如何接收请求和数据
如何将请求和数据转发给业务层
如何将响应数据转换成json发回到前端
介绍了这么多,对SpringMVC进行一个定义
SpringMVC是一种基于Java实现MVC模型的轻量级Web框架 优点 使用简单、开发便捷(相比于Servlet)
灵活性强
SpringMVC入门案例
SpringMVC具体的实现流程
1.创建web工程(Maven结构)
2.设置tomcat服务器,加载web工程(tomcat插件)
3.导入坐标(SpringMVC+Servlet)
4.定义处理请求的功能类(UserController)
5.设置请求映射(配置映射关系)
6.将SpringMVC设定加载到Tomcat容器中
步骤1:创建Maven项目
步骤2:补全目录结构
步骤3:导入jar包
<?xml version="1.0" encoding="UTF-8"?>
4.0.0
com.itheima
springmvc_01_quickstart
1.0-SNAPSHOT
war
javax.servlet
javax.servlet-api
3.1.0
provided
org.springframework
spring-webmvc
5.2.10.RELEASE
org.apache.tomcat.maven
tomcat7-maven-plugin
2.1
8888
/
说明:
servlet的坐标为什么需要添加provided ? scope是maven中jar包依赖作用范围的描述, 如果不设置默认是compile在在编译、运行、测试时均有效 如果运行有效的话就会和tomcat中的servlet-api包发生冲突,导致启动报错
provided代表的是该包只在编译和测试的时候用,运行的时候无效直接使用tomcat中的,就避免冲突.
步骤4:创建配置类
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
//springmvc配置类,本质上还是一个spring配置类
@Configuration
@ComponentScan("com.itheima.controller")
public class SpringMvcConfig {
}
步骤5:创建Controller类
步骤6:使用配置类替换web.xml
将web.xml删除,换成ServletContainersInitConfig
package com.itheima.config;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
//web容器配置类
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springmvc配置类,产生springmvc容器(本质还是spring容器)
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;
}
}
步骤7:配置Tomcat环境
IDEA配置Tomcat环境
步骤8:启动运行项目
步骤9:设置返回数据为json
如果方法直接返回字符串,springmvc会把字符串当成页面的名称在项目中进行查找 返回,因为不存在对应返回值名称的页面,所以会报404错误,找不到资源。 而我们其实是想要直接返回的是json数据,具体如何修改呢?
添加注解@ResponseBody
package com.itheima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
//定义表现层控制器bean
@Controller
public class UserController {
//设置映射路径为/save,即外部访问路径
@RequestMapping("/save")
//设置当前操作返回结果为指定json数据(本质上是一个字符串信息)
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'info':'springmvc'}";
}
}
工作流程解析
为了更好的使用SpringMVC,我们将SpringMVC的使用过程总共分两个阶段来分析,分别是启动服务 器初始化过程和单次请求过程
启动服务器初始化过程
1. 服务器启动,执行ServletContainersInitConfig类,初始化web容器 功能类似于以前的web.xml
2. 执行createServletApplicationContext方法,创建了WebApplicationContext对象 该方法加载SpringMVC的配置类SpringMvcConfig来初始化SpringMVC的容器
3. 加载SpringMvcConfig配置类
4. 执行@ComponentScan加载对应的bean
扫描指定包及其子包下所有类上的注解,如Controller类上的@Controller注解
5. 加载UserController,每个@RequestMapping的名称对应一个具体的方法
此时就建立了 /save 和 save方法的对应关系
6. 执行getServletMappings方法,设定SpringMVC拦截请求的路径规则
/代表所拦截请求的路径规则,只有被拦截后才能交给SpringMVC来处理请求
单次请求过程
1. 发送请求http://localhost/save
2. web容器发现该请求满足SpringMVC拦截规则,将请求交给SpringMVC处理
3. 解析请求路径/save
4. 由/save匹配执行对应的方法save() 上面的第五步已经将请求路径和方法建立了对应关系,通过/save就能找到对应的save方法
5. 执行save()
6. 检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方
bean加载控制
controller、service和dao这些类都需要被容器管理成bean对象,那么到底是该让SpringMVC加 载还是让Spring加载呢?
业务bean(Service)
功能bean(DataSource,SqlSessionFactoryBean,MapperScannerConfigurer等)
分析清楚谁该管哪些bean以后,接下来要解决的问题是如何让Spring和SpringMVC分开加载各自的 内容。
在SpringMVC的配置类SpringMvcConfig中使用注解@ComponentScan,我们只需要将其扫描范围设 置到controller即可,如
在Spring的配置类SpringConfig中使用注解@ComponentScan ,当时扫描的范围中其实是已经包含 了controller,如:
从包结构来看的话,Spring已经多把SpringMVC的controller类也给扫描到,所以针对这个问题 该如何解决,就是咱们接下来要学习的内容。
概括的描述下咱们现在的问题就是因为功能不同,如何避免Spring错误加载到SpringMVC的bean?
针对上面的问题,解决方案也比较简单,就是:
加载Spring控制的bean的时候排除掉SpringMVC控制的bean
具体该如何排除:
方式一:Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等
方式二:Spring加载的bean设定扫描范围为com.itheima,排除掉controller包中的bean
方式三:不区分Spring与SpringMVC的环境,加载到同一个环境中[了解即可]
设置bean加载控制
方式一:修改Spring配置类,设定扫描范围为精准范围。
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
@Configuration
@ComponentScan({"com.itheima.service","com.itheima.dao"})
public class SpringConfig {
}
说明:
上述只是通过例子说明可以精确指定让Spring扫描对应的包结构,真正在做开发的时候,因为Dao最 终是交给MapperScannerConfigurer对象来进行扫描处理的,我们只需要将其扫描到service包可。
方式二:修改Spring配置类,设定扫描范围为com.itheima,排除掉controller包中的bean
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
@Configuration
//设置spring配置类加载bean时的过滤规则,当前要求排除掉表现层对应的bean
//excludeFilters属性:设置扫描加载bean时,排除的过滤规则
//type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
//classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
@ComponentScan(value="com.itheima",
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
ANNOTATION:按照注解排除
ASSIGNABLE_TYPE:按照指定的类型过滤
ASPECTJ:按照Aspectj表达式排除,基本上不会用
REGEX:按照正则表达式排除
CUSTOM:按照自定义规则排除
大家只需要知道第一种ANNOTATION即可
请求与响应
设置映射路径
package com.itheima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class BookController {
//请求路径映射
@RequestMapping("/book/save")
@ResponseBody
public String save(){
System.out.println("book save ...");
return "{'module':'book save'}";
}
}
package com.itheima.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
//类上方配置的请求映射与方法上面配置的请求映射连接在一起,形成完整的请求映射路径
@RequestMapping("/user")
public class UserController {
//请求路径映射
@RequestMapping("/save")
@ResponseBody
public String save(){
System.out.println("user save ...");
return "{'module':'user save'}";
}
//请求路径映射
@RequestMapping("/delete")
@ResponseBody
public String delete(){
System.out.println("user delete ...");
return "{'module':'user delete'}";
}
}
请求参数
请求路径设置好后,只要确保页面发送请求地址和后台Controller类中配置的路径一致,就可以接 收到前端的请求,接收到请求后,如何接收页面传递的参数?
关于请求参数的传递与接收是和请求方式有关系的,目前比较常见的两种请求方式为:
GET发送单个参数
发送请求与参数:
http://localhost/commonParam?name=itcast
接收参数:
//普通参数:请求参数与形参名称对应即可完成参数传递
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ){
System.out.println("普通参数传递 name ==> "+name);
return "{'module':'common param'}";
}
GET发送多个参数
发送请求与参数:
http://localhost/commonParam?name=itcast&age=15
接收参数:
//普通参数:请求参数与形参名称对应即可完成参数传递
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param'}";
}
GET请求中文乱码
出现乱码的原因相信大家都清楚,Tomcat8.5以后的版本已经处理了中文乱码的问题,但是IDEA中的Tomcat插件目前只到Tomcat7,所以需要修改pom.xml来解决GET请求中文乱码问题
org.apache.tomcat.maven
tomcat7-maven-plugin
2.1
8999
/
UTF-8
POST发送参数
发送请求与参数:
接收参数:
和GET一致,不用做任何修改
//普通参数:请求参数与形参名称对应即可完成参数传递
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'common param'}";
}
POST请求中文乱码
解决方案:配置过滤器
package com.itheima.config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
public class servletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[0];
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
//乱码处理
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return new Filter[]{filter};
}
}
CharacterEncodingFilter是在spring-web包中,所以用之前需要导入对应的jar包。
五种类型参数传递
普通参数
如果形参与地址参数名不一致该如何解决?
解决方案:使用@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类,先来看下User
package com.itheima.domain;
public class User {
private String name;
private int age;
private Address address;
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", age=" + age +
", address=" + address +
'}';
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
发送请求和参数:
后台接收参数:
//POJO参数:请求参数与形参对象中的属性对应即可完成参数传递
@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
System.out.println("pojo参数传递 user ==> "+user);
return "{'module':'pojo param'}";
}
注意:
如果POJO对象中嵌套了其他的POJO类,如
public class Address {
private String province;
private String city;
//setter...getter...略
}
public class User {
private String name;
private int age;
private Address address;
//setter...getter...略
}
发送请求和参数:
后台接收参数
//嵌套POJO参数:嵌套属性按照层次结构设定名称即可完成参数传递
@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoContainPojoParam(User user){
System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
return "{'module':'pojo contain pojo param'}";
}
请求参数key的名称要和POJO中属性的名称一致,否则无法封装
数组类型参数
举个简单的例子,如果前端需要获取用户的爱好,爱好绝大多数情况下都是多个,如何发送请求数据 和接收数据呢?
//数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
return "{'module':'array param'}";
}
集合类型参数
数组能接收多个值,那么集合是否也可以实现这个功能呢?
发送请求和参数
:
后台接收参数:
//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
SpringMVC将List看做是一个POJO对象来处理,将其创建一个对象并准备把前端的数 据封装到对象中.
JSON数据传输参数
前面我们说过,现在比较流行的开发方式为异步调用。前后台以异步方式进行交换,传输的数据使用 的是JSON,所以前端如果发送的是JSON数据,后端该如何接收?
对于JSON数据类型,我们常见的有三种:
对于上述数据,前端如何发送,后端如何接收?
JSON普通数组
步骤1:pom.xml添加依赖
SpringMVC默认使用的是jackson来处理json的转换,所以需要在pom.xml添加jackson依赖
com.fasterxml.jackson.core
jackson-databind
2.9.0
步骤2:PostMan发送JSON数据
步骤3:开启SpringMVC注解支持
在SpringMVC的配置类中开启SpringMVC的注解支持,这里面就包含了将JSON转换成对象的功能。
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}
步骤4:参数前添加@RequestBody
//集合参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据
@RequestMapping("/listParamForJson")
@ResponseBody
public String listParamForJson(@RequestBody List likes){
System.out.println("list common(json)参数传递 list ==> "+likes);
return "{'module':'list common for json param'}";
}
步骤5:启动运行程序
JSON普通数组的数据就已经传递完成,下面针对JSON对象数据和JSON对象数组的数据该如何传递呢?
JSON对象数据
我们会发现,只需要关注请求和数据如何发送?后端数据如何接收?
请求和数据的发送:
{
"name":"itcast",
"age":15
}
后端接收数据:
//POJO参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数据映射到形参的实体类对象中,要求属性名称一一对应
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
System.out.println("pojo(json)参数传递 user ==> "+user);
return "{'module':'pojo for json param'}";
}
启动程序访问测试
说明:
address为null的原因是前端没有传递数据给后端。
如果想要address也有数据,我们需求修改前端传递的数据内容:
{
"name":"itcast",
"age":15,
"address":
{
"province":"beijing",
"city":"beijing"
}
}
JSON对象数组
集合中保存多个POJO该如何实现?
请求和数据的发送:
[
{"name":"itcast","age":15},
{"name":"itheima","age":12}
]
后端接收数据:
//集合参数:json格式
//1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
//2.使用@RequestBody注解将外部传递的json数组数据映射到形参的保存实体类对象的集合对象中,要求属性名称一一对应
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "{'module':'list pojo for json param'}";
}
小结
SpringMVC接收JSON数据的实现步骤为:
(1)导入jackson包
(2)使用PostMan发送JSON数据
(3)开启SpringMVC注解驱动,在配置类上添加@EnableWebMvc注解
(4)Controller方法的参数前添加@RequestBody注解
@RequestBody与@RequestParam区别
区别
@RequestParam用于接收url地址传参,表单传参【application/x-www-formurlencoded】
@RequestBody用于接收json数据【application/json】
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "{'module':'list pojo for json param'}";
}
应用
日期类型参数传递
前面我们处理过简单数据类型、POJO数据类型、数组和集合数据类型以及JSON数据类型,接下来我们 还得处理一种开发中比较常见的一种数据类型,日期类型
日期类型比较特殊,因为对于日期的格式有N多中输入方式,比如: 2088-08-18 2088/08/18 08/18/2088 ......
针对这么多日期格式
,SpringMVC该如何接收,它能很好的处理日期类型数据么?
步骤1:编写方法接收日期数据
在UserController类中添加方法,把参数设置为日期类型
//日期参数
//使用@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'}";
}
SpringMVC默认支持的字符串转日期的格式为yyyy/MM/dd,如果想使用其他格式,需要使用@DateTimeFormat。
响应
对于响应,主要就包含两部分内容:
package com.itheima.controller;
import com.itheima.domain.User;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Controller
public class UserController {
//响应页面/跳转页面
//返回值为String类型,设置返回值为页面名称,即可实现页面跳转
@RequestMapping("/toJumpPage")
public String toJumpPage(){
System.out.println("跳转页面");
return "page.jsp";
}
//响应文本数据
//返回值为String类型,设置返回值为任意字符串信息,即可实现返回指定字符串信息,需要依赖@ResponseBody注解
@RequestMapping("/toText")
@ResponseBody
public String toText(){
System.out.println("返回纯文本数据");
return "response text";
}
//响应POJO对象
//返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
System.out.println("返回json对象数据");
User user = new User();
user.setName("itcast");
user.setAge(15);
return user;
}
//响应POJO集合对象
//返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonList")
@ResponseBody
public List toJsonList(){
System.out.println("返回json集合数据");
User user1 = new User();
user1.setName("传智播客");
user1.setAge(15);
User user2 = new User();
user2.setName("黑马程序员");
user2.setAge(12);
List userList = new ArrayList();
userList.add(user1);
userList.add(user2);
return userList;
}
}
Rest风格
REST简介
REST(Representational State Transfer),表现形式状态转换,它是一种软件架构风格
当我们想表示一个网络资源的时候,可以使用两种方式:
传统风格资源描述形式
http://localhost/user/getById?id=1 查询id为1的用户信息
http://localhost/user/saveUser 保存用户信息
REST风格描述形式
http://localhost/user/1 http://localhost/user
传统方式一般是一个请求url对应一种操作,这样做不仅麻烦,也不安全,因为会程序的人读取了你的 请求url地址,就大概知道该url实现的是一个什么样的操作。 查看REST风格的描述,你会发现请求地址变的简单了,并且光看请求URL并不是很能猜出来该URL的 具体功能 所以REST的优点有:
隐藏资源的访问行为,无法通过地址得知对资源是何种操作 书写简化 但是我们的问题也随之而来了,一个相同的url地址即可以是新增也可以是修改或者查询,那么到底我 们该如何区分该请求到底是什么操作呢?
按照REST风格访问资源时使用行为动作区分对资源进行了何种操作
请求的方式比较多,但是比较常用的就4种,分别是GET , POST , PUT , DELETE。
按照不同的请求方式代表不同的操作类型。
发送GET请求是用来做查询
发送POST请求是用来做新增发送
PUT请求是用来做修改
发送DELETE请求是用来做删除
清楚了什么是REST风格后,我们后期会经常提到一个概念叫RESTful,那什么又是RESTful呢?
根据REST风格对资源进行访问称为RESTful。 后期我们在进行开发的过程中,大多是都是遵从REST风格来访问我们的后台服务,所以可以说咱们以 后都是基于RESTful来进行开发的。
package com.itheima.controller;
import com.itheima.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
public class UserController {
//设置当前请求方法为POST,表示REST风格中的添加操作
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
//设置当前请求方法为DELETE,表示REST风格中的删除操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
//设置当前请求方法为PUT,表示REST风格中的修改操作
@RequestMapping(value = "/users",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user){
System.out.println("user update..."+user);
return "{'module':'user update'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@RequestMapping(value = "/users/{id}" ,method = RequestMethod.GET)
@ResponseBody
public String getById(@PathVariable Integer id){
System.out.println("user getById..."+id);
return "{'module':'user getById'}";
}
//设置当前请求方法为GET,表示REST风格中的查询操作
@RequestMapping(value = "/users",method = RequestMethod.GET)
@ResponseBody
public String getAll(){
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
}
/*
@RequestMapping
@ResponseBody
public String delete(){
System.out.println("user delete...");
return "{'module':'user delete'}";
}
@RequestMapping
@ResponseBody
public String update(){
System.out.println("user update...");
return "{'module':'user update'}";
}
@RequestMapping
@ResponseBody
public String getById(){
System.out.println("user getById...");
return "{'module':'user getById'}";
}
@RequestMapping
@ResponseBody
public String getAll(){
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
*/
package com.itheima.controller;
import com.itheima.domain.Book;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
//@Controller
//@ResponseBody配置在类上可以简化配置,表示设置当前每个方法的返回值都作为响应体
//@ResponseBody
@RestController //使用@RestController注解替换@Controller与@ResponseBody注解,简化书写
@RequestMapping("/books")
public class BookController {
// @RequestMapping( method = RequestMethod.POST)
@PostMapping //使用@PostMapping简化Post请求方法对应的映射配置
public String save(@RequestBody Book book){
System.out.println("book save..." + book);
return "{'module':'book save'}";
}
// @RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
@DeleteMapping("/{id}") //使用@DeleteMapping简化DELETE请求方法对应的映射配置
public String delete(@PathVariable Integer id){
System.out.println("book delete..." + id);
return "{'module':'book delete'}";
}
// @RequestMapping(method = RequestMethod.PUT)
@PutMapping //使用@PutMapping简化Put请求方法对应的映射配置
public String update(@RequestBody Book book){
System.out.println("book update..."+book);
return "{'module':'book update'}";
}
// @RequestMapping(value = "/{id}" ,method = RequestMethod.GET)
@GetMapping("/{id}") //使用@GetMapping简化GET请求方法对应的映射配置
public String getById(@PathVariable Integer id){
System.out.println("book getById..."+id);
return "{'module':'book getById'}";
}
// @RequestMapping(method = RequestMethod.GET)
@GetMapping //使用@GetMapping简化GET请求方法对应的映射配置
public String getAll(){
System.out.println("book getAll...");
return "{'module':'book getAll'}";
}
}
新增
//设置当前请求方法为POST,表示REST风格中的添加操作
@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save(){
System.out.println("user save...");
return "{'module':'user save'}";
}
// @RequestMapping( method = RequestMethod.POST)
@PostMapping //使用@PostMapping简化Post请求方法对应的映射配置
public String save(@RequestBody Book book){
System.out.println("book save..." + book);
return "{'module':'book save'}";
}
删除
前端发送请求的时候使用: http://localhost/users/1 ,路径中的1就是我们想要传递的参数。
后端获取参数,需要做如下修改:
//设置当前请求方法为DELETE,表示REST风格中的删除操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
// @RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE)
@DeleteMapping("/{id}") //使用@DeleteMapping简化DELETE请求方法对应的映射配置
public String delete(@PathVariable Integer id){
System.out.println("book delete..." + id);
return "{'module':'book delete'}";
}
如果有多个参数需要传递该如何编写?
前端发送请求的时候使用: http://localhost/users/1/tom ,路径中的1和tom就是我们想要传递的 两个参数。 后端获取参数,需要做如下修改:
@Controller
public class UserController {
//设置当前请求方法为DELETE,表示REST风格中的删除操作
@RequestMapping(value = "/users/{id}/{name}",method =
RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id,@PathVariable String name)
{
System.out.println("user delete..." + id+","+name);
return "{'module':'user delete'}";
}
}
修改
//设置当前请求方法为PUT,表示REST风格中的修改操作
@RequestMapping(value = "/users",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user){
System.out.println("user update..."+user);
return "{'module':'user update'}";
}
访问该方法使用 PUT: http://localhost/users
根据ID查询
//设置当前请求方法为GET,表示REST风格中的查询操作
//@PathVariable注解用于设置路径变量(路径参数),要求路径上设置对应的占位符,并且占位符名称与方法形参名称相同
@RequestMapping(value = "/users/{id}" ,method = RequestMethod.GET)
@ResponseBody
public String getById(@PathVariable Integer id){
System.out.println("user getById..."+id);
return "{'module':'user getById'}";
}
查询所有
//设置当前请求方法为GET,表示REST风格中的查询操作
@RequestMapping(value = "/users",method = RequestMethod.GET)
@ResponseBody
public String getAll(){
System.out.println("user getAll...");
return "{'module':'user getAll'}";
}
小结
RESTful入门案例,我们需要学习的内容如下:
(1)设定Http请求动作(动词)
@RequestMapping(value="",method = RequestMethod.POST|GET|PUT|DELETE)
(2)设定请求参数(路径变量)
@RequestMapping(value="/users/{id}",method = RequestMethod.DELETE)
@ReponseBody public String delete(@PathVariable Integer id){ }
关于接收参数,我们学过三个注解@RequestBody、@RequestParam、@PathVariable ,这三个注解 之间的区别和应用分别是什么?
区别
@RequestParam用于接收url地址传参或表单传参
@RequestBody用于接收json数据
@PathVariable用于接收路径参数,使用{参数名称}描述路径参数
应用
后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
如果发送非json格式数据,选用@RequestParam接收请求参数
采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路 径变量,通常用于传递id值.
SpringMVC需要将静态资源进行放行。
package com.itheima.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
//设置静态资源访问过滤,当前类需要设置为配置类,并被扫描加载
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
//当访问/pages/????时候,从/pages目录下查找内容
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}
该配置类是在config目录下,SpringMVC扫描的是controller包,所以该配置类还未生效,要 想生效需要将SpringMvcConfig配置类进行修改
@Configuration
@ComponentScan({"com.itheima.controller","com.itheima.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
或者
@Configuration
@ComponentScan("com.itheima")
@EnableWebMvc
public class SpringMvcConfig {
}
页面更新:2024-04-30
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号