接下来详细的学习web开发中的请求响应

我们之前所编写的springbootweb程序,我们仅仅是通过一个简单的java程序来编写,没有实现接口也没有继承任何的类,这种程序,Tomcat其实是不识别的,而对于Tomcat我们都知道它也被称为servlet容器,我们采用springboot开发的web程序它底层给我们提供了一个servlet容器(DispatcherServlet容器)-----核心控制器(前端控制器)

而Dispatcher容器他实现了servlet的接口,当前端浏览器请求数据的时候,都要先经过DispatcherServlet,然后将请求放置到各个controller中进行处理,再将处理好的数据返回给servlet,最后返回给前端浏览器,实现请求响应。
那么对于servlet容器,他接收数据通过web服务器进行解析http协议,那么也就是结果tomcat将协议解析完成,然后Tomcat将浏览器的请求数据封装打包成一个对象,也就是HttpServletRequest,将响应的数据也封装成一个对象,叫做HttpServletResponse

一般的浏览器与服务器间的这种请求响应模式,都是通过BS架构进行的,BS架构指的就是 browser和sever(浏览器和服务器),这种架构方式维护很方便,只需要将浏览器进行维护就可以,但是用户体验就很一般。有很多的平台比如淘宝、京东之类都是将应用程序的逻辑和数据存储在浏览器中。当然很像之前所学习的CS架构,也就是client和sever(客户端和服务器),这种架构方式维护开发都很困难,但是用户的体验就很好,一般像我们经常使用的微信QQ之类的客户端访问软件。

目前我们的开发都是前后端分离开发,那么我们对一个项目进行开发时,我们没有前端页面去测试我们的后端代码,一般对于get请求可以直接向浏览器来访问,都是对于post请求,我们就无法实现了,那么我们只能借助接口工具,一般都是postman,现在国内也有apifox都可以进行。
PS:在发送请求前要先启动springboot的启动类

一、请求
简单参数
对于简单参数,用一般的web开发时,需要通过HttpServletRequest对象手动获取,所以很麻烦,而且对于参数还要进行手动的类型转换,很繁琐

那么对于使用springboot的web开发时,我们只需要在controller中声明对应的形参就可以接收相应的参数,并且可以进行自动类型转换,当然在请求方式后的参数名称需要和形参设置的变量名保持一致,这样才可以成功接收

那么如果方法形参名与请求参数名不匹配,该怎么办呢?

我们可以使用@RequestParam,它的required属性默认是true,所以使用了@RequestParam那么后面接收的参数必须要接收的到,比如
public String simpleParam(RequestParam(value/name = "请求参数名") String 形参名称)
默认的required为true,说明此变量是必须的,若其中的参数名不是必须的,可以使用required将其设置为false,就不会报错了。如
public String simpleParam(RequestParam(value/name = "请求参数名", required = false) String 形参名称)

实体参数
在我们开发时,前端给我们传递的参数若太多的话,不利于我们的维护,我们就可以考虑将这些参数封装到一个实体类当中
对于简单的实体参数,可以将URL后面的变量封装成一个类,方便我们的使用

定义一个简单实体参数类
@RequestMapping("/simplePojo")
public String simplePojo(User user){
System.out.println(user);
return "OK";
}
将User中的参数进行封装
public class User {
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;
}
private String name;
private Integer age;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
运行我们的springboot启动项,localhost为8080端口

打开我们的apifox进行接口调试

最后输出OK与我们代码逻辑一致,调试成功了
复杂的实体参数,我们看封装类中是否还有属性,比如address中还有province和city,那么我们就需要继续封装这两个类将他们放在一个包下,在user包中调用这三个参数,以及参数的属性即可。

那么复杂的实体参数与简单的也差不多,只需要注意将参数的属性再封装一次即可
创建复杂实体参数类
@RequestMapping("/complexPojo")
public String complexPojo(User user){
System.out.println(user);
return "OK";
}
封装我们的Address,封装好后再封装到User中,private Address address
public class Address {
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;
}
private String province;
private String city;
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
'}';
}
}
其余步骤同simplePojo,最后发现我们的结果预期也一致


数组集合参数
对于请求参数与形参数组名称相同且请求参数为多个的,我们可以定义成数组类型接收,比如下图中的hobby为多个参数,我们可以直接将hobby定义为数组直接接收多个。

直接进入coding
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby){
System.out.println(Arrays.toString(hobby));
return "OK";
最后也是没有任何问题


那么集合数据也就是同理了,不过需要使用@RequestParam来绑定我们集合参数的关系,或者将数组封装成一个类,也可以创建一个对象来进行此操作

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


日期参数
通常我们也会见到含有日期的URL,所以对于日期参数,我们用@DateTimeFormat来注解完成日期参数的格式转换,比如yyyy-MM-dd HH:mm:ss;

编写格式eg:
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat (pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime) {
System.out.println(updateTime);
return "OK";
}


json参数
json参数,在post时对各个参数都要加双引号,且用@RequestBody标识json参数

coding一下,注意格式
@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user) {
System.out.println(user);
return "OK";
}
package com.itxt.controller.pojo;
public class User {
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;
}
private Address address;
private String name;
private Integer age;
@Override
public String toString() {
return "User{" +
"address=" + address +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
post接收数据成功


路径参数
对于路径参数,可以通过请求URL传递参数,用大括号{}标记比如{id},{name},需要使用@PathVariable获取路径参数,可以同时接收多个路径参数,只需要在一个路径参数后加 / 再传入一个路径参数即可,比如{id}/{name}

那么直接编写代码来接收路径参数,这里用了两个路径参数,一个id一个name,通过get来接收一下,看看服务端接收数据是否一致
@RequestMapping("/path/{id}/{name}")
public String pathParam(@PathVariable Integer id,@PathVariable String name) {
System.out.println(id);
System.out.println(name);
return "OK";
}
可以看到通过get传入两个路径参数,一个629一个xt。


发现接收的路径参数与get所发送的参数一致, 那么我们的路径参数也接收成功了
请求数据总结
对以上所学习的内容小结,可以通过实践来记忆这些编写格式
@RequestParam 当简单参数的请求参数与方法形参不一致时可以手动进行映射
@RequestParam 对集合的绑定格式
@DateTimeFormat 日期参数绑定格式
@RequestBody json参数绑定格式
@PathVariable 路径参数绑定格式

二、响应
接下来我们来学习数据的响应,也就是服务端将数据响应给客户端浏览器
我们之前对于响应的数据已经有了说明,也就是我们加在类前的@RestController,他已经涵盖了响应数据的注解,响应数据为@ResponseBody,之前我们通过@RestController将向浏览器响应的数据return了回去,如果是对象或者集合,它都会先将这些转为json然后返回
其中这些响应的方法都称为一个功能接口,里面的路径就是这个功能接口的访问路径

但是在我们编写响应方法的时候,由于各种方法所传回的类型不同,有对象,有字符串还有列表等等,前端人员的解析工作就会大大增加,所以为了方便管理维护,我们给所有的功能接口都设置一个统一的响应结果,满足所有的功能场景,我们就可以设计一个实体对象Result来接收

然后result对象通过响应注释@ResponseBody将数据解析为json文件,前端就收到了统一的格式,响应码、提示信息、返回的数据
那么我们直接来编写一个Result对象,以及响应数据类ResponseController
public class Result {
private Integer code;
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(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,"error",null);
}
@Override
public String toString() {
return "Result{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
@RestController
public class ResponseController {
@RequestMapping("/hello")
public Result hello(){
System.out.println("Hello World");
return Result.success("Hello World");
}
@RequestMapping("/address")
public Result getAddress(){
Address add = new Address();
add.setProvince("JiangXi");
add.setCity("GanZhou");
return Result.success(add);
}
}
那么我们运行服务端,用客户端浏览器接口来访问路径,看是否可以响应到我们需要的数据


可以看到客户端浏览器已经接收到了我们需要的数据,那么编写就非常成功了,我们成功的掌握了数据的请求与响应
响应总结
那么响应数据注意的就是注解+统一格式
注解@ResponseBody或者@RestController都可以使用
统一响应结果封装到result实体对象中,返回三个数据,一个是响应码code,一个是提示信息msg,还有响应的数据data即可。

本文介绍了SpringBootWeb开发中的请求响应机制,包括简单参数、实体参数、数组和集合参数、日期参数、json参数以及路径参数的处理。同时,还强调了如何通过统一的Result对象管理和响应数据的格式化。

被折叠的 条评论
为什么被折叠?



