spring boot 基础案例【3】构建RESTful API与单元测试

news2025/1/10 23:51:53

教程1
案例教程
案例仓库
在线编程

教程2
基础教程
教程仓库
在线编程

本案例所在的仓库
本案例所在的文档


进入正文

1.文件目录

在这里插入图片描述

1. Chapter21Application.java

地址:chapter2-1/src/main/java/com/didispace/chapter21/Chapter21Application.java

package com.didispace.chapter21;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Chapter21Application {

	public static void main(String[] args) {
		SpringApplication.run(Chapter21Application.class, args);
	}

}

2. User.java

地址:chapter2-1/src/main/java/com/didispace/chapter21/User.java

package com.didispace.chapter21;

import lombok.Data;

@Data
public class User {
    private Long id;
    private String name;
    private int age;

    public User(Long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    // Getter and Setter methods
    // 略...
}

这段代码是一个简单的 Java 类定义,使用了 Lombok 库中的 @Data 注解,用于自动生成 getter、setter 和 toString 等方法。这个类定义了一个 User 类,包含了三个字段:idnameage,分别表示用户的唯一标识、姓名和年龄。

在 Java 中,通常需要为类的每个字段手动编写 getter 和 setter 方法以及 toString 方法来实现类的基本功能,但是使用 Lombok 的 @Data 注解可以自动帮助生成这些方法,从而简化了代码编写过程。

下面是这段代码的详细解释:

  • package com.didispace.chapter21;:这行代码定义了类的包路径,即 User 类所属的包名为 com.didispace.chapter21。包路径用于组织类,以便在不同的类之间进行引用和管理。

  • import lombok.Data;:这行代码导入了 Lombok 库中的 @Data 注解。通过导入该注解,我们可以在 User 类上使用 @Data 注解来自动生成 getter、setter 和 toString 方法。

  • @Data:这个注解是 Lombok 提供的,用于在编译时自动生成 getter、setter、equals、hashCode 和 toString 等方法。在 User 类上添加了 @Data 注解后,就不需要手动编写这些方法了,Lombok 会在编译时自动生成。

  • public class User {:这行代码定义了一个公共的 User 类。在 Java 中,类通常被定义为公共的(即 public),以便在其他包中可以访问到该类。

  • private Long id;private String name;private Integer age;:这三行代码定义了 User 类的三个私有字段,分别是 idnameage。这些字段被声明为私有的(即 private),意味着它们只能在 User 类的内部访问,外部无法直接访问这些字段。

  • }:这行代码表示类定义的结束。

总的来说,这段代码定义了一个简单的 Java 类 User,通过使用 Lombok 的 @Data 注解简化了 getter、setter 和 toString 方法的编写,使得代码更加简洁和易读。

3. UserController.java

地址:chapter2-1/src/main/java/com/didispace/chapter21/UserController.java

package com.didispace.chapter21;

import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@RequestMapping(value = "/users")     // 通过这里配置使下面的映射都在/users下
public class UserController {

    // 创建线程安全的Map,模拟users信息的存储
    static Map<Long, User> users = Collections.synchronizedMap(new HashMap<Long, User>());
    static {
        User user1 = new User(1566L, "Alice", 25);
        User user2 = new User(2L, "Bob", 30);
        User user3 = new User(3L, "Charlie", 35);
        users.put(user1.getId(), user1);
        users.put(user2.getId(), user2);
        users.put(user3.getId(), user3);
    }
    

    /**
     * 处理"/users/"的GET请求,用来获取用户列表
     *
     * @return
     */
    @GetMapping("/")
    public List<User> getUserList() {
        // 还可以通过@RequestParam从页面中传递参数来进行查询条件或者翻页信息的传递
        List<User> r = new ArrayList<User>(users.values());
        return r;
    }

    /**
     * 处理"/users/"的POST请求,用来创建User
     *
     * @param user
     * @return
     */
    @PostMapping("/")
    public String postUser(@RequestBody User user) {
        // @RequestBody注解用来绑定通过http请求中application/json类型上传的数据
        users.put(user.getId(), user);
        return "success";
    }

    /**
     * 处理"/users/{id}"的GET请求,用来获取url中id值的User信息
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        // url中的id可通过@PathVariable绑定到函数的参数中
        return users.get(id);
    }

    /**
     * 处理"/users/{id}"的PUT请求,用来更新User信息
     *
     * @param id
     * @param user
     * @return
     */
    @PutMapping("/{id}")
    public String putUser(@PathVariable Long id, @RequestBody User user) {
        User u = users.get(id);
        u.setName(user.getName());
        u.setAge(user.getAge());
        users.put(id, u);
        return "success";
    }

    /**
     * 处理"/users/{id}"的DELETE请求,用来删除User
     *
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    public String deleteUser(@PathVariable Long id) {
        users.remove(id);
        return "success";
    }

}

解释:

这段代码是一个基于Spring框架的RESTful风格的API示例,用于管理用户信息。让我逐步解释每个部分的功能和作用:

  1. package com.didispace.chapter21;:这行代码定义了类的包路径,即 UserController 类所属的包名为 com.didispace.chapter21。包路径用于组织类,以便在不同的类之间进行引用和管理。

  2. import org.springframework.web.bind.annotation.*;:这行代码导入了Spring框架中用于处理HTTP请求的注解,包括 @RestController@RequestMapping@GetMapping@PostMapping@PutMapping@DeleteMapping。这些注解用于定义RESTful API的请求映射和处理方法。

  3. @RestController:这个注解标注在类上,表示该类是一个RESTful风格的控制器,可以处理HTTP请求并返回RESTful风格的响应。

  4. @RequestMapping(value = "/users"):这个注解用于映射HTTP请求的URL路径,指定了处理该控制器的请求路径为 /users。因为在类级别上使用了这个注解,所以下面所有的请求映射路径都相对于 /users

  5. public class UserController {:这行代码定义了一个公共的 UserController 类。在Spring框架中,控制器类通常被定义为公共的(即 public),以便可以被其他类和组件引用。

  6. static Map<Long, User> users = Collections.synchronizedMap(new HashMap<Long, User>());:这行代码定义了一个静态的 Map 对象 users,用于存储用户信息。这里使用了 Collections.synchronizedMap 方法创建了一个线程安全的 Map,以确保在多线程环境下对用户信息的操作是安全的。

接下来是几个请求处理方法,它们分别处理不同的HTTP请求:

  • @GetMapping("/"):处理GET请求,用来获取用户列表。使用 @GetMapping 注解将该方法映射到处理 /users/ 路径的GET请求,并通过 List<User> 类型的返回值返回用户列表。

  • @PostMapping("/"):处理POST请求,用来创建新用户。使用 @PostMapping 注解将该方法映射到处理 /users/ 路径的POST请求,并通过 @RequestBody 注解从请求体中获取用户信息,并将用户信息添加到 users Map 中。

  • @GetMapping("/{id}"):处理GET请求,用来获取指定ID用户的信息。使用 @GetMapping 注解将该方法映射到处理 /users/{id} 路径的GET请求,并通过 @PathVariable 注解将URL中的 id 参数绑定到方法的参数中,然后根据 idusers Map 中获取对应的用户信息并返回。

  • @PutMapping("/{id}"):处理PUT请求,用来更新指定ID用户的信息。使用 @PutMapping 注解将该方法映射到处理 /users/{id} 路径的PUT请求,并通过 @PathVariable 注解将URL中的 id 参数绑定到方法的参数中,通过 @RequestBody 注解从请求体中获取新的用户信息,并更新 users Map 中对应ID的用户信息。

  • @DeleteMapping("/{id}"):处理DELETE请求,用来删除指定ID用户。使用 @DeleteMapping 注解将该方法映射到处理 /users/{id} 路径的DELETE请求,并通过 @PathVariable 注解将URL中的 id 参数绑定到方法的参数中,然后从 users Map 中删除对应ID的用户信息。

总的来说,这段代码实现了一个简单的用户管理系统,通过HTTP请求来实现对用户信息的增删改查操作,符合RESTful风格的API设计原则。

3.效果

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

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

相关文章

CSS @keyframes 动画:颜色变化、背景旋转与放大缩小

在CSS中&#xff0c;keyframes 是一个强大的工具&#xff0c;它允许我们创建复杂的动画效果。今天&#xff0c;我们将一起探索如何使用 keyframes 来实现颜色变化、背景旋转以及放大缩小的动画效果。 动画会在 2 秒内循环播放&#xff0c;并在不同的时间点改变盒子的背景颜色和…

【JVM】简述类加载器及双亲委派机制

双亲委派模型&#xff0c;是加载class文件的一种机制。在介绍双亲委派模型之前&#xff0c;我需要先介绍几种类加载器&#xff08;Class Loader&#xff09;。 1&#xff0c;类加载器 Bootstrap&#xff0c;加载lib/rt.jar&#xff0c;charset.jar等中的核心类&#xff0c;由…

VS code 同步odata服务

在做UI5得开发过程中&#xff0c;经常会出现odata需要更新 那么已经加载过得项目如何去跟新odata服务呢 可以通过如下步骤 1.右键打开应用信息 2.找到manage service models 3.点击编辑 4.选中 刷新并保存

前端发起网络请求的几种常见方式(XMLHttpRequest、FetchApi、jQueryAjax、Axios)

摘要 前端发起网络请求的几种常见方式包括&#xff1a; XMLHttpRequest (XHR)&#xff1a; 这是最传统和最常见的方式之一。它允许客户端与服务器进行异步通信。XHR API 提供了一个在后台发送 HTTP 请求和接收响应的机制&#xff0c;使得页面能够在不刷新的情况下更新部分内容…

【YOLOv9改进[Conv]】使用基于Haar的小波变换Down_wt处理替换模型结构中的Conv和ADown 实践

目录 一 基于Haar的小波变换 二 使用基于Haar的小波变换Down_wt处理替换模型结构中的Conv和ADown 实践 1 整体修改 2 配置文件 3 训练 三 报错处理 一 基于Haar的小波变换 Haar小波是最简单的小波形式之一&#xff0c;具有易于计算和实现的优点。使用二维离散小波变换&a…

TCP重传,滑动窗口,流量控制,拥塞控制

TCP重传&#xff0c;滑动窗口&#xff0c;流量控制&#xff0c;拥塞控制 TCP重传机制&#xff1a; 超时重传快速重传SACKD-SACK 通过序列号与确认应答判断是否要重传 超时重传&#xff1a; 超过指定时间没有收到确认应答报文&#xff0c;就会重发该数据 触发超时重传的情况…

k8s 资源组版本支持列表

1 kubernetes的资源注册表 kube-apiserver组件启动后的第一件事情是将Kubernetes所支持的资源注册到Scheme资源注册表中,这样后面启动的逻辑才能够从Scheme资源注册表中拿到资源信息并启动和运行API服务。 kube-apiserver资源注册分为两步:第1步,初始化Scheme资源注册表;…

【论文笔记】Training language models to follow instructions with human feedback A部分

Training language models to follow instructions with human feedback A 部分 回顾一下第一代 GPT-1 &#xff1a; 设计思路是 “海量无标记文本进行无监督预训练少量有标签文本有监督微调” 范式&#xff1b;模型架构是基于 Transformer 的叠加解码器&#xff08;掩码自注意…

【百度Apollo】探索自动驾驶:百度Apollo视觉感知模块的实践与创新

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引入一、百度Apollo视觉感知模块概述二、启动感知模块步骤一&#xff1a;进入 Docker 环境并启动 Dreamview步骤二…

请编写函数fun,该函数的功能是:统计各年龄段的人数。N个年龄通过调用随机函数获得,并放在主函数的age数组中;

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 请编…

我开始接单/兼职/搞副业/建设个人社区,为自己谋后路了。

我开始接单/兼职/搞副业/建设个人社区&#xff0c;为自己谋后路了。 简述 大家好&#xff0c;我是小荣&#xff0c;一个前端开发程序员。我最近开始在业余时间接私单了&#xff0c;也在想一些能够带来成长&#xff0c;收入的副业&#xff0c;主要也是为了自己谋后路&#xff…

ctfshow——SQL注入

文章目录 SQL注入基本流程普通SQL注入布尔盲注时间盲注报错注入——extractvalue()报错注入——updataxml()Sqlmap的用法 web 171——正常联合查询web 172——查看源代码、联合查询web 173——查看源代码、联合查询web 174——布尔盲注web 176web 177——过滤空格web 178——过…

【算法刷题 | 贪心算法09】4.30(单调递增的数字)

文章目录 16.单调递增的数字16.1题目16.2解法&#xff1a;贪心16.2.1贪心思路16.2.2代码实现 16.单调递增的数字 16.1题目 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的…

jenkins转载文本

基于Docker容器DevOps应用方案 企业业务代码发布系统 一、企业业务代码发布方式 1.1 传统方式 以物理机或虚拟机为颗粒度部署部署环境比较复杂&#xff0c;需要有先进的自动化运维手段出现问题后重新部署成本大&#xff0c;一般采用集群方式部署部署后以静态方式展现 1.2 容…

ubuntu部署sonar与windows下使用sonar-scanner

ubuntu部署sonar与windows下使用sonar-scanner sonar部署java安装mysql安装配置sonarqube 插件安装sonar-scanner使用简单使用 sonar部署 使用的是sonarqube-7.5&#xff0c;支持的java环境是jdk8&#xff0c;且MySQL版本 >5.6 && <8.0 java安装 打开终端&…

【初识Redis】

初识Redis Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的内存数据库&#xff0c;它提供了一个高性能的键值存储系统&#xff0c;并且支持多种数据结构&#xff0c;包括字符串、哈希、列表、集合和有序集合等。Redis的特点包括&#xff1a; 内存存储&…

Apache DolphinScheduler支持Flink吗?

随着大数据技术的快速发展&#xff0c;很多企业开始将Flink引入到生产环境中&#xff0c;以满足日益复杂的数据处理需求。而作为一款企业级的数据调度平台&#xff0c;Apache DolphinScheduler也跟上了时代步伐&#xff0c;推出了对Flink任务类型的支持。 Flink是一个开源的分…

2023年蓝桥杯C++A组第三题:更小的数(双指针解法)

题目描述 小蓝有一个长度均为 n 且仅由数字字符 0 ∼ 9 组成的字符串&#xff0c;下标从 0 到 n − 1&#xff0c;你可以将其视作是一个具有 n 位的十进制数字 num&#xff0c;小蓝可以从 num 中选出一段连续的子串并将子串进行反转&#xff0c;最多反转一次。小蓝想要将选出的…

罗宾斯《管理学》第13版/教材讲解/考研真题视频课程/网课

本课程是罗宾斯《管理学》&#xff08;第13版&#xff09;精讲班&#xff0c;为了帮助参加研究生招生考试指定考研参考书目为罗宾斯《管理学》&#xff08;第13版&#xff09;的考生复习专业课&#xff0c;我们根据教材和名校考研真题的命题规律精心讲解教材章节内容。 序号名…

神经网络基础(Neural net foundations)

Today we’ll be learning about the mathematical foundations of deep learning: Stochastic gradient descent (SGD), and the flexibility of linear functions layered with non-linear activation functions. We’ll be focussing particularly on a popular combination…