1、第一阶段邪修实战总览(9.1-9.30)

把第一阶段(基础夯实期)的学习计划拆解成极具操作性的每日行动方案。这个计划充分利用我“在职学习”的特殊优势,强调“用输出倒逼输入”,确保每一分钟的学习都直接服务于面试和实战。

  • 核心目标:构建起Java后端开发的知识树主干,并能通过一个小型项目串联起所有知识点。
  • 核心策略:每天3小时雷打不动的高效学习(工作日可分散,周末集中攻坚)。

2、周目标(9.1-9.14)

Java核心+Sprig Boot破冰,能独立使用Spring搭建Web后端并提供RESTful接口。


3、分日目标与邪修技巧

3.1、Day 9-10: Spring Boot开发RESTful API

  • 行动:设计/api/ads相关的接口(GET、POST),用@PostMapping接收前端传过来的JSON数据并解析。
  • 邪修技巧:使用Postman软件测试自己写的接口,确保能通。这个过程和前端联调一模一样,这就是经验。

3.1.1、学习分享

接下来我会讲解一下我在学习这部分知识的时候编写与测试GET接口的详细步骤:

第一步:设计我们的数据模型
在编写接收数据的API之前,需要先定义数据长什么样。我们可以直接在我们7-8天测试的那个demo中进行修改。

  • 创建实体类:在scr/main/java/com/adcampaign下新建一个entity包,并在该包下创建一个新的Java类,名为AdAdvertisement
  • 编写类代码:
package com.adcampaign.entity;/*** 广告活动数据模型类* 用于存储广告活动的核心数据,并提供数据计算和分析功能* 每个实例代表一天的广告活动数据*/
public class AdAdvertisement {// 日期(例如:"2023-10-01")private String date;// 广告花费(单位:元)private double cost;// 线索提交个数(用户提交的潜在客户信息数量)private int leadCount;// 私信消息数(收到的用户私信数量)private int messageCount;/*** 构造方法:创建广告活动数据对象* @param date 日期字符串* @param cost 广告花费金额* @param leadCount 线索数量* @param messageCount 私信消息数量*/public AdAdvertisement(String date, double cost, int leadCount, int messageCount) {this.date = date;this.cost = cost;this.leadCount = leadCount;this.messageCount = messageCount;}// Getter方法:获取私有属性的值public String getDate() { return date; }public double getCost() { return cost; }public int getLeadCount() { return leadCount; }public int getMessageCount() { return messageCount; }// Setter方法:修改私有属性的值public void setDate(String date) { this.date = date; }public void setCost(double cost) { this.cost = cost; }public void setLeadCount(int leadCount) { this.leadCount = leadCount; }public void setMessageCount(int messageCount) { this.messageCount = messageCount; }/*** 计算单个线索成本* 公式:单个线索成本 = 广告花费 ÷ 线索数量* @return 单个线索成本(元/个),如果线索数量为0则返回0*/public double calculateCostPerLead() {// 防止除以零错误:如果线索数为0,返回0return (leadCount > 0) ? cost / leadCount : 0;}/*** 计算私信消息转化成本* 公式:私信转化成本 = 广告花费 ÷ 私信消息数* @return 私信转化成本(元/条),如果私信数为0则返回0*/public double calculateCostPerMessage() {// 防止除以零错误:如果私信数为0,返回0return (messageCount > 0) ? cost / messageCount : 0;}/*** 分析广告花费随日期的变动情况* @param previousCampaign 上一个日期的广告活动数据(用于比较)* @return 变动情况描述,包含变动金额和百分比*/public String analyzeCostChange(AdAdvertisement previousCampaign) {// 检查是否有历史数据可供比较if (previousCampaign == null) return "无历史数据可供比较";// 计算变动金额:当前花费 - 上一期花费double changeAmount = this.cost - previousCampaign.getCost();// 计算变动百分比:(变动金额 ÷ 上一期花费) × 100%double changeRate = (changeAmount / previousCampaign.getCost()) * 100;// 格式化输出:保留两位小数,显示变动金额和百分比return String.format("花费变动: %.2f元 (%.2f%%)", changeAmount, changeRate);}/*** 分析单个线索成本随日期的变动情况* @param previousCampaign 上一个日期的广告活动数据(用于比较)* @return 变动情况描述,包含变动金额和百分比*/public String analyzeCostPerLeadChange(AdAdvertisement previousCampaign) {if (previousCampaign == null) return "无历史数据可供比较";// 获取当前和上一期的单个线索成本(调用已有的计算方法)double currentCpl = this.calculateCostPerLead();double previousCpl = previousCampaign.calculateCostPerLead();// 防止除以零错误if (previousCpl <= 0) return "历史单个线索成本为0,无法计算变动率";double changeAmount = currentCpl - previousCpl;double changeRate = (changeAmount / previousCpl) * 100;return String.format("单个线索成本变动: %.2f元 (%.2f%%)", changeAmount, changeRate);}/*** 分析私信消息转化成本随日期的变动情况* @param previousCampaign 上一个日期的广告活动数据(用于比较)* @return 变动情况描述,包含变动金额和百分比*/public String analyzeMessageCostChange(AdAdvertisement previousCampaign) {if (previousCampaign == null) return "无历史数据可供比较";// 获取当前和上一期的私信转化成本(调用已有的计算方法)double currentCpm = this.calculateCostPerMessage();double previousCpm = previousCampaign.calculateCostPerMessage();// 防止除以零错误if (previousCpm <= 0) return "历史私信转化成本为0,无法计算变动率";double changeAmount = currentCpm - previousCpm;double changeRate = (changeAmount / previousCpm) * 100;return String.format("私信转化成本变动: %.2f元 (%.2f%%)", changeAmount, changeRate);}
}

(其实要是大家仔细研究过这个系列的前面,并且看了Data_Board-README文档的话,不难发现,其实这个类是直接复制的,仅仅只是改了名字而已)
在这里插入图片描述
第二步:升级控制器
现在我们需要改造我们Day7-8创建的控制器或者来创建一个更专业的控制器,我们这里直接来创建吧

  • 创建控制器:在controller包下,创建AdController.java
  • 编写Get接口(返回数据列表):
package com.adcampaign.controller;import com.adcampaign.entity.AdAdvertisement; // 导入刚刚创建的实体类
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Arrays;
import java.util.List;@RestController
@RequestMapping("/api/ads") // 所有这个控制器下的接口路径都以 /api/ads 开头
public class AdController {// 模拟一些静态数据private List<AdAdvertisement> adList = Arrays.asList(new AdAdvertisement("2025-9-28",5000,10,50),new AdAdvertisement("2025-9-29",6000,15,60));@GetMapping // 等价于 @GetMapping(""),访问路径是 /api/adspublic List<AdAdvertisement> getAllAds() {return adList; // Spring Boot会自动将这个List序列化为JSON返回}
}

第三步:编写启动类
启动类通常位于项目最顶级的包下,之前7-8天的测试自动生成了一个启动类,我们这里直接删除即可,接下来在src/main/java/com/adcampaign包下新建一个启动类叫Data_Board_Application.java

  • 编写启动类代码:
package com.adcampaign;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;// 核心注解:标记这是一个Spring Boot应用的主配置类
@SpringBootApplication
@RestController
public class Data_Board_Appliction {public static void main(String[] args) {SpringApplication.run(Data_Board_Appliction.class, args);}
}
  • 测试GET接口
    • 启动项目,运行启动类Data_Board_Application.java,然后在在终端窗口如果出现下面的样式则代表运行成功:
      在这里插入图片描述
    • 打开浏览器,访问网址http://localhost:8080/api/ads,如果在浏览器中显示如图所示的两条包含广告数据的JSON数组,就证明成功了。
      在这里插入图片描述

第四步:编写POST接口(接收数据)
这是最关键的一步,可以学会如何接收前端发送的JOSN数据。

  • 在AdController中添加POST接口:
// 新增POST接口@PostMappingpublic String createAd(@RequestBody AdAdvertisement newAd) {// @RequestBody 注解告诉Spring:“请把请求体里的JSON数据,转换成一个AdAdvertisement对象”// 模拟处理:打印接收到数据System.out.println("接收到新的广告数据:");System.out.println("日期: " + newAd.getDate());System.out.println("广告花费: " + newAd.getCost());System.out.println("线索提交个数: " + newAd.getLeadCount());System.out.println("私信消息数: " + newAd.getMessageCount());// 这里暂时不做实际存储,只是返回成功消息return "广告数据创建成功! " + newAd.getDate();}
  • AdController控制器的完整代码如下:
package com.adcampaign.controller;import com.adcampaign.entity.AdAdvertisement; // 导入刚刚创建的实体类
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;import java.util.Arrays;
import java.util.List;@RestController
@RequestMapping("/api/ads") // 所有这个控制器下的接口路径都以 /api/ads 开头
public class AdController {// 模拟一些静态数据private List<AdAdvertisement> adList = Arrays.asList(new AdAdvertisement("2025-9-28",5000,10,50),new AdAdvertisement("2025-9-29",6000,15,60));@GetMapping // 等价于 @GetMapping(""),访问路径是 /api/adspublic List<AdAdvertisement> getAllAds() {return adList; // Spring Boot会自动将这个List序列化为JSON返回}// 新增POST接口@PostMappingpublic String createAd(@RequestBody AdAdvertisement newAd) {// @RequestBody 注解告诉Spring:“请把请求体里的JSON数据,转换成一个AdAdvertisement对象”// 模拟处理:打印接收到数据System.out.println("接收到新的广告数据:");System.out.println("日期: " + newAd.getDate());System.out.println("广告花费: " + newAd.getCost());System.out.println("线索提交个数: " + newAd.getLeadCount());System.out.println("私信消息数: " + newAd.getMessageCount());// 这里暂时不做实际存储,只是返回成功消息return "广告数据创建成功! " + newAd.getDate();}
}

第五步:测试POST接口(使用Postman)
由于我们不能用浏览器地址栏测试POST请求,必须使用Postman或类似的API测试工具,所以需要我们来下载并安装一个Postman来进行测试。

  • 大家可以跟着这篇文章来初步了解一下Postman,postman接口测试工具详解【全】,这篇文章中详细介绍了如何下载、安装与一些简单的使用。
  • 创建一个新请求:
    • 方法选择:POST
    • URL输入:localhost:8080/api/ads
  • 设置请求头:
    • 点击Headers标签
    • 添加一个Key:Content-Type,Value:application/json
  • 设置请求体:
    • 点击Body标签
    • 选择raw和JOSN
    • 在下方文本框中输入一段JOSN数据:
{"date": "2025-09-30","cost": 100.5,"leadCount": 5,"messageCount": 7
}
  • 点击Send:

    • 成功标志:下方响应去会看到广告数据创建成功2025-9-30
      在这里插入图片描述
    • 同时,回头看我们的IDE控制台(运行Spring Boot)的窗口,应该能看到打印出的接收到的数据信息。
      在这里插入图片描述
  • 这个项目的源码我放到了我的GitHub里,点击Data_Board_Spring_Boot链接直接学习和使用即可~


总结

@RequestBody是灵魂:

  • 它完成了HTTP请求体 -> Java对象的魔法转换。这个过程叫“反序列化”,由Spring内置的Jackson库自动完成。只需要定义一个Java类,字段名能和JSON的key对上就行。

为什么要有无参构造器和Getter/Setter?

  • Jackson库在创建对象和读取/设置属性时需要使用它们。没有他们,转换就会失败。这也是之前为什么要强调生成这些方法的原因。

Web开发经验

  • 使用Spring Boot的@RestController开发过RESTful接口,包括处理GET和POST请求。并且我知道如何使用@RequestBody注解来接收前端发送的JSON格式参数,完成反序列化。

@SpringBootApplication

是一个组合注解,它包含了三个核心功能:

  • @SpringBootConfiguration:标记该类为配置类
  • @EnableAutoConfiguration:开启自动配置,这是Spring Boot的魔法所在,它根据您引入的jar包依赖(如Spring-Web,MySQL Driver),自动配置应用程序锁需的组件(如Tomcat服务器、SpringMVC)。
  • @ComponentScan:自动扫描当前包及其子包下的组件(如@Controller,@Service,@RestController,@Component等),并注册为Spring Bean。

包路径的重要性

  • AdControlle控制器类必须放在启动类的同级或者子包下!例如,如果启动类在com.example.demo包下,那么您的控制器最好放在com.example.demo.controller包下。如果放在一个毫不相干的包路径下,@ComponentScan将无法发现它,导致404错误。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【GD32】ROM Bootloader、自定义Bootloader区别

Bootloader是应用程序跑起来之前&#xff0c;用于初始化的一段程序&#xff0c;它分为两种&#xff0c;ROM Bootloader、自定义Bootloader。GD32芯片出厂时预烧录在ROM中的Bootloader&#xff08;以下简称ROM Bootloader&#xff09;和自己编写的Bootloader&#xff08;以下简称…

Linux防火墙-Firewalld

一、 概述 按表现形式划分&#xff1a; 软件防火墙&#xff1a; 集成在系统内部&#xff0c;Linux系统&#xff1a; iptables、firewalld、ufw&#xff1b; windows系统下&#xff1a; windows defender 硬件防火墙&#xff1a; 华为防火墙、思科防火墙、奇安信防火墙、深信服防…

【Qt】PyQt、原生QT、PySide6三者的多方面比较

目录 引言 一、基本定义 二、核心对比维度 1. 编程语言与开发效率 2. 功能与 API 兼容性 3. 性能表现 4. 许可证与商业使用 5. 社区与文档支持 三、迁移与兼容性 四、适用场景推荐 五、总结对比表 总结 引言 PySide6、PyQt&#xff08;通常指 PyQt5/PyQt6&#xf…

JavaWeb站内信系统 - 技术设计文档

1. 系统概述1.1 项目背景本系统旨在为企业或社区平台提供一套完整的站内信解决方案&#xff0c;支持用户之间的消息发送、接收、管理等功能&#xff0c;提升用户间的沟通效率。1.2 设计目标实现用户间消息发送和接收支持一对一和一对多消息发送提供消息状态跟踪&#xff08;已读…

Java基础 9.10

1.System类常见方法和案例exit&#xff1a;退出当前程序arraycopy&#xff1a;复制数组元素&#xff0c;比较适合底层调用&#xff0c;一般使用 Arrays.copyOf 完成复制数组int[] src{1,2,3};int[] dest new int[3]; System.arraycopy(src, 0, dest, 0, 3);currentTimeMilens&…

详解flink性能优化

1. 简介 Apache Flink是一个强大的流处理框架&#xff0c;其性能很大程度上取决于内存的使用效率。在大规模数据处理场景中&#xff0c;合理的内存配置和优化可以显著提升Flink作业的性能和稳定性。本文将深入探讨Flink内存优化的各个方面&#xff0c;包括状态后端选择、内存配…

VueFlow的箭头怎么调整

正好最近用到了VueFlow组件&#xff0c;发现箭头默认样式太小&#xff0c;无法体现流程展示&#xff0c;因此翻阅相关资料得出下列方法&#xff0c;有什么更好的方法&#xff0c;大家可以推荐推荐&#xff0c;谢谢。方法1&#xff1a;通过边&#xff08;Edge&#xff09;的样式…

【Python】S1 基础篇 P9 文件处理与异常处理技术

目录文件读取操作读取文件的全部内容相对路径和绝对路径逐行访问文件内容文件写入操作写入单行内容写入多行内容结构化数据的存储异常处理机制理解异常的工作原理ZeroDivisionError异常示例try-except语句块的使用else语句块的正确使用静默失败的合理应用本文将深入探讨Python中…

分布式事务实战手册:从四场业务灾难看方案选型与落地陷阱

在分布式系统的稳定性战役中&#xff0c;数据一致性问题如同潜伏的暗礁。某生鲜电商因分布式事务设计缺陷&#xff0c;在春节促销期间出现"下单成功但无库存发货"的悖论&#xff0c;3小时内产生2300笔无效订单&#xff0c;客服投诉量激增300%&#xff1b;某银行转账系…

Java算法题中的输入输出流

在Java算法题中&#xff0c;处理输入输出主要依赖系统流&#xff08;System.in和System.out&#xff09;&#xff0c;常用的方法总结如下&#xff1a; 一、输入方法&#xff08;读取系统输入&#xff09; 主要通过java.util.Scanner类或BufferedReader类实现&#xff0c;适用于…

墨水屏程序

EPD Reader 基于ESP32-C3的电子墨水屏阅读器&#xff0c;支持ap 配网、sntp 时间同步、txt阅读、天气预报、显示节假日信息、农历显示、自动休眠、web配置等功能。这是在另一个项目 一个rust embassy esp32c3 的练习项目-CSDN博客的基础上修改的 。 界面比较粗糙&#xff0c;以…

Git 创建 SSH 密钥

1.生成 SSH 密钥 打开 Git Bash ssh-keygen -t ed25519 -C "your_email@example.com" 把 ”your_email@example.com“ 改成再 github 注册的邮箱 系统会提示您三次输入: 第一个提示:Enter file in which to save the key (/c/Users/86189/.ssh/id_ed25519): 直接…

当前 AI 的主流应用场景

当前AI技术已深度渗透至社会各领域,2025年的主流应用场景呈现出行业垂直化、交互自然化、决策自主化三大特征。以下从六大核心领域展开分析,结合最新技术突破与规模化落地案例,揭示AI如何重塑人类生产生活范式: 一、智能办公与生产力革命 AI正从工具升级为「数字同事」,…

EI会议:第六届电信、光学、计算机科学国际会议(TOCS 2025)

第六届电信、光学、计算机科学国际会议&#xff08;TOCS 2025&#xff09;定于11月21-23日在中国南阳举行&#xff0c;本届会议以“电信、光学、计算机科学”为主题&#xff0c;旨在为相关领域的专家和学者提供一个探讨行业热点问题&#xff0c;促进科技进步&#xff0c;增加科…

回归预测 | MATLAB基于GRU-Attention的多输入单输出回归预测

代码是一个基于 MATLAB 的深度学习时间序列预测模型,结合了 GRU(门控循环单元)和自注意力机制(Self-Attention),用于回归预测任务。 一、主要功能 使用 GRU + Self-Attention 神经网络模型对时间序列数据进行回归预测,评估模型在训练集和测试集上的性能,并可视化预测结…

【JavaEE】(24) Linux 基础使用和程序部署

一、Linux 背景知识 Linux 的第一个版本开发者是 Linus&#xff0c;所以部分人会叫“林纳斯”。Linux 只是一个开源的操作系统内核&#xff0c;有些公司/开源组织基于 Linux 内核&#xff0c;配套了不同的应用程序&#xff0c;构成不同的操作系统&#xff08;比如 vivo、&#…

视觉SLAM第9讲:后端1(EKF、非线性优化)

目标&#xff1a; 1.理解后端的概念&#xff1b; 2.理解以EKF为代表的滤波器后端的工作原理&#xff1b; 3.理解非线性优化的后端&#xff0c;明白稀疏性是如何利用的&#xff1b; 4.使用g2o和Ceres实际操作后端优化。 9.1 概述 9.1.1 状态估计的概率解释 1.后端优化引出 前段…

楼宇自控系统监控建筑变配电系统:功效体现在安全与节能层面

建筑变配电系统是保障建筑电力供应的 “心脏”&#xff0c;负责将外界高压电转化为建筑内设备可使用的低压电&#xff0c;为暖通、照明、电梯等核心系统供电。传统变配电管理依赖人工巡检&#xff0c;不仅存在 “监测滞后、故障难预判” 的安全隐患&#xff0c;还因无法精准调控…

【Docker安装使用常见问题汇总】

文章目录1. wsl update failed: update failed:2.dockerDesktopLinuxEngine: The system cannot find the file specified.3. 中文语言包3.1. 下载中文包3.2 默认路径如下&#xff1a;3.3 备份并替换 app.asar 文件&#xff1a;4. Get "https://registry-1.docker.io/v2/&…

Android面试指南(八)

目录 1、Java语言相关 1.1、String的intern方法 1.2、HashMap的扩容 1.3、Java数组不支持泛型 1.4、泛型类型保留到运行时 1.5、匿名内部类使用的外部变量需要加final 2、Kotlin语言相关 3、设计模式 1、Java语言相关 1.1、String的intern方法 1&#xff09;、String…