Spring Web MVC入门(2)——请求(上)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: Spring Web MVC入门(2)——请求

       访问不同的路径,就是发送不同的请求在发送请求时,可能会带一些参数,所以学习Spring的请求,主要是学习如何传递参数到后端,以及后端如何接收

       传递参数,这里主要使用Postman来模拟,浏览器也可以,但是Postman会更方便。

后端开发人员无需过度关注如何传递参数,了解即可,实际开发中以Postman测试为主。比如餐厅里的厨师,不需要关注用户是在店里下单还是外卖平台下单,只需要知道如何接收订单,根据订单做出对应的菜肴即可。


一、传递单个参数


       接收单个参数,在Spring MVC中直接使用方法中的参数就可以了,比如以下代码:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
@RequestMapping("/Demo1")
public class Demo1 {
    @RequestMapping("/test")
    public String test(String name) {
        return "接收到的参数name:" + name;
    }
}

       Postman观察返回的请求:

       查询字符串名称必须和方法里的参数名称一样,如图:

       现在把name改成name1,结果如下:

       因为URL已经指定要访问test方法了,但是方法没有name1这个参数,就只能返回一个null了。

基础类型和包装类型的区别

1、基础类型

       基础类型现在正常传参,代码如下:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
@RequestMapping("/Demo1")
public class Demo1 {
    @RequestMapping("/test")
    public String test(int age) {
        return "接收到的参数age:" + age;
    }
}

       Postman:

       

       是没有任何问题的。下面看看如果不传参,会怎么样

(1)不传参

       Postman:

       错误码是500,说明是服务器这边出问题了,观察程序日志:

       上面说int类型的参数age,虽然为可选的,但由于被声明为基本类型,而不能转换为空值,考虑将其声明为对应基本类型的包装类型。按照错误信息解决错误即可初学者也应该养成看错误日志的习惯

(2)传字符串

       传字符串,Postman:

       错误码是400,说明是客户端这边出问题了,error提示:Bad Request,说明请求有问题,再看服务器这边,也出现了警告日志:

       如果实在看不懂,可以去有道云进行翻译,如图:

       说明基本类型int不能转换为字符串

2、包装类型

       代码如下:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
@RequestMapping("/Demo1")
public class Demo1 {
    @RequestMapping("/test")
    public String test(Integer age) {
        return "接收到的参数age:" + age;
    }
}

       正常传参,观察结果:

       没有问题。

(1)不传参

       当不传参时,Postman结果如下:

       和基本类型不同,并没有报错,而是显示出null。

       对于包装类型,如果不传对应参数,Spring接收到的数据则为null,所以企业开发中,对于参数可能为空的数据,建议使用包装类型

(2)传字符串

       传字符串,Postman结果:

       报错和基本类型一样,日志如下:

3、小结

       对于方法里参数可能为null的数据,建议使用包装类型而对于传递对象时(后面会讲到),对象(类)里面可以不使用包装类型如果无法进行区分,那就都使用包装类型好了


二、传递多个参数


       和接收单个参数一样,无非就是多加几个参数而已,代码如下:

    @RequestMapping("/test2")
    public String test2(String name, Integer age) {
        return "接收到的参数name:" + name + "  接收到的参数age:" + age;
    }
}

       Postman观察结果如下:

       这里传参的时候,填入query string 的参数位置顺序可以任意的,结果不受这个顺序影响

       但是如果要传很多个,3个,4个,5个.....,这样进行传参代码就会显得很丑,所以,就可以引入对象,下面的内容介绍传对象。


三、传递对象


       现在有Student类,代码如下:

public class Student {
    private String name;
    private int age;
    private int id;
 
    public String getName() {return name;}
    public int getAge() {return age;}
    public int getId() {return id;}
    public void setName(String name) {this.name = name;}
    public void setAge(int age) {this.age = age;}
    public void setId(int id) {this.id = id;}
 
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                '}';
    }
}

       传递对象的代码:

    @RequestMapping("test3")
    public Object test3(Student student) {
        return student.toString();
    }

       Postman发送请求,结果如下:

       如果不传参数呢?这里不会吧报错?试一下就知道了,如图:

       

       可以看到,并不会报错原因就是在对象(类)中,成员属性会自动初始化使用基础类型,也会进行初始化,如果没有传递这个参数,不会报错但如果直接在接口方法中声明,使用int类型,没传参就会报错,就像上面介绍基础类型报错的例子。


四、后端参数重命名(后端参数映射)


       某些特殊的情况下,前端传递的参数key和我们后端接收的key可以不一致,比如前端传递了一个time给后端,但后端是使用createtime字段来接收的,这样就会出现参数接收不到的情况,如果我们想前端传过来的参数,后端接收的参数是重命名后的,就可以使用@RequestParam来重命名后端等待参数值。

       代码如下:

@RequestMapping("d1")
@RestController
public class Demo1 {
    @RequestMapping("r1")
    public String method_1(@RequestParam(value = "time") String newTime) {
        return "接收到的参数newTime:" + newTime;
    }
}

       postman页面如下:

       

       可以看到,Spring可以正确的把浏览器传递的参数time绑定到后端参数newTime上。

       我们试试传参的参数改成newTime,看看有没有问题,postman页面如下:

       

       错误码400,说明客户端这边的请求有问题,看看报错日志:

       请求参数“time”不存在,说明访问这个方法,必须要有参数,而我们传的newtTime参数,在这里没有,所以就报错了,我们也可以设置参数不是必须的,代码如下:

@RequestMapping("d1")
@RestController
public class Demo1 {
    @RequestMapping("r1")
    public String method_1(@RequestParam(value = "time",required = false) String newTime) {
        return "接收到的参数newTime:" + newTime;
    }
}

       这样如果我们没有传参,也不会报错了,如图:

       

       或者传其他参数名,也不会报错

       

在这里可以得出结论:

1、注解:@RequestParam 进行参数重命名时,请求参数只有和@RequestParam声明的名称一致,才能进行参数绑定和赋值。

2、注解:@RequestParam 默认访问此方法是必须要带参数的,也可以设置不再参数。


五、传递数组


       传递数组时,Spring MVC可以自动绑定数组参数的赋值,代码如下:

    @RequestMapping("r2")
    public String method2(String[] str) {
        return Arrays.toString(str);
    }

       postman页面如下:

       

       浏览器可以使用以下URL:

http://127.0.0.1:8080/d1/r2?str=zhangsan&str=lisi&str=wangwu

http://127.0.0.1:8080/d1/r2?str=zhangsan%2clisi%2cwangwu

http://127.0.0.1:8080/d1/r2?str=zhangsan,lisi,wangwu


六、传递集合


       集合参数,和数组类似,同一个请求参数名有多个,且需要使用@RequestParam注解绑定参数关系。

       默认情况下,请求中参数名相同的多个值,是封装到数组。如果要封装到集合,要使用@RequestParam绑定参数关系。

不加注解@RequestParam

       不加注解@RequestParam的代码:

    @RequestMapping("r3")
    public String method3(List<String> list) {
        return "size:" + list.size() + ",list:" + list;
    }

       postman页面:

       

       可以看到,服务器这边报错了,看看日志:

       说明传参的时候,出问题了,因为没有加注解@RequestParam,所以默认传的参数是数组,但接收的确实集合List,所以服务器这边代码就会报错。

加注解@RequestParam

       加注解@RequestParam的代码:

    @RequestMapping("r3")
    public String method3(@RequestParam List<String> list) {
        return "size:" + list.size() + ",list:" + list;
    }

       postman页面:

       

       可以看到,这时候就没出错了,因为加了注解@RequestParam后,客户端这边传的参数就不是数组了,而是List。


七、传递JSON数据


1、JSON概念

       JSON:JavaScript Object Notation【JavaScript 对象表示法】。

       JSON是一种轻量级的数据交互格式。它基于ECMAScript(欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式,来存储和表示数据。——百度百科

       简单来说:JSON就是一种数据格式,有自己的格式和语法,使用文本表示一个对象或数组的信息,因此JSON本质是字符串。主要负责在不同的语言中进行数据传递和交换。

       类似于:国际通用语言:英语。或者是中国56个民族不同地区的通用语言:普通话。有自己的语法,但其他语言也认识。

JSON于JavaScript的关系:

       没有关系,只是语法相似,js开发者能更快的上手而已,但是他的语法本身比较简单,所以也很好学。

2、JSON语法

       JSON是一个字符串,它的格式非常类似JavaScript对象字棉量的格式,如下是一段JSON数据:

{

   "squadName": "Super hero squad",

   "homeTown": "Metro City",

   "formed": 2016,

   "secretBase": "Super tower",

   "active": true,

   "members": [

       {

           "name": "Molecule Man",

           "age": 29,

           "secretIdentity": "Dan Jukes",

           "powers": [

               "Radiation resistance",

               "Turning tiny",

               "Radiationblast"

           ]

       },

       {

           "name": "Madame Uppercut",

           "age": 39,

           "secretIdentity": "Jane Wilson",

           "powers": [

               "Million tonne punch",

               "Damage resistance",

               "Superhumanreflexes"

           ]

       },

       {

           "name": "Eternal Flame",

           "age": 1000000,

           "secretIdentity": "Unknown",

           "powers": [

               "Immortality",

               "Heat Immunity",

               "Inferno",

               "Teleportation",

               "Interdimensional travel"

           ]

       }

   ]

}

       也可以进行压缩:

{"squadName":"Super hero squad","homeTown":"Metro City","formed":2016,"secretBase":"Super tower","active":true,"members":[{"name":"Molecule Man","age":29,"secretIdentity":"Dan Jukes","powers":["Radiation resistance","Turning tiny","Radiationblast"]},{"name":"Madame Uppercut","age":39,"secretIdentity":"Jane Wilson","powers":["Million tonne punch","Damage resistance","Superhumanreflexes"]},{"name":"Eternal Flame","age":1000000,"secretIdentity":"Unknown","powers":["Immortality","Heat Immunity","Inferno","Teleportation","Interdimensional travel"]}]}

       压缩后和没压缩之前的数据是一样的,只不过没压缩的进行了格式化,更易读。

(1)JSON的语法:

1、数据在 键值对(Key / Value)中。

2、数据由逗号 " , " 分割。

3、对象用 " { } " 表示。

4、数组用 " [ ] " 表示。

5、值可以为对象,也可以为数组,数组中可以包含多个对象。

(2)JSON的两种结构:

1、对象:大括号 " { } " 保存的对象是一个无序的 键值对 集合。一个对象以左括号 " { " 开始,右括号 " } " 结束。每个 "键" 后跟一个冒号 " : ",键值对使用逗号 " , " 分隔。

2、数组:中括号 " [ ] " 保存的数组是值(Value)的有序集合。一个数组以左中括号 " [ " 开始,右中括号 " ] ",值之间使用逗号 " , " 分隔。

所以,以下都是合法的JSON数据:

{"name":"admin","age":18}

["hello", 3.1415, "json"]

[{"name":"admin","age":18},{"name":"root","age":16},{"name":"张三","age":20}]

       可以使用在线JSON格式化工具来进行校验和书写:在线JSON校验格式化工具(Be JSON)

3、JSON字符串和Java对象互转

       JSON本质上是一个字符串,通过文本来存储和描述数据。

       Spring MVC框架也集成了JSON的转换工具,我们可以直接使用,来完成JSON字符串和Java对象的互转。

       本质上是 Jackson-databind 提供的功能,Spring MVC框架中已经把该工具包引入了进来,咱们直接使用即可,如果脱离SPring MVC使用,需要引入相关依赖:

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

       Person类如下:

public class Person {
    private int id;
    private String name;
    private String password;
    public Person(){ };
    public Person(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    };
    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
    public int getId() {return id;}
    public String getName() {return name;}
    public String getPassword() {return password;}
    public void setId(int id) {this.id = id;}
    public void setName(String name) {this.name = name;}
    public void setPassword(String password) {this.password = password;}
}

       互转的代码如下:

public class JSONUtils {
    private static ObjectMapper objectMapper = new ObjectMapper();
 
    public static void main(String[] args) throws JsonProcessingException {
        Person person = new Person(10, "zhangsan", "123456");
        //对象转为JSON字符串
        String jsonStr = objectMapper.writeValueAsString(person);
        System.out.println("JSON字符串为:" + jsonStr);
        //JSON字符串转为对象
        Person p = objectMapper.readValue(jsonStr, Person.class);
        System.out.println("转换的对象为:" + person.toString());
    }
}

       运行结果如下:

4、JSON优点

1、简单易用:语法简单,易于理解和编写,可以快速地进行数据转换。

2、跨平台支持:JSON可以被多种编程语言解析和生成,可以在不同的平台和语言之间进行数据交换和传输。

3、轻量级:相较于XML格式,JSON数据格式更加轻量级,传输数据时占用的带宽较小,可以提高传输速度。

4、易于扩展:JSON的数据结构灵活,支持嵌套对象和数组等复杂的数据结构,便于扩展和使用。

5、安全性:JSON数据格式是一种纯文本格式,不包含可执行代码,不会执行恶意代码,因此具有较高的安全性。

       基于以上特点,JSON在Web应用程序中被广泛使用,如前后端数据交互、API接口数据传输等。

5、传递JSON对象

       接收JSON对象,需要使用@RequestBody注解。

RequestBody:请求正文,意思是这个注解作用在请求正文的数据绑定,请求参数必须写在请求正文中。

       后端代码如下:

@RestController
@RequestMapping("/d1")
public class Demo {
    @RequestMapping("/m1")
    public Object method1(@RequestBody Person person) {
        return person.toString();
    }
}

       使用postman发送json请求参数:

       可以看到,后端正确接收到了,下面通过fiddler观察一下请求参数:

       

       可以看到,请求类型是json。那如果后端代码去掉注解@RequestBody呢?代码如下:

@RestController
@RequestMapping("/d1")
public class Demo {
    @RequestMapping("/m1")
    public Object method1( Person person) {
        return person.toString();
    }
}

       继续使用Postman传递json,看看响应结果:

       可以看到,并没有给person赋值成功。


Spring Web MVC入门(2)——请求(下):https://developer.aliyun.com/article/1528172

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
26天前
|
前端开发 Java 数据库
SpringBoot入门 - 对Hello world进行MVC分层
SpringBoot入门 - 对Hello world进行MVC分层
43 3
SpringBoot入门 - 对Hello world进行MVC分层
|
1月前
|
前端开发 Java 数据库
SpringBoot入门(3) - 对Hello world进行MVC分层
SpringBoot入门(3) - 对Hello world进行MVC分层
33 4
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
58 4
|
20天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
38 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
4天前
|
设计模式 前端开发 Java
步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理
通过对 `DispatcherServlet`源码的深入剖析,我们了解了SpringMVC请求处理的全流程。`DispatcherServlet`作为前端控制器,负责请求的接收和分发,处理器映射和适配负责将请求分派到具体的处理器方法,视图解析器负责生成和渲染视图。理解这些核心组件及其交互原理,有助于开发者更好地使用和扩展SpringMVC框架。
22 4
|
1月前
|
前端开发 Java 数据库
SpringBoot入门(3) - 对Hello world进行MVC分层
SpringBoot入门(3) - 对Hello world进行MVC分层
16 1
 SpringBoot入门(3) - 对Hello world进行MVC分层
|
17天前
|
Java 数据库连接 数据库
从入门到精通---深入剖析Spring DAO
在Java企业级开发中,Spring框架以其强大的功能和灵活性,成为众多开发者的首选。Spring DAO(Data Access Object)作为Spring框架中处理数据访问的重要模块,对JDBC进行了抽象封装,极大地简化了数据访问异常的处理,并能统一管理JDBC事务。本文将从概述、功能点、背景、业务点、底层原理等多个方面深入剖析Spring DAO,并通过多个Java示例展示其应用实践,同时指出对应实践的优缺点。
21 1
|
21天前
|
监控 Java 数据安全/隐私保护
如何用Spring Boot实现拦截器:从入门到实践
如何用Spring Boot实现拦截器:从入门到实践
38 5
|
22天前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
67 2
|
2月前
|
前端开发 Java 数据库
SpringBoot入门(3) - 对Hello world进行MVC分层
SpringBoot入门(3) - 对Hello world进行MVC分层
45 1
SpringBoot入门(3) - 对Hello world进行MVC分层
下一篇
DataWorks