SpringMVC【简介+请求与响应+REST风格】,SpringMVC基础入门第一篇

SpringMVC

springMVC概述:

  • SpringMVC技术和Servlet技术功能相同,均属于web层开发技术。

对于SpringMVC我们主要学习如下内容:

  • SpringMVC简介
  • 请求与响应
  • REST风格
  • SSM整合(注解版)
  • 拦截器

学习目标

  1. 掌握基于SpringMVC获取请求参数和响应json数据操作
  2. 熟练应用基于REST风格的请求路径设置与参数传递
  3. 能够根据实际业务建立前后端开发通信协议并进行实现
  4. 基于SSM整合技术开发任意业务模块功能

显示

SpringMVC简介

SpringMVC概述

将参数传递到业务层,再由业务层访问数据层,得到用户访问的数据后,将数据返回给表现层,表现层将数据转换为Json格式发送给前端页面。前端页面接受数据后,解析数据,组织成用户浏览的页面信息。

之前数据层一开始使用JDBC技术,后来使用了MyBatis框架替换了JDBC技术。之前表现层的开发使用的是Servlet技术,现在使用SpringMVC技术替换原来的Servlet技术。

  • SpringMVC是一种基于Java实现MVC模型的轻量级Web框架

  • 优点:

    • 使用简单,开发便捷(相比于Servlet)
    • 灵活性强

显示
显示

入门案例(掌握)

  1. 使用SpringMVC技术前需要先导入SpringMVC坐标和Servlet坐标
    <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>
  1. 创建SpringMVC控制器类(等同于Servlet功能)
@Controller
public class UserController {
    //2.2设置当前操作的访问路径
    @RequestMapping("/sava")
    //2.3设置当前操作的返回值类型 将返回的东西整体作为响应的内容返回外面
    @ResponseBody
    //定义处理请求的操作
    public String sava(){
        System.out.println("user save模块正在执行.");
        return "{'module':'springmvc'}";
    }
}
  1. 初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的bean
//3.创建springmvc的配置文件,加载controller对应的bean
@Configuration
@ComponentScan("com.zpd.controller")
public class SpringMvcConfig {
}
  1. 初始化Servlet容器,加载SpringMVc环境,并设置SpringMVC技术处理的请求
//4.定义一个servlet容器启动的配置类,在里面加载spring配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    protected WebApplicationContext createServletApplicationContext() {
        //加载springmvc容器配置
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
    //设置那些请求归属springmvc处理
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
    //加载spring容器配置
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

知识点:@Controller

名称@Controller
类型类注解
位置SpringMVC控制器类定义上方
作用设定SpringMVC的核心控制器bean

知识点:@RequestMapping

名称@RequestMapping
类型方法注解 类注解
位置SpringMVC控制器方法定义上方
作用设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀
相关属性value(默认):请求访问路径,或访问路径前缀

知识点:@ResponseBody

名称@ResponseBody
类型类注解或方法注解
位置SpringMVC控制器类或方法定义上方
作用设置当前控制器方法响应内容为当前返回值,无需解析

springMVC入门程序开发总结(1+N)

  • 一次性工作
    • 创建工程,设置服务器,加载工程
    • 导入坐标
    • 创建web容器启动类,加载SpringMVC配置,并设置SpringMVC请求拦截路径
    • SpringMVC核心配置类(设置配置类,扫描controller包,加载Controller控制器bean)
  • 多次工作
    • 定义处理请求的控制器类
    • 定义处理请求的控制器方法,并配置映射路径(@RequestMapping)与返回json数据(@ResponseBody)

本次案例中:

  • AbstractDispatcherServletInitializer类是SpringMWVc提供的快速初始化web3.0容器的抽象类

  • AbstractDispatcherServletInitializer提供三个接口方法供用户实现

    • createServletApplicationContext()方法,创建Servlet容器时,加载springNVC对应的bean并放入
      WebApplicationContext对象范围中,而WebApplicationContext的作用范围为ServletContext范围,即整个web容器范围
        protected WebApplicationContext createServletApplicationContext() {
            AnnotationConfigWebApplicationContext ctx=
                    new AnnotationConfigWebApplicationContext();
            ctx.register(SpringMvcConfig.class);
            return ctx;
        }
    
    • getServletMappings()方法,设定SpringMC对应的请求映射路径,设置为 / 表示拦截所有请求,任意请求都将转入到SpringMVc进行处理
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    
    • createRootApplicationContext()方法,如果创建Servlet容器时需要加载非SpringMVC对应的bean,使用当前方法进行,使用方式同createServletApplicationContext()
        protected WebApplicationContext createRootApplicationContext() {
            return null;
        }
    

入门案例工作流程分析(掌握)

启动服务器初始化过程

  1. 服务器启动,执行ServletContainersInitConfig类,初始化web容器

    • 功能类似于以前的web.xml
  2. 执行createServletApplicationContext方法,创建了WebApplicationContext对象

    • 该方法加载SpringMVC的配置类SpringMvcConfig来初始化SpringMVC的容器
  3. 加载SpringMvcConfig配置类

    @Configuration
    @ComponentScan("com.zpd.controller")
    public class SpringMvcConfig {
    }
    
  4. 执行@ComponentScan加载对应的bean

    • 扫描指定包及其子包下所有类上的注解,如Controller类上的@Controller注解
  5. 加载UserController,每个@RequestMapping的名称对应一个具体的方法

    @Controller
    public class UserController {
        //2.2设置当前操作的访问路径
        @RequestMapping("/sava")
        //2.3设置当前操作的返回值类型 将返回的东西整体作为响应的内容返回外面。
        @ResponseBody
        //定义处理请求的操作
        public String sava(){
            System.out.println("user save模块正在执行.");
            return "{'module':'springmvc'}";
        }
    }
    
    • 此时就建立了 /save 和 save方法的对应关系
  6. 执行getServletMappings方法,设定SpringMVC拦截请求的路径规则

        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    
    • /代表所拦截请求的路径规则,只有被拦截后才能交给SpringMVC来处理请求

单次请求过程

  1. 发送请求http://localhost:端口号/save
  2. web容器发现该请求满足SpringMVC拦截规则,将请求交给SpringMVC处理
  3. 解析请求路径/save
  4. 由/save匹配执行对应的方法save()
    • 上面的第五步已经将请求路径和方法建立了对应关系,通过/save就能找到对应的save方法
  5. 执行save()
  6. 检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方q

Controller加载控制

因为功能不同,如何避免Spring错误的加载到SpringMVc的bean—加载spring控制的bean的时候排除掉springMVC控制的bean

  • controller目录存放的是SpringMVC的controller类
  • service目录存放的是service接口和实现类
  • dao目录存放的是dao/Mapper接口

controller、service和dao这些类都需要被容器管理成bean对象,那么到底是该让SpringMVC加载还是让Spring加载呢?

  • SpringMVC加载其相关bean(表现层bean),也就是controller包下的类

  • Spring控制的bean

    • 业务bean(Service)
    • 功能bean(DataSource,SqlSessionFactoryBean,MapperScannerConfigurer等)
    • 方式一:Spring加载的bean设定扫描范围为com.itheima,排除掉controller包内的bean
  @Configuration
  @ComponentScan({"com.itheima.service","comitheima.dao"})
  public class SpringConfig {
  }
  • 方式二:Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等
@Configuration
@ComponentScan(value="com.itheima",
excludeFilters=@ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
) 
public class SpringConfig {
}
  • excludeFilters属性:设置扫描加载bean时,排除的过滤规则

  • type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除

    • ANNOTATION:按照注解排除
    • ASSIGNABLE_TYPE:按照指定的类型过滤
    • ASPECTJ:按照Aspectj表达式排除,基本上不会用
    • REGEX:按照正则表达式排除
    • CUSTOM:按照自定义规则排除

只需要知道第一种ANNOTATION即可

  • classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean

如何测试controller类已经被排除掉了?

public class App{
public static void main (String[] args){
AnnotationConfigApplicationContext ctx = new
AnnotationConfigApplicationContext(SpringConfig.class);
System.out.println(ctx.getBean(UserController.class));
	}
}

如果被排除了,该方法执行就会报bean未被定义的错误

注意:测试的时候,需要把SpringMvcConfig配置类上的@ComponentScan注解注释掉,否则不会报错

出现问题的原因是,

  • Spring配置类扫描的包是com.itheima
  • SpringMVC的配置类,SpringMvcConfig上有一个@Configuration注解,也会被Spring扫描
  • SpringMvcConfig上又有一个@ComponentScan,把controller类又给扫描进来了
  • 所以如果不把@ComponentScan注释掉,Spring配置类将Controller排除,但是因为扫描到SpringMVC的配置类,又将其加载回来,演示的效果就出不来
  • 解决方案,也简单,把SpringMVC的配置类移出Spring配置类的扫描范围即可

最后一个问题,有了Spring的配置类,要想在tomcat服务器启动将其加载,我们需要修改
ServletContainersInitConfig

protected WebApplicationContext createRootApplicationContext() {
	AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
	ctx.register(SpringConfig.class);
	return ctx;
}

对于上述的配置方式,Spring还提供了一种更简单的配置方式,可以不用再去创建
AnnotationConfigWebApplicationContext对象,不用手动register对应的配置类,如何实现?

  • 简化开发
//web配置类简化开发,仅设置配置类类名即可
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {

    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

知识点:@ComponentScan

名称@ComponentScan
类型类注解
位置类定义上方
作用设置spring配置类扫描路径,用于加载使用注解格式定义的bean
相关属性excludeFilters:排除扫描路径中加载的bean,需要指定类别(type)和具体项 (classes) includeFilters:加载指定的bean,需要指定类别(type)和具体项(classes)

PostMan

  • PostMan是一款强大的网页调试与发送网页HTTP请求的Chrome插件
  • 作用:常用于接口测试
  • 特征
    • 简单
    • 实用
    • 美观
    • 大方

直接使用,然后在里面创建账号与密码。

创建工作区,对于get,post等命令可以进行保存等。

请求和响应

请求映射路径

团队多人开发,每人设置不同的请求路径,冲突问题如何解决-设置模块名作为请求路径前缀

如果出现路径冲突,需要在每个模块里的@RequestMapping注解中添加内容方便区分。

UserController

@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'}";
    }
}

BookController

@Controller
@RequestMapping("/book")
public class BookController {
    //请求路径映射
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
        System.out.println("book save ...");
        return "{'module':'book save'}";
    }
}

在PostMan中进行测试

http://localhost/user/delete ==>{'module':'user delete'}

http://localhost/user/save ==>{'module':'user save'}

http://localhost/book/save ==> {'module':'book save'}

知识点:@RequestMapping

名称@RequestMapping
类型方法注解 类注解
位置SpringMVC控制器方法定义上方
作用设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀
相关属性value(默认):请求访问路径,或访问路径前缀

五种类型参数传递

普通参数

  • Get请求

普通参数:url地址传参,地址参数名与形参变量名相同,定义形参即可接收参数

http://localhost/commonParam?name=sjy&age=20

显示
接收参数:

@Controller
public class UserController {
@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name,int age){
System.out.println("普通参数传递 name ==> "+name);
System.out.println("普通参数传递 age ==> "+age);
return "{'module':'commonParam'}";
	}
}	
  • Post请求

普通参数:form表单post请求传参,表单参数名与形参变量名相同,定义形参即可接收参数

显示

输出内容

普通参数传递 name ==> zpd
普通参数传递 age ==> 21下去
显示

Post乱码处理:配置过滤器

    //乱码处理
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("utf-8");
        return new Filter[]{filter};
    }

对于不同名称的映射,无法正常的传递,需要在参数前面添加@RequestParam注解。

http://localhost/commonParamDifferentName?name=zpd&age=22

    @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'}";
    }

POJO参数

需要是相同的映射,并且里面的参数是POJO里面的参数。

嵌套POJO类型参数

需要是相同的映射,里面的参数是POJO里面的参数,嵌套在里面的内容需要用 .

例如User里面包含name和age,并嵌套了Address,Address里面包含有city和province,传递参数需要如下

KEYVALUE
namezpd
age21
address.cityzhengzhou
address.provincebeijing

数组类型参数

在传递参数时写一样的KEY,不同的值。

    //数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
    @RequestMapping("/arrayParam")
    @ResponseBody
    public String arrayParam(String[] likes){
        System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
        return "{'module':'array param'}";
    }
KEYVALUE
likestrival
likesgame
likesball
likesmeinv

集合类型参数

直接使用数组的方式传递参数会报错。

错误的原因是:SpringMVC将List看做是一个POJO对象来处理,将其创建一个对象并准备把前端的数

据封装到对象中,但是List是一个接口无法创建对象,所以报错。

解决方案是:使用@RequestParam注解

//集合参数:同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据
@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
System.out.println("集合参数传递 likes ==> "+ likes);
return "{'module':'list param'}";
}
  • 集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定
    参数关系
  • 对于简单数据类型使用数组会比集合更简单些。

知识点:@RequestParam

名称@RequestParam
类型形参注解
位置SpringMVC控制器方法形参定义前面
作用绑定请求参数与处理器方法形参间的关系
相关属性required:是否为必传参数 defaultValue:参数默认值

Json数据传输参数

步骤一:pom.xml添加依赖

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.0</version>
    </dependency>

步骤二:PostMan发送JSON数据

显示
步骤三:开启SpringMVC注解支持

@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}

步骤四:参数前添加@RequestBody

    @RequestMapping("/listParamForJson")
    @ResponseBody
    public String listParamForJson(@RequestBody List<String> likes){
        System.out.println("list common(json)参数传递 list ==> "+likes);
        return "{'module':'list common for json param'}";
    }

步骤五:启动运行程序

list common(json)参数传递 list ==> [game, music, travel]

  • POJO集合参数: json数组数据与集合泛型属性名相同,定义List类型形参即可接收参数
    //集合参数:json格式
    //1.开启json数据格式的自动转换,在配置类中开启@EnableWebMvc
    //2.使用@RequestBody注解将外部传递的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'}";
    }

显示

知识点@EnableWebMvc

名称@EnableWebMvc
类型配置类注解
位置SpringMVC配置类定义上方
作用开启SpringMVC多项辅助功能

知识点@RequestBody

名称@RequestBody
类型形参注解
位置SpringMVC控制器方法形参定义前面
作用将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次

@RequestBody与@RequestParam区别

  • 区别:

​ @RequestParam用于接收url地址传参,表单传参【application/x-www-formurlencoded】
​ @RequestBody用于接收json数据【application/json】

  • 应用

    后期开发中,发送json格式数据为主,@RequestBody应用较广
    如果发送非json格式数据,选用@RequestParam接收请求参数

日期类型传递参数

接受形参时,根据不同的日期格式设置不同的接受方式

    @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'}";
    }

显示

知识点:@DateTimeFormat

名称@DateTimeFormat
类型形参注解
位置SpringMVC控制器方法形参前面
作用设定日期时间型数据格式
相关属性pattern:指定日期时间格式字符串

内部实现原理

类型转换器

  • Converter接口
public interface Converter<S, T> {
    @Nullable
    T convert(S var1);
}

​ 请求参数年龄数据(String-→Integer)

​ 日期格式转换(String Date)

  • @EnablewebMvc功能之一:根据类型匹配对应的类型转换器

响应

  • 响应页面(了解)
    //响应页面/跳转页面
    //返回值为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";
    }
  • 响应json数据(对象转json)
    //响应POJO对象
    //返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
    @RequestMapping("/toJsonPOJO")
    @ResponseBody
    public User toJsonPOJO(){
        System.out.println("返回json对象数据");
        User user = new User();
        user.setName("zpd");
        user.setAge(21);
        return user;
    }
  • 响应json数据(对象转json数组)
//响应POJO集合对象
//返回值为集合对象,设置返回值为集合类型,即可实现返回对应集合的json数组数据,需要依赖@ResponseBody注解和@EnableWebMvc注解
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
    System.out.println("返回json集合数据");
    User user1 = new User();
    user1.setName("zpd");
    user1.setAge(15);

    User user2 = new User();
    user2.setName("sjy");
    user2.setAge(12);

    List<User> userList = new ArrayList<User>();
    userList.add(user1);
    userList.add(user2);

    return userList;
}

知识点:新@ResponseBody

名称@ResponseBody
类型方法\类注解
位置SpringMVC控制器方法定义上方和控制类上
作用设置当前控制器返回值作为响应体, 写在类上,该类的所有方法都有该注解功能
相关属性pattern:指定日期时间格式字符串
  • HttpMessageConverter接口
public interface HttpMessageConverter<T> {
    boolean canRead(Class<?> var1, @Nullable MediaType var2);
    boolean canWrite(Class<?> var1, @Nullable MediaType var2);
    List<MediaType> getSupportedMediaTypes();
    T read(Class<? extends T> var1, HttpInputMessage var2) throws IOException, HttpMessageNotReadableException;
    void write(T var1, @Nullable MediaType var2, HttpOutputMessage var3) throws IOException, HttpMessageNotWritableException;
}

REST风格

REST风格简介

  • REST (Representational State Transfer),表现形式状态转换

    • 传统风格资源描述形式

      http:/ / localhost/user/getById?id=1

      http: / / localhost/user/ saveUser

    • REST风格

      http: / /localhost/user/1

      http: / /localhost/user

  • 优点

    • 隐藏资源的访问行为,无法通过地址得知对资源是何种操作
    • 书写简化
  • 按照REST风格访问资源时使用行为动作区分对资源进行了何种操作

    • http: / / localhost/users 查询全部用户信息 GET(查询)
    • http: / /localhost/users/1 查询指定用户信息 GET(查询)
    • http: / / localhost/users 添加用户信息 POST(新增/保存)
    • http: / / localhost/users 修改用户信息 PUT(修改/更新)
    • http:/ /localhost/users/1 删除用户信息 DELETE(删除)
  • 根据REST风格对资源进行访问称为RESTful

上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范
描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如: users、books、accounts.

入门案例

  1. 设定http请求动作(动词)
    //设置当前请求方法为POST,表示REST风格中的添加操作
    @RequestMapping(value = "/users",method = RequestMethod.POST)
    @ResponseBody
    public String save(){
        System.out.println("user save...");
        return "{'module':'user save'}";
    }

    //设置当前请求方法为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'}";
    }
  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

名称@RequestMapping
类型方法注解
位置SpringMVC控制器方法定义上方
作用设置当前控制器方法请求访问路径
相关属性value(默认):请求访问路径,或访问路径前缀 method:http请求动作,标准动作(GET/POST/PUT/DELETE)

知识点@PathVariable

名称@PathVariable
类型形参注解
位置SpringMVC控制器方法中的形参定义前面
作用绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应

@RequestBody @RequestParam @PathVariable

  • 区别

    • @RequestParam用于接收url地址传参或表单传参
    • @RequestBody用于接收json数据
    • @PathVariable用于接收路径参数,使用{参数名称}描述路径参数
  • 应用

    • 后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
    • 如果发送非json格式数据,选用@RequestParam接收请求参数
    • 采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值

RESUful快速开发

问题1:每个方法的@RequestMapping注解中都定义了访问路径/books,重复性太高。
问题2:每个方法的@RequestMapping注解中都要使用method属性定义请求方式,重复性太高。
问题3:每个方法响应json都需要加上@ResponseBody注解,重复性太高。

//@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(@ReqqqqquestBody 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'}";
    }
}

问题一:每个方法的@RequestMapping注解中都定义了访问路径/books,重复性太高

将@RequestMapping提到类上面,用来定义所有方法共同的访问路径

问题二:每个方法的@RequestMapping注解中都要使用method属性定义请求方式,重复性太高

使用@GetMapping @PostMapping @PutMapping @DeleteMapping代替

问题三:每个方法响应json都需要加上@ResponseBody注解,重复性太高

1.将ResponseBody提到类上面,让所有的方法都有@ResponseBody的功能
2.使用@RestController注解替换@Controller与@ResponseBody注解,简化书写

知识点@RequestController

名称@RestController
类型类注解
位置基于SpringMVC的RESTful开发控制器类定义上方
作用设置当前控制器类为RESTful风格, 等同于@Controller与@ResponseBody两个注解组合功能

知识点 @GetMapping @PostMapping @PutMapping @DeleteMapping

名称@GetMapping @PostMapping @PutMapping @DeleteMapping
类型方法注解
位置基于SpringMVC的RESTful开发控制器方法定义上方
作用设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作, 例如@GetMapping对应GET请求
相关属性value(默认):请求访问路径

案例:基于RESTful页面数据交互

  1. 制作SpringMVC控制器,并通过PostMan测试接口功能
@RestController
@RequestMapping("/books")
public class BookController {
    @PostMapping
    public String save(@RequestBody Book book){
        System.out.println("book save ==>"+book);
        return "{'module':'book save success'}";
    }
    @GetMapping
    public List<Book> getAll(){
        System.out.println("book getAll is running");
        List<Book> list = new ArrayList<Book>();

        Book book1 = new Book();
        book1.setType("物联网");
        book1.setName("传感器");
        book1.setDescription("很不咋地");
        list.add(book1);

        Book book2 = new Book();
        book2.setType("大数据");
        book2.setName("hadoop");
        book2.setDescription("也不咋地");
        list.add(book2);
        return list;
    }
}
  1. 设置对静态资源的访问放行
@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/");
    }
}
  1. 前端页面通过异步提交访问后台控制器
                saveBook () {
                   axios.post("http://localhost/books",this.formData).then((res)=>{

                   });
                },

                //主页列表查询
                getAll() {
           /*         axios.get("/books").then((res)=>{
                        this.dataList = res.data;
                    });*/
                    axios.get("http://localhost/books").then((res)=>{
                        this.dataList = res.data;
                    });
                },
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值