一、Postman
1. 使用教程
(1) 登录完成之后,可以创建工作空间:



(2) 创建请求:

点击"Save",保存当前请求


2. 简单参数
(1) 原始方式
① 在原始的Web程序当中,需要通过Servlet中提供的API:HttpServletRequest(请求对象),获取请求的相关信息。比如获取请求参数:
② 在Controller中,我们要想获取Request对象,可以直接在方法的形参中声明 HttpServletRequest 对象。然后就可以通过该对象来获取请求信息:
java
//根据指定的参数名获取请求参数的数据值
String request.getParameter("参数名")
java
@RestController
public class RequestController {
//原始方式
@RequestMapping("/simpleParam")
public String simpleParam(HttpServletRequest request){
// http://localhost:8080/simpleParam?name=Tom&age=10
// 请求参数: name=Tom&age=10 (有2个请求参数)
// 第1个请求参数: name=Tom 参数名:name,参数值:Tom
// 第2个请求参数: age=10 参数名:age , 参数值:10
String name = request.getParameter("name");//name就是请求参数名
String ageStr = request.getParameter("age");//age就是请求参数名
int age = Integer.parseInt(ageStr);//需要手动进行类型转换
System.out.println(name+" : "+age);
return "OK";
}
}
以上这种方式,我们仅做了解。(在以后的开发中不会使用到)
(2)SpringBoot方式(推荐)
在Springboot的环境中,对原始的API进行了封装,接收参数的形式更加简单。 如果是简单参数,参数名与形参变量名相同,定义同名的形参即可接收参数。
java
@RestController
public class RequestController {
// http://localhost:8080/simpleParam?name=Tom&age=10
// 第1个请求参数: name=Tom 参数名:name,参数值:Tom
// 第2个请求参数: age=10 参数名:age , 参数值:10
//springboot方式
@RequestMapping("/simpleParam")
public String simpleParam(String name , Integer age ){//形参名和请求参数名保持一致
System.out.println(name+" : "+age);
return "OK";
}
}
postman测试( GET 请求)

postman测试( POST请求 ):

结论:不论是GET请求还是POST请求,对于简单参数来讲,只要保证请求参数名和Controller方法中的形参名保持一致,就可以获取到请求参数中的数据值。
(3) 参数名不一致
① 如果方法形参名称与请求参数名称不一致,controller方法中的形参还能接收到请求参数值吗?
java
@RestController
public class RequestController {
// http://localhost:8080/simpleParam?name=Tom&age=20
// 请求参数名:name
//springboot方式
@RequestMapping("/simpleParam")
public String simpleParam(String username , Integer age ){//请求参数名和形参名不相同
System.out.println(username+" : "+age);
return "OK";
}
}
答案:运行没有报错。 controller方法中的username值为:null,age值为20
② 那么如果我们开发中,遇到了这种请求参数名和controller方法中的形参名不相同,怎么办?
解决方案:可以使用Spring提供的@RequestParam注解完成映射
java
@RestController
public class RequestController {
// http://localhost:8080/simpleParam?name=Tom&age=20
// 请求参数名:name
//springboot方式
@RequestMapping("/simpleParam")
public String simpleParam(@RequestParam("name") String username , Integer age ){
System.out.println(username+" : "+age);
return "OK";
}
}
Q:
@RequestParam到底在干嘛?A:简单来说,
@RequestParam就是 Spring Boot 用来把「URL 请求参数」和「方法形参」绑定起来的工具。
- 你的 URL 里的参数名是
name,但方法里的变量名是username,名字不一样。- 这时候必须用
@RequestParam("name")告诉 Spring:"把 URL 里name参数的值,赋值给方法里的username变量。"
3. 实体参数
(1) 简单实体对象
① 定义 Pojo 实体类:
java
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
② Controller方法:
java
@RestController
public class RequestController {
//实体参数:简单实体对象
@RequestMapping("/simplePojo")
public String simplePojo(User user){
System.out.println(user);
return "OK";
}
}
(2) 复杂实体对象
① 复杂实体对象指的是,在实体类中有一个或多个属性,也是实体对象类型的。如下:
- User类中有一个Address类型的属性(Address是一个实体类)

② 代码演示:
- Address实体类
java
public class Address {
private String province;
private String city;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
'}';
}
}
- User实体类
java
public class User {
private String name;
private Integer age;
private Address address; //地址对象
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}
(3) 数组集合参数
① 使用场景
数组集合参数的使用场景:在HTML的表单中,有一个表单项是支持多选的(复选框),可以提交选择的多个值。

② 数组参数
1). 请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数

2). 代码演示
Controller方法:
java
@RestController
public class RequestController {
//数组集合参数
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby){
System.out.println(Arrays.toString(hobby));
return "OK";
}
}
③ 集合参数
1). 请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam 绑定参数关系
默认情况下,请求中参数名相同的多个值,是封装到数组。如果要封装到集合,要使用@RequestParam绑定参数关系

2). 代码演示
java
@RestController
public class RequestController {
//数组集合参数
@RequestMapping("/listParam")
public String listParam(@RequestParam List<String> hobby){
System.out.println(hobby);
return "OK";
}
}
(4) 日期参数
① 使用场景
因为日期的格式多种多样(如:2022-12-12 10:05:45 、2022/12/12 10:05:45),那么对于日期类型的参数在进行封装的时候,需要通过@DateTimeFormat注解,以及其pattern属性来设置日期的格式。

-
@DateTimeFormat注解的pattern属性中指定了哪种日期格式,前端的日期参数就必须按照指定的格式传递。
-
后端controller方法中,需要使用Date类型或LocalDateTime类型,来封装传递的参数。
② 代码演示
java
@RestController
public class RequestController {
//日期时间参数
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){
System.out.println(updateTime);
return "OK";
}
}
(5) JSON参数
① Postman发送JSON格式数据:

② 服务端Controller方法接收JSON格式数据:
-
传递json格式的参数,在Controller中会使用实体类进行封装。
-
封装规则:JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数。需要使用 @RequestBody标识。
Q:什么是POJO类型形参?
A: POJO 全称是 Plain Old Java Object ,翻译过来就是「普通的 Java 对象」。它没有继承任何特殊类、也没有实现任何特殊接口,唯一的作用就是封装数据。简单来说,你可以把它理解成一个 "数据容器",专门用来存放前端传递过来的 JSON 数据。

③ 代码演示
Controller方法:
java
@RestController
public class RequestController {
//JSON参数
@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user){
System.out.println(user);
return "OK";
}
}
(6) 路径参数
① 路径参数
-
前端:通过请求URL直接传递参数
-
后端:使用{...}来标识该路径参数,需要使用@PathVariable获取路径参数

② 代码演示
java
@RestController
public class RequestController {
//路径参数
@RequestMapping("/path/{id}")
public String pathParam(@PathVariable Integer id){
System.out.println(id);
return "OK";
}
}
二、响应
1. @ResponseBody
(1) @ResponseBody注解:
① 类型:方法注解、类注解
② 位置:书写在Controller方法上或类上
③ 作用:将方法返回值直接响应给浏览器
- 如果返回值类型是实体对象/集合,将会转换为JSON格式后在响应给浏览器
(2) 但是在我们所书写的Controller中,只在类上添加了@RestController注解、方法添加了@RequestMapping注解,并没有使用@ResponseBody注解,怎么给浏览器响应呢?
java
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
System.out.println("Hello World ~");
return "Hello World ~";
}
}
原因:在类上添加的@RestController注解,是一个组合注解。
- @RestController = @Controller + @ResponseBody
2. 统一响应结果

(1) 统一的返回结果使用类来描述,在这个结果中包含:
-
响应状态码:当前请求是成功,还是失败
-
状态码信息:给页面的提示信息
-
返回的数据:给前端响应的数据(字符串、对象、集合)
(2) 代码演示
① 定义在一个实体类Result来包含以上信息。代码如下:
java
public class Result {
private Integer code;//响应码,1 代表成功; 0 代表失败
private String msg; //响应码 描述字符串
private Object data; //返回的数据
public Result() { }
public Result(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
//增删改 成功响应(不需要给前端返回数据)
public static Result success(){
return new Result(1,"success",null);
}
//查询 成功响应(把查询结果做为返回数据响应给前端)
public static Result success(Object data){
return new Result(1,"success",data);
}
//失败响应
public static Result error(String msg){
return new Result(0,msg,null);
}
}
② 改造Controller:
java
@RestController
public class ResponseController {
//响应统一格式的结果
@RequestMapping("/hello")
public Result hello(){
System.out.println("Hello World ~");
//return new Result(1,"success","Hello World ~");
return Result.success("Hello World ~");
}
//响应统一格式的结果
@RequestMapping("/getAddr")
public Result getAddr(){
Address addr = new Address();
addr.setProvince("广东");
addr.setCity("深圳");
return Result.success(addr);
}
//响应统一格式的结果
@RequestMapping("/listAddr")
public Result listAddr(){
List<Address> list = new ArrayList<>();
Address addr = new Address();
addr.setProvince("广东");
addr.setCity("深圳");
Address addr2 = new Address();
addr2.setProvince("陕西");
addr2.setCity("西安");
list.add(addr);
list.add(addr2);
return Result.success(list);
}
}
三、案例
1. 需求说明
需求:加载并解析xml文件中的数据,完成数据处理,并在页面展示

2. 准备工作
(1) 前端页面资源
- 已经准备好,直接拷贝进来,放在src/main/resources下的static目录下
(2) Springboot项目的静态资源(html,css,js等前端资源)默认存放目录为:classpath:/static 、 classpath:/public、 classpath:/resources
- classpath:代表的是类路径,在maven的项目中,其实指的就是 src/main/resources 或者 src/main/java,但是java目录是存放java代码的,所以相关的配置文件及静态资源文档,就放在 src/main/resources下。
3. 代码实现
java
@RestController
public class EmpController {
@RequestMapping("/listEmp")
public Result list(){
//1. 加载并解析emp.xml
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
//System.out.println(file);
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
//2. 对数据进行转换处理 - gender, job
empList.stream().forEach(emp -> {
//处理 gender 1: 男, 2: 女
String gender = emp.getGender();
if("1".equals(gender)){
emp.setGender("男");
}else if("2".equals(gender)){
emp.setGender("女");
}
//处理job - 1: 讲师, 2: 班主任 , 3: 就业指导
String job = emp.getJob();
if("1".equals(job)){
emp.setJob("讲师");
}else if("2".equals(job)){
emp.setJob("班主任");
}else if("3".equals(job)){
emp.setJob("就业指导");
}
});
//3. 响应数据
return Result.success(empList);
}
}
核心逻辑:
① String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
|---------------------------|---------------------|--------------------------------------------------------------------------------------------------------------------------------------|
| 代码片段 | 核心作用 | 大白话解释 |
| this.getClass() | 获取当前类的Class对象 | 拿到 EmpController 这个类的"身份证",通过它能找到加载这个类的"工具"。 |
| .getClassLoader() | 获取类加载器(ClassLoader) | 类加载器是JVM的"资源查找工具",它默认会去 target/classes 目录(Maven编译后,resources 里的文件会复制到这里)找资源文件。 |
| .getResource("emp.xml") | 从类路径根目录找文件 | 告诉类加载器:"去你的默认查找目录(classpath根)里找名为 emp.xml 的文件",返回一个 URL 对象(包含文件的位置信息)。<br>⚠️ 这里不用加 /,因为 resources 编译后就是类路径(classpath)的根目录。 |
| .getFile() | 把URL转成绝对路径字符串 | 把 URL 对象(比如 file:/D:/JavaWeb/demo/target/classes/emp.xml)转换成普通的文件路径字符串,方便后续XML解析工具读取文件。 |
② Stream流
java
// 流式遍历
empList.stream().forEach(emp -> {
// 处理 gender 和 job 的逻辑(和上面完全一样)
String gender = emp.getGender();
if("1".equals(gender)){
emp.setGender("男");
}else if("2".equals(gender)){
emp.setGender("女");
}
String job = emp.getJob();
if("1".equals(job)){
emp.setJob("讲师");
}else if("2".equals(job)){
emp.setJob("班主任");
}else if("3".equals(job)){
emp.setJob("就业指导");
}
});
**Q1:**为什么是 emp ->
A1:
①
emp ->是 Java 8 推出的 Lambda 表达式 语法,在你的代码里,它的作用是:"把遍历到的每一个
Emp类型的对象,用emp这个变量名来代表,然后把这个emp传递给后面{}里的代码块去处理。"② 简单说:
emp就是遍历过程中 "当前那一个员工对象" 的名字,->是 "把这个对象交给后面处理" 的分隔符。
**Q2:**为什么要使用 stream()A2:
不用 stream ()(传统 for 循环写法)
java// 传统 for 循环遍历 for (int i = 0; i < empList.size(); i++) { Emp emp = empList.get(i); // 处理 gender String gender = emp.getGender(); if("1".equals(gender)){ emp.setGender("男"); }else if("2".equals(gender)){ emp.setGender("女"); } // 处理 job String job = emp.getJob(); if("1".equals(job)){ emp.setJob("讲师"); }else if("2".equals(job)){ emp.setJob("班主任"); }else if("3".equals(job)){ emp.setJob("就业指导"); } }① 代码更简洁,少写 "模板代码"
传统 for 循环需要写
int i=0; i<empList.size(); i++和empList.get(i)这些 "遍历的模板代码",而stream().forEach()直接聚焦 "对每个 emp 对象做什么",不用关心 "怎么遍历"------ 把注意力放在数据处理逻辑 (改 gender、job),而非遍历的过程。② 可读性更高(语义化)
empList.stream().forEach(emp -> { ... })读起来就像 "把 empList 转成流,对每个 emp 执行下面的操作",语义更直观,新手也能一眼看懂 "这是遍历每个员工并处理数据"。
四、如何搜索CSDN编写文章内容的关键字
- 从当前页面点击右上角的头像 → 选择「我的主页」
- 进入个人博客主页后,在顶部的搜索框(一般在头像下方 / 页面顶部)输入关键字
- 按回车,结果会显示你的文章列表,每条结果会高亮关键字在正文中的位置,并展示正文片段,不用点开就知道内容是否匹配。
