当前位置: 首页 > article >正文

请求响应入门

请求响应

一、请求响应流程

在这里插入图片描述

请求响应的步骤:

  1. 启动内嵌的Tomcat服务器
  2. 打开浏览器,并通过访问路径,就可以访问到我们部署在Tomcat当中的应用程序了
  3. Controller接收到请求之后,会对请求进行处理,处理完毕之后,再给浏览器响应对应的结果(请求和响应都要遵循HTTP协议)

注意事项

  • Tomcat不能识别我们编写的Controller程序,但它是识别一项Java EE规范里的技术的Servlet容器
  • 而基于Spring boot开发的web程序中,Spring boot 底层给我们提供了一个非常核心的servlet程序——DispatcherServlet前端控制器),有了它,前端浏览器发起的请求都会先经过DispatcherServlet,它会将解析后的所有信息封装到一个对象中——HttpServletRequest,由这个对象转给后面的各个Controller程序,由这些Controller程序再对请求进行处理,处理完毕,再将处理完的结果返回给DispatcherServlet程序,再根据另外一个对象来响应数据——HttpServletResponse,之后再给浏览器响应数据

在这里插入图片描述

二、请求响应介绍和架构

  • 请求(HttpServletRequest):获取请求数据
  • 响应(HttpServletResponse):设置响应数据
  • BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端(以上就是一个标准的BS架构,类似于网页)
    • 维护方便,但体验一般
  • CS架构:Client/Server,客户端/服务器架构模式(类似于APP)
    • 开发、维护麻烦,但体验不错

三、请求

  • 由于后端开发时,每开发完一个功能就需要去测试,可能会去从浏览器的地址栏直接输入这样一个地址,这样就可以访问到开发的web应用了,但是由地址栏发起的请求全部都是GET请求,无法测试POST请求,这时候可能需要自己编写前端的代码,然后再来进行后端的功能接口测试——此时我们可以借助一款功能强大的接口测试工具——postman

Postman

  • Postman一款功能强大的网页调试与发送网页HTTP请求的chrome插件
  • 作用:常用于进行接口测试

模拟页面发送各种请求

1、模拟GET请求

在这里插入图片描述
GET请求加上后缀?参数名1=参数1&参数名2=参数2,下面的数据也会自动生成

在这里插入图片描述

2、模拟POST请求

在这里插入图片描述

选择POST请求后,输入这个请求的网址,并在Bodyx-www-form-urlencoded中自己写入想要传递的数据

1、简单参数

1.1 原始方式
  • 在原始的web程序中,获取请求参数,需要通过HttpServletRequest对象手动获取。

在Controller对象中编写以下程序:

// 测试请求参数
@RestController
public class RequestController {
    
    // 原始方式
    @RequestMapping("/simpleParam")
	public String simpleParam(HttpServletRequest request) {
		// 获取请求数据       
    	String name = request.getParameter("name");
    	String ageStr = request.getParameter("age");
    	int age = Integer.parseInt(ageStr);
    	System.out.println(name + ":" + age);
    	return "OK";
}
}

此时运行这个springboot项目,即会占用系统的8080端口,我们就可以用Postman去模拟浏览器测试发送请求

在这里插入图片描述

点击send方法,可以看到返回OK,在后端代码中可以看到

在这里插入图片描述

返回了请求时路径的值。

  • 但这种方法获取数据过于繁琐,且需要手动的类型转换
1.2 Springboot方式
  • 简单参数:参数名与形参变量名相同,定义形参即可接收参数。

  • 也就是说,只要前端的请求参数名与形参的变量名保持一致即可接收成功,而且在接收到的过程中会进行自动的类型转换

// 测试请求参数
@RestController
public class RequestController {
    
    // Springboot方式
    @RequestMapping("/simpleParam")
	public String simpleParam(String name, Integer age) {
    	System.out.println(name + ":" + age);
    	return "OK";
}
}

运行结果和上述一样

注意事项

  • 如果形参名与前端的请求参数名不一致时,可以使用@RequestParam完成映射。

代码可以修改为:

// 测试请求参数
@RestController
public class RequestController {
    
    // Springboot方式
    @RequestMapping("/simpleParam")
	public String simpleParam(@RequestParam(name = "name") String username, Integer age) {
    	System.out.println(username + ":" + age);
    	return "OK";
}
}
  • 映射@RequestParam(name/value = "请求参数名")
    • @RequestParam中的required属性默认为true,代表该请求参数必须传递,如果不传递将会报错。因此如果请求参数中没有这个值时,就会报错;但可以修改一下required的值,没有也不会报错,有了也可以正常使用

改变required的值:

// 测试请求参数
@RestController
public class RequestController {
    
    // Springboot方式
    @RequestMapping("/simpleParam")
	public String simpleParam(@RequestParam(name = "name", required = false) String username, Integer age) {
    	System.out.println(username + ":" + age);
    	return "OK";
}
}

这样不论有没有这个请求参数,请求都能正常执行!

2、实体参数

前提背景

​ 在简单参数接收中,前端传递了多少个请求参数,我们就需要在方法中声明多少个形参来接收,如果前端要传递的请求参数过多时,就不便于使用简单参数这种方式进行接收,这时候就需要将所有的实体对象都封装到一个实体类当中

  • 简单实体对象:请求参数名与形参属性名相同,定义POJO接收即可

  • 要想成功的封装,就要遵循一个原则需要让请求的参数名与实体类的属性名保持一致。

2.1简单实体参数

在这里插入图片描述

我们可以使用请求的参数名,将他们都封装到一个实体类当中

  • 创建一个pojo包,专门存放实体类
package com.springboot.springboot_webdemo02.pojo;

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中写上:

@RestController
public class RequestController {
    // 简单实体对象
    @RequestMapping("/simplePojo")
    public String simplepojo(User user) {
        System.out.println(user);
        return "OK";
    }
}

此时点击Send发送:

在这里插入图片描述

在这里插入图片描述

请求成功!


2.2复杂实体参数

在这里插入图片描述

根据请求参数可知,需要创建Address

  • Pojo包中创建Address
package com.springboot.springboot_webdemo02.pojo;

public class Address {
    private String province;
    private String city;

    @Override
    public String toString() {
        return "Address{" +
                "province='" + province + '\'' +
                ", city='" + 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;
    }
}

修改User类中的代码:

package com.springboot.springboot_webdemo02.pojo;

public class User {
    private String name;
    private Integer age;
    private 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 Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                '}';
    }
}

然后可以在Controller中写上:

@RestController
public class RequestController {
    // 简单实体对象
    @RequestMapping("/simplePojo")
    public String simplepojo(User user) {
        System.out.println(user);
        return "OK";
    }
    
    // 复杂实体对象
    @RequestMapping("/complexPojo")
    public String complexpojo(User user) {
        System.out.println(user);
        return "OK";
    }
}

此时点击Send发送后:

在这里插入图片描述

在这里插入图片描述

请求成功!


3、数组参数

  • 当用户填的表单为多选时,返回的参数就是以数组的形式进行传输的

在这里插入图片描述

然后可以在Controller中加上:

// 数组集合参数
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby) {
    System.out.println(Arrays.toString(hobby));
    rerurn "OK";
}

此时点击Send发送后:

在这里插入图片描述

在这里插入图片描述

数据请求成功!


4、集合参数

  • 也可以将多选的值放进集合里
  • 集合参数:请求参数名与形参集合名称相同且请求参数为多个,@RequestParam绑定参数关系

在这里插入图片描述

然后可以在Controller中加上:

@RequestMapping("/listParam")
public String listParam(@RequestParam List<String> hobby) {
    System.out.println(hobby);
    return "OK";
}

此时点击Send发送后:

在这里插入图片描述

在这里插入图片描述

数组集合参数

  • 数组:请求参数名与形参中数组变量名相同,可以直接使用数组进行封装
  • 集合:请求参数名与形参中集合变量名相同,通过@RequestParam绑定参数关系

5、日期参数

  • 在项目的前端表单页面,我们经常会遇到一些日期时间类参数,这时候就需要将其封装起来
  • 日期参数:使用==@DateTimeFormat==注解完成日期参数格式转换(指定日期传递的格式)

在这里插入图片描述

然后可以在Controller中加上:

// 日期时间参数
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat(pattern = "yyyy:MM:dd HH:mm:ss")LocalDateTime updateTime) {
    System.out.println(updateTime);
    return "OK";
}

此时点击Send发送后:

在这里插入图片描述

在这里插入图片描述

请求成功!


6、json参数

  • 发送一个请求并且传递json格式的请求数据,需要将请求数据设置为POST,因为json格式的数据是需要方法请求体当中携带到服务端的
  • JSON参数:JSON数据键名与形参对象属性名相同,定义POJO类型形参即可接收参数,需要使用==@RequestBody==标识(将JSON格式的数据封装到一个实体对象当中)

POST请求:
在这里插入图片描述

然后可以在Controller中加上:

// json参数
@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user) {
    System.out.println(user);
    return "OK";
}
  • UserAddress是上面出现过的类

此时点击Send发送后:

在这里插入图片描述

在这里插入图片描述

7、路径参数

  • 路径参数:通过请求URL直接传递参数,使用{…}来标识该路径参数,需要使用==@PathVariable==获取路径参数(将路径参数绑定为后面的形参)

在这里插入图片描述

然后可以在Controller中加上:

@RequestMapping("/path/{id}")
public String pathParam(@PathVariable Integer id) {
    System.out.println(id);
    return "OK";
}

此时点击Send发送后:

在这里插入图片描述
在这里插入图片描述

  • 也可以改变路径参数,都可以获取到!

也可以同时传递多个请求参数:

在这里插入图片描述

然后可以在Controller中变成:

@RequestMapping("/path/{id}/{name}")
    public String pathParam(@PathVariable Integer id, @PathVariable String name) {
        System.out.println(id + ":" + name);
        return "OK";
    }

发送后即可看见:

在这里插入图片描述

总结

在这里插入图片描述


四、响应

  • 其实上面的Controller方法中,都已经设置了响应数据return值作为了返回数据,返回给了客户端浏览器,都依赖于一个核心的注解==@ResponseBody==
  • @ResponseBody
    • 类型:方法注解,类注解
    • 位置:Controller方法上/Controller的类上
    • 作用:将方法返回值直接响应,如果返回值类型是实体对象/集合,将会转换为JSON格式响应
    • 说明:@ResrController = @Controller + @ResponseBody(所以上面可以直接通过返回值响应数据给客户端服务器)

1、响应-字符串

  • 可以再定义一个类,专门用于存放ResponseController,并使用@RestController注解

在这个类ResponseController中加入:

@RequestMapping("/hello")
    public String hello() {
        System.out.println("Hello World!");
        return "Hello World!";
    }

在这里插入图片描述

发送后即可看见:

在这里插入图片描述

在这里插入图片描述

2、响应-对象json

请求可以写:(换个路径即可)

在这里插入图片描述

在这个类ResponseController中加入:

@RequestMapping("/getAddr")
    public Address getArr() {
        Address addre = new Address();
        addre.setProvince("山西");
        addre.setCity("运城");
        return addre;
    }

发送后即可看见:

在这里插入图片描述

3、响应-集合json

请求也是换个自定义路径http://localhost:8080/listAddr即可

在这个类ResponseController中加入:

@RequestMapping("/listAddr")
    public List<Address> listAddr() {
        List<Address> list = new ArrayList<>();

        Address addr = new Address();
        addr.setProvince("山西");
        addr.setCity("运城");
        list.add(addr);

        Address address = new Address();
        address.setProvince("北京");
        address.setCity("北京");
        list.add(address);

        return list;
    }

发送后即可看见:

在这里插入图片描述

4、统一响应结果

​ 以上的三种响应方式都不一样,前端需要分情况解析,当开发大型项目时,这样将会不便管理,且难以维护;所以在实际开发当中,我们都会给所以得功能接口(一个响应方法就是一个功能接口)设置一个统一的响应结果

  • 统一响应结果:设置一个实体对象Result来接收

在这里插入图片描述

Result对象的构建

pojo包中创建一个Result

public class Result {
    private Integer code; // 1-成功 0-失败
    private String msg; // 提示信息
    private Object data; // 数据 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(Object data) {
        return new Result(1, "success", data);
    }

    public static Result success() {
        return new Result(1, "success", null);
    }

    public static Result error(String msg) {
        return new Result(0, msg, null);
    }

    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}

ResponseController类中的功能接口进行改造:

@RequestMapping("/hello")
    public Result hello() {
        System.out.println("Hello World!");
        return Result.success("Hello World!");
    }

    @RequestMapping("/getAddr")
    public Result getArr() {
        Address addre = new Address();
        addre.setProvince("山西");
        addre.setCity("运城");
        return Result.success(addre);
    }

    @RequestMapping("/listAddr")
    public Result listAddr() {
        List<Address> list = new ArrayList<>();

        Address addr = new Address();
        addr.setProvince("山西");
        addr.setCity("运城");
        list.add(addr);

        Address address = new Address();
        address.setProvince("北京");
        address.setCity("北京");
        list.add(address);

        return Result.success(list);
    }

此时发送可以看见:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

都变成了统一的JSON格式!

拓展:

  • Springboot项目的静态资源(html,css,js等前端资源)默认存放目录为classpath:/static、classpath:/public、classpath:/resources(对于Maven项目来说:resources目录就是一个内路径(相当于classpath))——一般直接放在resources目录下的static目录下即可。

http://www.kler.cn/a/400441.html

相关文章:

  • Isaac Sim+SKRL机器人并行强化学习
  • 三维测量与建模笔记 - 点特征提取 - 4.3 Harris特征点
  • 鸿蒙实现 web 传值
  • Nginx server_name配置错误导致路由upstream超时问题
  • 【STL】set,multiset,map,multimap的介绍以及使用
  • SpringBoot使用AspectJ的@Around注解实现AOP全局记录接口:请求日志、响应日志、异常日志
  • element ui table进行相同数据合并单元格
  • Web搭建入门教程:基于ssh向服务器推送文件
  • 了解存储过程
  • c#————委托Action使用例子
  • 【泛型 Plus】Kotlin 的加强版类型推断:@BuilderInference
  • LM2 : A Simple Society of Language Models Solves Complex Reasoning
  • MyBatis XML一个方法执行插入或更新操做(PostgreSQL)
  • Java Collection的使用
  • Jaskson处理复杂的泛型对象
  • (Linux 入门) 基本指令、基本权限
  • 动态规划 之 子序列系列 算法专题
  • 脚手架vue-cli,webpack模板
  • 资源管理功能拆解——如何高效配置和管理项目资源?
  • 高斯数据库Postgresql死锁和锁表解决方法
  • MATLAB深度学习(三)——LeNet卷积神经网络
  • 独立站干货:WordPress主机推荐
  • Python高级编程模式和设计模式
  • CTF攻防世界小白刷题自学笔记14
  • Flink算子
  • Vue 3 中 ref 属性详解:操作 DOM 元素的利器