SpringBootWeb 请求与响应 --学习笔记

在浏览器发起请求时,后端的web服务器是如何响应的?

通过自定义的Controller控制器类——请求会被部署在Tomcat中的Controller接收,然后Controller再给浏览器一个响应,在请求响应的过程中是遵循HTTP协议的

但其实Tomcat是不识别我们自己定义的Controller的。Tomcat是一个Servlet容器,支持Serlvet规范的,在tomcat中是可以识别 Servlet程序的

所以在SpringBootweb中,内置了一个核心的Servlet程序 DispatcherServlet,称之为 核心控制器,DispatcherServlet 负责接收页面发送的请求,然后根据执行的规则,将请求再转发给后面的请求处理器Controller,请求处理器处理完请求之后,最终再由DispatcherServlet给浏览器响应数据

这种浏览器/服务器的模式,也称之为BS结构

BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端

接收请求

一·、原始方式

通过Servlet中提供的API:HttpServletRequest(请求对象),获取请求的相关信息(比较繁琐,麻烦)

示例:

@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";
    }
}

二、springboot方式

对原始的API进行了封装,对于简单参数,只需要定义的形参名 = 参数名,即可接收参数

示例:

@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";
    }
}

参数名与形参名不一致:接收的值为null

如果非得用不一致的形参名的话,可以在形参名前加上@RequestParam注解,在该注解中有一个required值,默认为true,意为该参数必须有值传递过来,否则报错,如有需要,可手动设置为false

示例:

public String simpleParam(@RequestParam(name = "name", required = false) String username, Integer age)
1、简单实体对象

当前端传递的参数较多时,难道我们要一个一个形参全都给他写上吗?
当然不,这样太繁琐了,可以定义一个属性名对应参数名的对象,用该对象来接收

示例:

 public String simplePojo(User user) 
//参数可能有很多,比如username,password等,需要在user对象中定义同名成员变量,成员变量可以多,但是不能少
 2、复杂实体对象

一个参数有多种属性,譬如name、age、address.province、address.city四个参数,其中address就有province和city俩个属性,这时就可以把address看成一个大的address对象,其中有俩个成员变量就是province和city。把name、age、address又看成一个user对象,也就是对象嵌套对象,再用大的那个对象去接收参数

图示:

用大的这个对象(user)去接收就行了,记得名字一致

3、数组集合参数

就是参数名一样,值不一样,此时就可以用数组 or 集合来接收

图示:

或者 

用数组接收,直接定义同名数组就行了:

 public String arrayParam(String[] hobby)

用集合接收,同名集合,不过要多用一个@RequestParam 绑定参数关系

public String listParam(@RequestParam List<String> hobby)
4、日期参数

使用@DateTimeFormat注解中的pattern设置同款日期格式,使用Date或LocalDateTime来封装

public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime)
5、JSON参数

使用对象接收,成员变量名 = Json的数据键名,使用@RequestBody注解标识

 public String jsonParam(@RequestBody User user)
6、路径参数

直接在请求的URL中传递参数,如

http://localhost:8080/user/1		
http://localhost:880/user/1/0

使用{key}来标识该路径参数,使用@PathVariable获取路径参数,如

 @RequestMapping("/path/{id}")
    public String pathParam(@PathVariable Integer id)

响应请求

controller方法中的return的结果直接返回给了浏览器,关键在于@ResponseBody注解

@ResponseBody注解:

  • 类型:方法注解、类注解

  • 位置:书写在Controller方法上或类上

  • 作用:将方法返回值直接响应给浏览器

    • 如果返回值类型是实体对象/集合,将会转换为JSON格式后在响应给浏览器

@ResponseBody注解是一个组合注解

        @RestController = @Controller + @ResponseBody

统一响应结果

真实开发中统一规定的返回结果形式

在这个结果中包含:

  • 响应状态码:当前请求是成功,还是失败

  • 状态码信息:给页面的提示信息

  • 返回的数据:给前端响应的数据(字符串、对象、集合)

使用实体类Result来包含以上信息。代码如下:

public class Result {
    private Integer code;//响应码,1 代表成功; 0 代表失败
    private String msg;  //响应码 描述字符串
    private Object 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);
    }
    ......//省略get、set方法和构造器
}

使用统一响应结果时只需要将此Result类设置为Controller类的返回值类型设置为Result

//响应成功
return Result.success(响应数据,没有留空)
//响应失败
return Result.error()

分层解耦:三层架构

在我们进行程序设计以及程序开发时,尽可能让每一个接口、类、方法的职责更单一些(单一职责原则)

单一职责原则:一个类或一个方法,就只做一件事情,只管一块功能

这样就可以让类、接口、方法的复杂度更低,可读性更强,扩展性更好,也更利用后期的维护

实际上就是将代码划分为三层:

  1. Controller :数据接收、响应数据
    控制层。接收前端发送的请求,对请求进行处理,并响应数据
  2. Service :逻辑处理
    业务逻辑层。处理具体的业务逻辑
  3. Dao :数据访问
    数据访问层(Data Access Object),也称为持久层。负责数据访问操作,包括数据的增、删、改、查

图示:

实际操作:构建三个包,包名分别为: Controller、Service、Dao,将代码拆分到三层架构中,各层负责各家事,到需要其它层时,直接调用其方法,将数据传递过去交给其处理

  • 内聚:软件中各个功能模块内部的功能联系

  • 耦合:衡量软件中各个层/模块之间的依赖、关联的程度

而在三层架构中,往往需要new 一个其它层的对象来处理方法,比如控制层肯定需要new一个逻辑层对象来进行逻辑处理,这种方式显然是耦合的,假如当逻辑层的实现变了之后,还需要去修改控制层的代码,那么有没有什么办法,不管逻辑层怎么变,只需要逻辑层做相应的修改,而控制层不用修改代码呢?(各层处理各家事,解耦合)

  • 解决思路:
    • 提供一个容器,容器中存储一些对象(例:逻辑层对象)

    • 控制层程序从容器中获取逻辑层类型的对象

我们想要实现上述解耦操作,就涉及到Spring中的两个核心概念:

  • 控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转

    对象的创建权由程序员主动创建转移到容器(由容器创建、管理对象)。这个容器称为:IOC容器或Spring容器

  • 依赖注入: Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入

    程序运行时需要某个资源,此时容器就为其提供这个资源

    例:EmpController程序运行时需要EmpService对象,Spring容器就为其提供并注入EmpService对象

IOC容器中创建、管理的对象,称之为:bean对象

IOC&DI

将对象交给IOC容器管理,在对象上添加注解:

  • @Component(标注在其它类上)
  • @Controller (标注在控制层类上)
  • @Service (标注在业务层类上)
  • @Repository (标注在数据访问层类上)

如:

@RestController  //@RestController = @Controller + @ResponseBody
public class EmpController {
@Service
public class EmpServiceA implements EmpService {
@Repository
public class EmpDaoA implements EmpDao {

ps:在IOC容器中,每一个Bean都有一个属于自己的名字,可以通过注解的value属性指定bean的名字。如果没有指定,默认为类名首字母小写

从IOC容器中获取对象(依赖注入),只需要在对象定义上去除new,加上@Autowired注解

如:

 @Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
    private EmpService empService ;
@Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
    private EmpDao empDao ;

依赖注入是靠类型来识别需要的对象的,当存在多个同类型对象时,可以只保留一个需要使用的交给IOC容器管理,或者使用以下三个注解:

  • @Primary:存在多个相同类型时,在其中一个打上该注解表明此对象为默认的实现

  • @Qualifier:指定当前要注入的bean对象。 在@Qualifier的value属性中,指定注入的bean的名称,@Qualifier注解不能单独使用,必须配合@Autowired使用

  • @Resource:按照bean的名称进行注入。通过name属性指定要注入的bean的名称

@Autowird 与 @Resource的区别

  • @Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解

  • @Autowired 默认是按照类型注入,而@Resource是按照名称注入

 

  • 11
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以和你分享一些关于Spring Boot的学习笔记。 1. Spring Boot是什么? Spring Boot是一个基于Spring框架的快速开发框架,它能够帮助开发者快速搭建Spring项目,简化了Spring应用开发的繁琐过程,提高了开发效率。 2. Spring Boot的优点有哪些? Spring Boot的优点有很多,其中包括: - 简化了Spring应用的开发,提高了开发效率; - 集成了很多常用的第三方库,减少了依赖管理的工作; - 自动化配置,减少了配置文件的编写工作; - 内嵌了Tomcat等Web容器,使得应用的部署更加便捷; - 提供了Actuator等模块,使得应用的监控和管理更加便捷。 3. Spring Boot的核心注解有哪些? Spring Boot的核心注解包括: - @SpringBootApplication:标注在启动类上,代表这是一个Spring Boot应用; - @Controller:标注在控制器类上,处理HTTP请求; - @Service:标注在服务类上,用于处理业务逻辑; - @Repository:标注在数据访问类上,用于数据库访问; - @Configuration:标注在配置类上,用于配置Spring应用上下文。 4. Spring Boot的配置文件有哪些? Spring Boot的配置文件包括: - application.properties:基于Key-Value的属性文件; - application.yml:基于YAML语法的配置文件。 5. 如何使用Spring Boot集成数据库? 使用Spring Boot集成数据库需要完成以下几个步骤: - 在pom.xml中添加相关数据库依赖; - 配置数据源和JPA/Hibernate等相关配置; - 编写实体类和DAO层代码。 以上就是一些关于Spring Boot的学习笔记,希望能对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A泽予

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值