day05-SpringBootWeb请求响应

news2024/11/20 13:43:43

请求响应:

  • 请求(HttpServletRequest):获取请求数据
  • 响应(HttpServletResponse):设置响应数据

BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。
CS架构:Client/Server,客户端/服务器架构模式。
在这里插入图片描述

一、请求

1 Postman

Postman 是一款功能强大的网页调试与发送网页 HTTP 请求的 Chrome 插件。

2 简单参数

简单参数:在向服务器发起请求时,向服务器传递的是一些普通的请求数据。

2.1 原始方式(仅做了解,在以后的开发中不会使用到)

在原始的 Web 程序当中,需要通过 Servlet 中提供的 API:HttpServletRequest(请求对象),获取
请求的相关信息。比如获取请求参数: Tomcat 接收到 http 请求时:把请求的相关信息封装到 HttpServletRequest 对象中

在 Controller 中,我们要想获取 Request 对象,可以直接在方法的形参中声明 HttpServletRequest 对象。然后就可以通过该对象来获取请求信息:

	//1. 简单参数
     //原始方式
    @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";
    }

2.2 SpringBoot方式

如果是简单参数,参数名与形参变量名相同,定义同名的形参即可接收参数。

    //springboot方式
    @RequestMapping("/simpleParam")
    public String simpleParam(String name, Integer age){
        System.out.println(name+ ":" + age);
        return "OK";
    }

结论:不论是 GET 请求还是 POST 请求,对于简单参数来讲,只要保证请求参数名和 Controller 方法中的形参名保持一致 ,就可以获取到请求参数中的数据值。

2.3 参数名不一致

结论:运行没有报错。对于简单参数来讲,请求参数名和 controller 方法中的形参名不一致时,无法接收到请求数据。

简单参数:如果方法形参名称与请求参数名称不匹配,可以使用 @RequestParam 完成映射。

//    @RequestMapping("/simpleParam")
    public String simpleParam(@RequestParam(name = "name", required = false) String username, Integer age){
        System.out.println(username+ ":" + age);
        return "OK";
    }

@RequestParam 中的 required 属性默认为 true,代表该请求参数必须传递,如果不传递将报错。 如果该参数是可选的,可以将 required 属性设置为 false。

3 实体参数

3.1 简单实体对象

简单实体对象:请求参数名与形参对象属性名相同,定义 POJO 接收即可
在这里插入图片描述

    //2. 实体参数
    @RequestMapping("/simplePojo")
    public String simplePojo(User user){
        System.out.println(user);
        return "OK";
    }
public class User {
   private String name;
   private Integer age;
}

3.2 复杂实体对象

复杂实体对象:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数。
在这里插入图片描述

    @RequestMapping("/complexPojo")
    public String complexPojo(User user){
        System.out.println(user);
        return "OK";
    }
public class User {
    private String name;
    private Integer age;
    private Address address;
}
public class Address {
    private String province;
    private String city;
}

4 数组集合参数

数组集合参数的使用场景:在 HTML 的表单中,有一个表单项是支持多选的(复选框),可以提交选择的多个值。
在这里插入图片描述

4.1 数组

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

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

4.2 集合

集合参数:请求参数名与形参集合名称相同且请求参数为多个,@RequestParam 绑定参数关系

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

5 日期参数

日期参数:使用 @DateTimeFormat 注解完成日期参数格式转换,以及其 pattern 属性来设置日期的格式。
在这里插入图片描述

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

6 JSON参数

JSON 参数:JSON 数据 键名 与形参对象 属性名 相同,定义 POJO 类型形参即可接收参数,需要使用 @RequestBody 标识
在这里插入图片描述

	//5. json参数
    @RequestMapping("/jsonParam")
    public String jsonParam(@RequestBody User user){
        System.out.println(user);
        return "OK";
    }

7 路径参数

路径参数:通过请求 URL 直接传递参数,使用{…}来标识该路径参数,需要使用 @PathVariable 获取路径参数
在这里插入图片描述

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

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

二、响应

1 @ResponseBody

类型:方法注解、类注解
位置:Controller 方法上/类上
作用:将方法返回值直接响应,如果返回值类型是 实体对象/集合 ,将会转换为 JSON 格式响应
说明:@RestController = @Controller + @ResponseBody

/**
 * 测试响应数据
 */
@RestController
public class ResponseController {

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

    @RequestMapping("/getAddr")
    public Address getAddr(){
        Address addr = new Address();
        addr.setProvince("广东");
        addr.setCity("深圳");
        return addr;
    }

    @RequestMapping("/listAddr")
    public List<Address> 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 list;
    }
    
}

2 统一响应结果

前端:只需要按照统一格式的返回结果进行解析(仅一种解析方案),就可以拿到数据。

统一的返回结果使用类来描述,在这个结果中包含:

  • 响应状态码:当前请求是成功,还是失败
  • 状态码信息:给页面的提示信息
  • 返回的数据:给前端响应的数据(字符串、对象、集合)
/**
 * 统一响应结果封装类
 */
public class Result {
    private Integer code ;//1 成功 , 0 失败
    private String msg; //提示信息
    private Object data; //数据 date

    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 +
                '}';
    }
}
@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);
    }
}

3 案例

加载并解析 emp.xml 文件中的数据,完成数据处理,并在页面展示。
在这里插入图片描述

实现步骤

  1. 在 pom.xml 文件中引入 dom4j 的依赖,用于解析 XML 文件
  2. 引入资料中提供的解析 XML 的工具类 XMLParserUtils、对应的实体类 Emp、XML文件 emp.xml
  3. 引入资料中提供的静态页面文件,放在 resources 下的 static 目录下
  4. 编写 Controller 程序,处理请求,响应数据

Springboot 项目的静态资源(html,css,js等前端资源)默认存放目录为:classpath:/static 、 classpath:/public、 classpath:/resources

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

}

三、分层解耦

1 三层架构

在这里插入图片描述

那其实我们上述案例的处理逻辑呢,从组成上看可以分为三个部分:

  1. 数据访问:负责业务数据的维护操作,包括增、删、改、查等操作。
  2. 逻辑处理:负责业务逻辑处理的代码。
  3. 请求处理、响应数据:负责,接收页面的请求,给页面响应数据。

在这里插入图片描述

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

在这里插入图片描述

2 分层解耦

  • 内聚:软件中各个功能模块内部的功能联系。
  • 耦合:衡量软件中各个层/模块之间的依赖、关联的程度。
  • 软件设计原则:高内聚低耦合。

在这里插入图片描述

  • 控制反转: Inversion Of Control,简称 IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。
  • 依赖注入: Dependency Injection,简称 DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
  • Bean对象:IOC容器中创建、管理的对象,称之为bean。

3 IOC&DI

3.1 IOC&DI入门

①. Service 层 及 Dao 层的实现类,交给 IOC 容器管理。
②. 为 Controller 及 Service 注入运行时,依赖的对象。
③. 运行测试。
在这里插入图片描述

3.2 IOC详解

3.2.1 bean的声明

要把某个对象交给 IOC 容器管理,需要在对应的类上加上如下注解之一:
在这里插入图片描述

注意事项:

  • 声明 bean 的时候,可以通过 value 属性指定 bean 的名字,如果没有指定,默认为类名首字母小写。
  • 使用以上四个注解都可以声明 bean,但是在 springboot 集成 web 开发中,声明控制器 bean 只能用 @Controller。
3.2.2 组件扫描
  • 前面声明 bean 的四大注解,要想生效,还需要被组件扫描注解 @ComponentScan 扫描。
  • @ComponentScan 注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解 @SpringBootApplication 中,默认扫描的范围是启动类所在包及其子包
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {

3.3 DI详解

@Autowired注解,默认是按照 类型 进行,如果存在多个相同类型的bean,将会报出如下错误:
在这里插入图片描述

通过以下几种方案来解决:

  1. @Primary
  2. @Qualifier
  3. @Resource
@Primary
@Service
public class EmpServiceA implements EmpService {
}
@RestController
public class EmpController {
    @Autowired    
    @Qualifier("empServiceA")
    private EmpService empService ;
@RestController
public class EmpController {
    @Resource(name = "empServiceB")
    private EmpService empService ;

@Autowird 与 @Resource的区别

  1. @Autowired 是 spring 框架提供的注解,而 @Resource 是 JDK 提供的注解
  2. @Autowired 默认是按照类型注入,而 @Resource 是按照名称注入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1520908.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux使用Docker部署Registry结合内网穿透实现公网远程拉取推送镜像

文章目录 1. 部署Docker Registry2. 本地测试推送镜像3. Linux 安装cpolar4. 配置Docker Registry公网访问地址5. 公网远程推送Docker Registry6. 固定Docker Registry公网地址 Docker Registry 本地镜像仓库,简单几步结合cpolar内网穿透工具实现远程pull or push (拉取和推送)…

科普文之五分钟轻松入门Generative AI

1. 引言 最近&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;在行业内带来了巨大的变动。还记得 2022 年 11 月推出的 ChatGPT 吗&#xff1f;在短时间内&#xff0c;它就成为了有史以来用户数量最快突破 1 亿的产品。 人工智能已经存在了很长一段时间&…

MySQL锁整理

MySQL锁信息来源 MySQL锁太多&#xff0c;内容太杂。写篇文章记录一下

3D地图在BI大屏中的应用实践

前言 随着商业智能的不断发展&#xff0c;数据可视化已成为一项重要工具&#xff0c;有助于用户更好地理解数据和分析结果。其中&#xff0c;3D地图作为一种可视化工具&#xff0c;已经在BI大屏中得到了广泛地应用。 3D地图通过将地理信息与数据相结合&#xff0c;以更加直观…

python--函数的基本用法

python--函数的基本用法 定义函数无参无返回值有参无返回值无参有返回值有参有返回值 空函数多个返回值函数的参数必传参数&#xff08;不传会报错&#xff09;关键字参数不定长参数*args**kwargs区别 拆包(了解)*用法**用法 定义函数 无参无返回值 def foo():语句有参无返回…

网络安全框架和云安全参考架构介绍

目录 一、网络安全框架 1.1 概述 1.2 IATF框架 1.2.1 框架来源 1.2.2 框架结构图 1.2.3 框架内容 1.2.3.1 人&#xff08;People&#xff09; 1.2.3.2 技术&#xff08;Technology&#xff09; 1.2.3.3 操作&#xff08;Operation&#xff09; 1.3 NIST网络安全框架 …

任何图≌自己这一几何最最起码常识推翻直线公理和平面公理

黄小宁 与x∈R相异&#xff08;等&#xff09;的实数均可表为yxδ&#xff08;增量δ可0也可≠0&#xff09;。因各实数的绝对值都可是表示长度的数故各实数都可是一维空间“管道”g内点的坐标。于是x∈R变换为实数yxδ的几何意义可是&#xff1a;“管道”g内R轴上的质点x∈R(x…

由浅到深认识C语言(9):动态内存分配

该文章Github地址&#xff1a;https://github.com/AntonyCheng/c-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.csdn…

前端基础——HTML傻瓜式入门(2)

该文章Github地址&#xff1a;https://github.com/AntonyCheng/html-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

夏天快到了,车辆改色膜备案流程是什么?

夏天快到了 越来越多的车主想给自己的爱车贴上变色膜。 但也有不少车主对车辆贴膜登记流程并不清楚。 本期电影一号小编就给大家科普一下。 一起来看看吧~ 您可以先更改车身颜色&#xff0c;然后再进行&#xff1a; 现在相关政策发生了变化&#xff0c;允许车主先改变车辆颜…

复杂微纳结构制造需求旺盛 微纳3D打印市场发展前景广阔

复杂微纳结构制造需求旺盛 微纳3D打印市场发展前景广阔 微纳3D打印是一种基于增材原理制造微纳结构的新型微纳加工技术。   3D打印又称为增材制造&#xff0c;是以数字模型为基础&#xff0c;将材料逐层堆积制造出实体物品的制造技术。我国3D打印市场发展动力强劲&#xff0c…

加速渲染:Blender与在线渲染农场的结合

​在数字艺术和三维设计的世界里&#xff0c;Blender软件因其强大的功能和灵活性而广受欢迎。然而&#xff0c;随着项目复杂性的增加&#xff0c;渲染时间也随之增长&#xff0c;成为艺术家和设计师面临的一大挑战。在线渲染农场的出现&#xff0c;为这一问题提供了革命性的解决…

Python Learn day05

Python Learn day05 本文主要讲解 继承、多态、定制类 继承和多态 什么是继承 当新类想要拥有现有类的功能结构&#xff0c;可以使用继承。继承的前提是新类 is a 现有类&#xff0c;即&#xff1a; 子类 is 父类 总是从某个类继承&#xff1a; class Myclass(object):pass…

从单一收入到自由职业:宝哥多元化收入探索之旅

你好&#xff0c;我是宝哥&#xff0c;一个热爱前端开发的自媒体人。 目前是&#xff1a; 前端社群达人 (管理10个前端交流群&#xff0c;连接数千开发者)微博前端大V (拥有20万粉丝&#xff0c;分享最新前端技术和资讯)前端公众号主编 (运营头部前端公众号&#xff0c;影响着数…

算法打卡day18|二叉树篇07|Leetcode 530.二叉搜索树的最小绝对差、501.二叉搜索树中的众数、236. 二叉树的最近公共祖先

算法题 Leetcode 530.二叉搜索树的最小绝对差 题目链接:530.二叉搜索树的最小绝对差 大佬视频讲解&#xff1a;二叉搜索树的最小绝对差视频讲解 个人思路 因为是在二叉搜索树求绝对差&#xff0c;而二叉搜索树是有序的&#xff0c;那就把它想成在一个有序数组上求最值&…

P6技巧:导出XER设置老版本/新版本

前言 在一个大型的项目中&#xff0c;虽然业主方已要求承包商必须使用P6格式来提交计划&#xff0c;但实际情况是承包商会给到你多种不同版本的XER文件&#xff0c;使得得在Oracle Primavera P6 之间导入或导出。 如果收到的 XER 文件不适合你使用的 Primavera P6 版本&#x…

使用IDEA2023创建传统的JavaWeb项目并运行与调试

日期:2024-0312 作者:dusuanyun 文档环境说明: OS:Deepin 20.9(Linux) JDK: OpenJDK21 Tomcat:10.1.19 IDEA: 2023.3.4 (Ultimate Edition) 本文档默认已经安装JDK及环境变量的配置。 关键词…

广度优先算法(一篇文章讲透)

目录 引言 一、算法概述 二、算法步骤 1 初始化 2 循环处理 三、算法应用 1 图的最短路径问题 2 网络爬虫 3 社交网络分析 4 游戏路径搜索 事例 四、算法特点与性能 五、性能优化 1 剪枝策略&#xff1a; 2 使用高效的数据结构&#xff1a; 3 并行化处理&#…

VS2022实现简单控件的缩放

private float X;//当前窗体的宽度private float Y;//当前窗体的高度public Form1(){InitializeComponent();}// 将控件的宽&#xff0c;高&#xff0c;左边距&#xff0c;顶边距和字体大小暂存到tag属性中private void setTag(Control cons){foreach (Control con in cons.Con…

【ARM】UBL本地服务器离线激活license

【更多软件使用问题请点击亿道电子官方网站查询】 1、 文档目标 UBL本地服务器离线激活license。 2、 问题场景 解决有用户外出时激活 license。 3、软硬件环境 1&#xff09;、软件版本&#xff1a;MDK5.39 2&#xff09;、电脑环境&#xff1a;Ubuntu 20.04 LTS 3&…