请求响应:常见参数接收及封装(简单参数)

在客户端向服务端发起请求时,往往会携带各种相关的请求数据(比如在删除员工的时候需要携带员工的id),这些请求数据通过多种形式(如直接写在URL中的参数,请求体中的json数据等),在后端程序(controller层)需要将这些请求数据正确的接收并正确的封装使用。这些参数常见的有:简单参数、数组集合参数、日期参数、json参数、路径参数等,都需要用不同的方法进行获取。(以下演示代码,案例都基于SpringBoot框架)

简单参数的获取

原始方式

在原始的web程序中,获取请求参数,需要通过HttpServletRequest对象进行手动获取,假如说定义一个请求,请求参数有name和age,使用HttpServletRequest对象获取:

java 复制代码
@RequestMapping("/simple")
public String getSimpleParameter(HttpServletRequest httpServletRequest) {
    String name = httpServletRequest.getParameter("name");
    // 通过HttpServletRequest对象获取的请求参数都是String类型的,需要手动进行类型转换
    int age = Integer.parseInt(httpServletRequest.getParameter("age"));
    System.out.println("姓名是: " + name + "年龄是: " + age);
    return "hello " + name + age;
}

在客户端发起请求:

发现服务端通过原始方式,通过HTTPServletRequest对象手动获取参数,成功接收请求参数:

由此可以看见,获取简单参数还是比较简单的,但是既然都是SpringBoot项目了,那么还使用原始的方式未免有些过于"笨拙"了,可以通过SpringBoot框架的方法更加简单的获取简单请求参数。

框架提供的便捷方式

在SpringBoot框架中,想要接收请求携带的简单参数,只需要在controller方法中声明对应的形参即可接收到,但是需要特别提醒的是:形参名必须和请求参数名相同。 总结而言:通过SpringBoot框架接收请求中的简单参数,在方法声明中定义和请求中参数名相同的形参就可以接收参数。

java 复制代码
@RequestMapping("/simple")
public String getSimpleParameter(String name, int age) {
    System.out.println("姓名是: " + name + "年龄是: " + age);
    return "hello " + name + age;
}

可以发现并没有通过冗杂的HttpServletRequest类手动获取请求参数,只需要在Controller的方法声明和请求参数同名的形参,SpringBoot就可以让方法中的形参去自动接收请求中的简单参数,这十分的方便。

使用post请求方法也可以正确的接收到参数:

叛逆期

上文已经提及,如果想要通过SpringBoot框架成功接收到请求参数,那么就必须保证接收的方法中的形参和请求参数同名,但是假如说"叛逆期"到了,我就使用不同名的形参接收,那么还会成功接收到吗?我们将形参改为username再次启动服务:

java 复制代码
@RequestMapping("/simple")
public String getSimpleParameter(String username, int age) {
    System.out.println("姓名是: " + username + "年龄是: " + age);
    return "hello " + username + age;
}

发现若形参名和请求参数名字不同时,就无法接收到请求参数了,那么username这个形参自然也便是null了。但是参数不对应就一定无法接收成功吗》其实也未必,只是现在需要稍微麻烦一点,SpringBoot提供了@RequestParam注解,便于当方法形参名和请求参数名不匹配时,通过@RequestParam注解完成映射:通过注解中的name属性指定请求参数名即可 (注意:注解中的name属性必须和请求参数名完全一致了,否则真没办法接收了!)

java 复制代码
@RequestMapping("/simple")
public String getSimpleParameter(@RequestParam(name="name") String username, int age) {
    System.out.println("姓名是: " + username + "年龄是: " + age);
    return "hello " + username + age;
}

此时,虽然函数中的形参名和请求参数名无法对应,但是通过@RequestParam注解指定这个形参应该对应的请求参数名,从而完成映射:

此时,通过@RequestParam指定了形参应该对应的请求参数,从而成功接收到了请求参数;但是仍然是不建议这么使用的:首先是因为这样的方法不是那么的规范,其次,只要设置了@RequestParam注解的参数就必须要传递,否则将会报警告:

java 复制代码
2024-12-04T00:04:45.869+08:00  WARN 21552 --- 
[JavaWeb06_Develop] [nio-8080-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : 
Resolved [org.springframework.web.bind.MissingServletRequestParameterException: 
Required request parameter 'name' for method parameter type String is not present]

这个警告的意思是必须的请求参数"name"不存在。这个原因就是@RequestParam注解中有个属性------required,这个属性默认为true,表示这个参数必须要传递,所以说如果我们不传递该参数,就会报警告。可以将其设置为false,这样即使不传递该参数程序也可以正常运行。

java 复制代码
@RequestMapping("/simple")
public String getSimpleParameter(@RequestParam(name="name", required = false) String username, int age) {
    System.out.println("姓名是: " + username + "年龄是: " + age);
    return "hello " + username + age;
}

实体参数的获取

若只是传递几个请求参数,那么通过方法中的形参进行接收也罢了,但是假如有多个参数,再使用形参接收就有些冗杂了,而且接收到的参数使用起来也很不方便;对于这种情况,我们就可以定义简单的实体对象来进行接收:请求参数名和对象的属性名相同。

先定义实体类用于接收参数,实体类的属性必须和参数名相同:

java 复制代码
package com.wzb.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private int age;
}

发现确实通过实体对象接收到了多个请求参数。

复杂实体对象

假如请求参数是一个复杂的实体对象,比如说User对象中有个属性Address,Address属性是一个对象,其中又有属性province和city,那么此时只需要保证请求参数名和形参对象属性名相同,然后按照对象的层次结构关系即可接收嵌套的pojo属性参数。

java 复制代码
@RequestMapping("/complexPojo")
public String getComplexParameter(TestUser user) {
    String name = user.getName();
    int age = user.getAge();
    Address address = user.getAddress();
    System.out.println("姓名是: " + name + "年龄是: " + age + "地址是: " + address.getProvince() + " " + address.getCity());
    System.out.println(user);
    return "hello " + name + age + address;
}

请求路径,及其请求参数封装:

发现只要按照对象的层次机构关系,即可接收到嵌套的pojo属性:

相关推荐
code喵喵25 分钟前
系统性能优化
java·性能优化·压力测试
-self-disciplinese25 分钟前
从零开始学Java,学习笔记Day22
java·笔记·后端·学习
m0_748236832 小时前
Spring Boot日志:从Logger到@Slf4j的探秘
java·spring boot·spring
芒果爱编程3 小时前
MCU、ARM体系结构,单片机基础,单片机操作
开发语言·网络·c++·tcp/ip·算法
明明跟你说过3 小时前
【Go语言】从Google实验室走向全球的编程新星
开发语言·后端·go·go1.19
码字哥4 小时前
EasyExcel设置表头上面的那种大标题(前端传递来的大标题)
java·服务器·前端
凌盛羽4 小时前
C#对Excel表csv文件的读写操作
开发语言·windows·物联网·microsoft·c#·excel
VBA63374 小时前
VBA高级应用30例应用在Excel中的ListObject对象:向表中添加注释
开发语言
Dontla4 小时前
Rust字节数组(Byte Array)Rust u8、Vec<u8>、数组切片、向量切片、字符串转字节数组转字符串、&[u8]类型:字节数组引用
开发语言·rust
走在考研路上6 小时前
Python错误处理
开发语言·python