当前位置: 首页 > java >正文

SpringBootWeb入门

目录

1.入门程序 

RestController

RequestMapping

执行流程

2.HTTP协议

请求协议

响应协议

3.三层架构

原代码

三层框架与关联

三层架构代码

4.分层解耦

概述​

IOC/DI概述

5.IOC控制反转 

注解选择 

注解扫描

6.DI依赖注入

注入选择

解决bean冲突


1.入门程序 

@RestController

@RestController

  • 这是一个类级别的注解(放在类定义之上)。

  • 它结合了 @Controller 和 @ResponseBody 两个注解的功能。

  • @Controller:告诉Spring,这个类是一个Web控制器(Controller),专门用来处理HTTP请求。

  • @ResponseBody:告诉Spring,这个类中所有处理请求的方法的返回值,都应该直接写入HTTP响应体(Response Body)中,而不是跳转到一个视图模板(如JSP, Thymeleaf)。这正是构建RESTful API所需的行为。

  • 简单来说@RestController 标明这个类是一个API控制器,它的方法返回的是数据(JSON/XML/字符串),而不是页面。

@RequestMapping

@RequestMapping

  • 这是一个方法级别的注解(放在方法定义之上)。

  • 它用来将HTTP请求映射到特定的处理方法上。

  • @RequestMapping("/hello") 的意思是:“任何发送到 /hello 路径的HTTP请求,都由这个 hello() 方法来处理。”

  • 默认情况下,它会映射所有类型的HTTP请求(GET, POST, PUT, DELETE等)。虽然不推荐,但你可以用 @RequestMapping(value = "/hello", method = RequestMethod.GET) 来指定只处理GET请求。更常用的专用注解是 @GetMapping("/hello")

执行流程

package org.example;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class HelloController {@RequestMapping("/hello")public String hello(String name) {return "hello world"+name+"!";}
}

  1. 启动应用:你运行这个Spring Boot应用程序,内嵌的Tomcat服务器会默认在 8080 端口启动。

  2. 发送请求:你在浏览器或Postman中访问 http://localhost:8080/hello?name=John

  3. Spring路由:Spring的前端控制器 (DispatcherServlet) 接收到这个指向 /hello 的请求。

  4. 寻找处理器DispatcherServlet 查询映射表,发现 HelloController 中的 hello 方法被映射到了 /hello 路径。

  5. 处理请求:Spring调用 hello 方法,并将URL中 ?name=John 的 John 值作为参数 name 传给方法。

  6. 生成响应:方法执行,返回字符串 "hello worldJohn!"

  7. 返回响应:因为类上有 @RestController,Spring将这个字符串直接写入HTTP响应体,并设置状态码为200 (OK)。

  8. 客户端接收:你的浏览器或Postman收到响应内容:hello worldJohn!

 

2.HTTP协议

请求协议

package org.example.springbootweb;import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class Requestcontroller {@RequestMapping("/request")public String request(HttpServletRequest requst) {//1.获取请求方式String method = requst.getMethod();System.out.println(method);//2.获取请求url路径String requestURL = requst.getRequestURL().toString();System.out.println(requestURL);String requestURI = requst.getRequestURI().toString();System.out.println(requestURI);//3.获取请求协议String protocol = requst.getProtocol();System.out.println(protocol);//4.获取请求参数 - name和ageString name = requst.getParameter("name");System.out.println(name);String age = requst.getParameter("age");System.out.println(age);//5.获取请求头 - AcceptString accept = requst.getHeader("Accept");System.out.println(accept);return "请求方式:" + method + "<br/>" +"请求路径:" + requestURL + "<br/>" +"请求路径:" + requestURI + "<br/>" +"请求协议:" + protocol + "<br/>" +"请求参数:" + name + "<br/>" +"请求参数:" + age + "<br/>" +"请求头:" + accept;}
}

响应协议

3.三层架构

原代码

三层框架与关联

controller层接受前端的请求,调用service层,

service层会先调用dao层拿到数据再处理具体的业务逻辑,最后将处理完的数据返回给controller层。

具体流程:controller->service->dao   请求顺序

dao->service->controller   数据传递

三层架构代码

Controller控制连接层

@RestController
public class UserController {private UserService userService=new UserServiceImpl();@RequestMapping("/list")public List<User> list()throws  Exception{//1.调用逻辑层方法,获取用户数据List<User> userList=userService.findAll();//2.返回用户数据return userList;}}

Service业务逻辑处理层

package org.example.service.impl;import org.example.dao.UserDao;
import org.example.dao.impl.UserDaoImpl;
import org.example.pojo.User;
import org.example.service.UserService;import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;public class UserServiceImpl implements UserService {private UserDao userDao=new UserDaoImpl();@Overridepublic List<User> findAll() {//1.调用dao层方法,获取用户数据List<String> lines = userDao.findAll();//2.解析用户数据,封装成User对象List<User> userList=lines.stream().map(line -> {String [] parts =line.split(",");  // 将字符串按逗号进行切割,获取每个字段的值Integer id = Integer.parseInt(parts[0]);String username = parts[1];String password = parts[2];String name = parts[3];Integer age = Integer.parseInt(parts[4]);LocalDateTime updateTime = LocalDateTime.parse(parts[5], DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));return new User(id, username, password, name, age, updateTime);}).toList();//3.返回用户数据return userList;}
}

dao数据访问层

package org.example.dao.impl;import cn.hutool.core.io.IoUtil;
import org.example.dao.UserDao;import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;public class UserDaoImpl implements UserDao {@Overridepublic List<String> findAll(){//1.加载并读取user.txt文件,获取用户数据InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");ArrayList<String> lines = IoUtil.readLines(in, StandardCharsets.UTF_8, new ArrayList<>());return lines;}
}

4.分层解耦

概述

由于Controller层和Service层需要分别调用Service层和dao层。

为了解耦,将调用的Service和dao层通过IOC(控制反转)将对象创建权交给外部容器。

同时通过DI(依赖注入)为Controller和Service提供需要依赖的对象。

IOC/DI概述

@Component 注解用于告诉 Spring:“我是一个由你管理的类,请把我创建成一个对象(Bean)并放入你的容器中。”

@Autowired 注解用于告诉 Spring:“请自动帮我从你的容器里找出合适类型的 Bean,并注入(Inject)到这个字段、构造函数或方法中。”

Spring 容器(Container):你可以把它想象成一个巨大的、无所不能的对象工厂(Factory) + 仓库(Map)。它负责创建、组装和管理应用程序中的所有对象(这些对象在 Spring 里被称为 Bean

  • 如何将对象放入容器?:有两种主要方式:

    1. 传统配置:在 XML 文件或 Java 配置类中手动声明每一个 Bean。

    2. 自动扫描(现代方式):在类上添加 @Component(或其派生注解),然后让 Spring 自动发现它们并创建 Bean。

5.IOC控制反转 

注解选择 

@Component注解衍生的三层架构注解分别是

@Controller控制层

@Service业务逻辑层

@Repository数据访问层

而控制层上常用的@RestController和@Controller注解是直接继承自@Component,

但前者功能上组合了@Controller和@ResponseBody。

注解扫描

在声明bean注解的时候,生效需要被组件扫描注解扫描,该注解在启动类中。

而扫描范围默认在启动类所在包及其子包。

6.DI依赖注入

注入选择

解决bean冲突

由于Autowired注解根据类型注入,当存在多个类型的bean时,Spring容器不知道注入哪个

@Primary在实现类中定义,表示优先使用该类提供的bean

@Qualifier与@Autowired共同使用,需要指定注入bean(默认为类的首字母小写)

@Resource通过名称注入bean(默认为类的首字母小写)

http://www.xdnf.cn/news/18609.html

相关文章:

  • Ollama 本地部署 Qwen2.5-7b
  • 搜索--常见面试问题
  • Android 之wifi连接流程
  • 使用 LangChain 和 Neo4j 构建知识图谱
  • 一文学会vue的动态权限控制
  • 00后AI创业者崛起与AI商业应用新玩法:从Mercor到历史人物复刻的机遇
  • 【剖析高并发秒杀】从流量削峰到数据一致性的架构演进与实践
  • MySQL GPG 密钥更新问题解决文档
  • Kubernetes网络服务全解析
  • Linux netfilter工作原理详解
  • Mac简单测试硬盘读写速度
  • 暴雨环境漏检率下降78%!陌讯动态融合算法在道路积水识别的工程突破
  • LeetCode 面试经典 150_数组/字符串_找出字符串中第一个匹配项的下标(23_28_C++_简单)(KMP 算法)
  • PyTorch 面试题及详细答案120题(71-85)-- 高级特性与工具
  • Base64 编码优化 Web 图片加载:异步响应式架构(Java 后端 + 前端全流程实现)
  • vue实现小程序oss分片上传
  • 合合信息acge模型获C-MTEB第一,文本向量化迎来新突破
  • 微前端架构核心要点对比
  • C++ 使用最新 MySQL Connector/C++(X DevAPI)+ CMake 完整教程
  • 力扣 30 天 JavaScript 挑战 第38天 (第九题)学习了 语句表达式的区别 高级函数 promise async await 节流
  • 《P3623 [APIO2008] 免费道路》
  • Redis Set 类型详解:从基础命令到实战应用
  • git实战(8)git高阶命令分析【结合使用场景】
  • 本地Docker部署开源Web相册图库Piwigo与在线远程访问实战方案
  • 如何优雅解决 OpenCV 分段错误(Segfault):子进程隔离实战
  • pig框架导入总结
  • 动手学深度学习(pytorch版):第六章节—卷积神经网络(1)从全连接层到卷积
  • 新能源汽车热管理仿真:蒙特卡洛助力神经网络训练
  • Text2SQL、ChatBI简介
  • [Vid-LLM] 功能分类体系 | 视频如何被“观看“ | LLM的主要作用