目录
[SpringBoot Web入门](#SpringBoot Web入门)
**静态资源:**服务器上存储的不会改变的数据,通常不会根据用户的请求而变化。比如:HTML、CSS、JS、图片、视频等(负责页面展示)
动态资源: 服务器端根据用户请求和其他动态数据生成的,内容可能会在每次请求时都发生变化。比如:Servlet、JSP Spring框架 等(负责逻辑处理)
**B/S架构:**Browser/Server,浏览器/服务器架构模式。客户端只需浏览器,应用程序的逻辑和数据都存在服务器端(维护方便,体验一般)
**C/S架构:**Client/Server,客户端/服务器端架构模式。需要单独开发维护客户端(体验不错,开发维护麻烦)
SpringBoot Web入门
spring
官网:spring.io

java
package com.itheima;
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) {
System.out.println("name = " + name);
return "hello " + name + "!";
}
}
Spring官方脚手架连接不上解决方案

入门程序剖析
为什么一个main方法就将web应用启动?
起步依赖:

HTTP协议
**概念:**超文本传输协议(Hyper Text Transfer Protocol),规定了浏览器和服务器之间数据传输的规则

特点
1、基于TCP协议:面向连接,安全
2、基于请求-响应模型的:一次请求对应一次响应
3、HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的
- 缺点:多次请求间不能共享数据
- 优点:速度快
HTTP协议-请求协议
HTTP协议-请求数据格式

- **请求行:**请求数据第一行(请求方式、资源路径、协议)
- 请求头:第二行开始,格式key:value
常见的请求头

- **请求体:**POST请求,存放请求参数
请求方式-GET:请求参数在请求行中,没有请求体,如:/brand/findAll?name=OPPO&status=1.GETq请求大小在浏览器中是有限制的。
请求方式-POST:请求参数在请求体中,POST请求大小是没有限制的
HTTP协议-请求数据获取
web服务器(Tomcat)对HTTP协议的请求数据进行解析,并进行了封装(HttpServletRequest),在调用Controller方法的时候传递给了该方法。这样就使得程序员不必直接对协议进行操作,让web开发更加便捷。
java
package com.itheima;
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 request) {
//1、获取请求方式
String method = request.getMethod();
System.out.println("请求方式 = " + method);
//2、获取请求URL地址
String requestURL = request.getRequestURL().toString();
System.out.println("请求URL地址 = " + requestURL);
//3、获取请求协议
String protocol = request.getProtocol();
System.out.println("请求协议 = " + protocol);
//4、获取请求参数
String name = request.getParameter("name");
String age = request.getParameter("age");
System.out.println("name = " + name + " , age = " + age);
//5、获取请求头信息
String accept = request.getHeader("Accept");
System.out.println("请求头信息 Accept = " + accept);
return "OK";
}
}


HTTP协议-响应协议
HTTP协议-响应数据格式

- 响应行:响应数据第一行(协议、状态码、描述)
- 响应头:第二行开始,格式key:value
- 响应体:最后一部分,存放响应数据
常见的响应状态码:



常见的响应头:

HTTP协议-响应数据设置
web服务器(Tomcat)对HTTP协议的响应数据进行了封装(HttpServletReponse),并在调用Controller方法的时候传递给了该方法。这样就使得程序员不必直接对协议进行操作,让web开发更加便捷。
java
package com.itheima;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@RestController
public class ResponseController {
// 方式一:HttpServletReponse 设置响应数据
@RequestMapping("/response")
public void response(HttpServletResponse response) throws IOException {
//1、设置响应状态码
response.setStatus(401);
//2、设置响应头
response.setHeader("name","itheima");
//3、设置响应体
response.getWriter().write("<h1>hello response</h1>");
}
//方式二:ResponseEntity 设置响应数据-Spring中提供的方式
@RequestMapping("/response2")
public ResponseEntity<String> response2(){
return ResponseEntity
.status(401)
.header("name","javaweb-ai")
.body("<h1>hello responseEntity</h1>");
}
}

SpringBootWeb案例


java
@RestController
public class UserController {
@RequestMapping("/list")
public List<User> list() throws Exception {
//1、加载并读取user.text文件,获取用户数据
//InputStream in = new FileInputStream(new File("D:\\code\\java_code\\web-ai-code\\web-ai-project01\\springboot-web-01\\src\\main\\resources\\user.txt"));
InputStream in = this.getClass().getClassLoader().getResourceAsStream("user.txt");
ArrayList<String> lines = IoUtil.readLines(in, StandardCharsets.UTF_8,new ArrayList<>());
//2、解析用户信息,封装为user对象->list集合
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);
}).collect(Collectors.toList());
//3、返回JSON格式的用户数据
return userList;
}
分层解耦
三层架构


**controller:**控制层,接收前端发送的请求,对请求进行处理,并响应数据
**service:**业务逻辑层,处理具体的业务逻辑
**dao:**数据访问层(持久层),负责数据访问操作,包括数据的增删改查
**耦合:**衡量软件中各个层/各个模块的依赖关联程度
**内聚:**软件中各个模块内部的功能联系
**软件设计原则:**高内聚低耦合
分层解耦的思路: 

IOC详解
要把某个对象交给IOC容器管理,需要在对应的类上加上如下注解之一:

声明bean时,可以通过注解的value属性指定bean的名字,如果没有指定,默认为类名首字母小写

DI详解
基于@Autowired进行依赖注入的常见方式由如下三种:
1、属性注入

**优点:**代码简洁,方便快速开发
**缺点:**隐藏了类之间的依赖关系、可能会破坏类的封装性
2、构造函数注入

如果当前类中只有一个构造函数,@Autowired可以省略
**优点:**能够清晰地看到类的依赖关系、提高了代码的安全性
**缺点:**代码繁琐、如果构造参数过多,可能会导致构造函数臃肿
3、setter注入

**优点:**保持类的封装性,依赖关系更清晰
**缺点:**需要额外编写setter方法,增加了代码量
java
// //方式一:属性注入
// @Autowired
// private UserService userService;
//方式二:构造器注入
// private final UserService userService;
// @Autowired
// public UserController(UserService userService) {
// this.userService = userService;
// }
//方式三:setter注入
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
@Autowired注解,默认是按照类型进行注入的
如果存在多个相同类型的bean,将会报出如下错误:

解决方案:
