快速入门Web开发(中)后端开发(有重点)(1):https://developer.aliyun.com/article/1548582
什么是控制器?
控制器(Controller)是MVC(Model-View-Controller)设计模式中的一个组件,用于接收用户的请求并处理请求的逻辑。控制器负责从用户请求中提取数据,调用合适的业务逻辑进行处理,并返回响应给用户。
控制器在Web应用程序中起到了桥梁的作用,它接收来自用户的请求,并根据请求的内容决定如何处理。控制器通常包含多个处理方法,每个方法对应不同的请求路径和请求方法,用于处理不同的请求。
控制器的主要作用包括:
- 接收请求:控制器监听来自客户端的请求,根据请求的路径和方法来确定调用哪个处理方法。
- 处理请求:控制器中的处理方法会根据业务逻辑对请求进行处理,可能会操作数据库、调用其他服务等。
- 提取数据:控制器从请求中提取所需的数据,例如请求参数、请求头、请求体等。
- 调用服务:控制器可能需要调用其他服务或组件来完成请求的处理,例如调用业务逻辑组件、数据访问组件等。
- 返回响应:控制器根据请求的处理结果生成响应数据,可以是HTML页面、JSON数据、XML数据等。
在Web开发中,控制器通常与视图(View)和模型(Model)一起工作,通过模型从数据库或其他数据源中获取数据,并将数据传递给视图进行渲染,最终返回给用户显示。
- 控制器的表现形式就是注解
@RestController
- 是一个注解,用于将类标记为RESTful风格的控制器。
@RequestMapping
- 这个注解使得被拦截的请求能与被注解的方法进行配对,配对成功了,就按照方法内的代码工作。其中,返回是返回给客户端的
**基本用法:**在控制器类或方法上使用 @RequestMapping
注解,指定请求的 URL 路径。例如:
javaCopy code@RequestMapping("/hello") public String hello() { return "Hello, World!";
- 该注解有很多用法,自行百度
为什么你能通过一小段代码来访问网页?(重点)
要明白这件事,首先要知道我们是如何访问网站的
访问网页的本质涉及多个技术层面,从用户输入网址到最终在浏览器上看到页面的过程包含了多个步骤:
- 域名解析:当你在浏览器中输入一个网址(URL),比如
http://www.example.com
,浏览器首先需要将这个域名解析成对应的 IP 地址。这个过程通过域名系统(DNS)完成,将易于记忆的域名映射到实际的服务器 IP 地址。(本地) - 发起连接:一旦浏览器获得了服务器的 IP 地址,它就会通过网络协议(通常是 HTTP 或 HTTPS)与服务器建立连接。这个过程涉及多个网络层的交互,包括 TCP/IP 协议等。(网络通信)
- 发送请求:浏览器发送一个 HTTP 请求给服务器,这个请求包含了请求的类型(GET、POST 等)、路径、头部信息(例如浏览器类型)、可能的请求体(对于 POST 请求)等。(网络通信)
- 服务器处理:服务器接收到请求后,根据请求的路径以及其他信息,决定要执行哪些操作。这通常涉及到服务器端的应用程序,比如一个 Web 应用程序。在以上的图片中,就是 Spring Boot 中的控制器方法。(服务器本地)
- 生成响应:服务器处理请求后,会生成一个 HTTP 响应。这个响应包括了响应的状态码(例如 200 OK、404 Not Found)、响应头部(例如内容类型),以及响应体(实际的数据内容)。(服务器本地)
- 传输响应:服务器将生成的 HTTP 响应通过网络传输回浏览器。(网络通信)
- 浏览器处理:浏览器接收到响应后,会根据响应的内容类型(例如 HTML、CSS、JavaScript 等)进行处理。浏览器会解析 HTML,构建 DOM(文档对象模型),加载和解析 CSS 样式,执行 JavaScript 等操作。(本地)
- 渲染页面:浏览器根据 DOM 结构和 CSS 样式对页面进行渲染,最终在浏览器窗口中呈现出用户可见的页面。(本地)
当你启动 Spring Boot 项目并且访问 http://localhost:8080
或其他定义的路径时,Spring Boot 内置的 Web 服务器( Tomcat 或其他容器)会拦截这些请求,并将请求映射到相应的控制器方法。控制器方法执行完成后,返回的内容会被直接写入 HTTP 响应,然后返回给浏览器进行显示。
响应数据
- 以上几个方法被称为功能接口
- 这样开发不便管理
package com.itheima.pojo; /** * 统一响应结果封装类 */ 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 + '}'; } }
@RequestMapping("/hello") public Result hello(){ System.out.println("Hello World ~"); //return new Result(1,"success","Hello World ~"); return Result.success("Hello World ~"); }
- 仔细观看以上代码就懂了
案列
//文件寻址 String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
this.getClass()
:获取当前对象所属的类。getClassLoader()
:获取类加载器对象。getResource("emp.xml")
:通过类加载器对象的getResource()
方法,传入资源文件的相对路径(相对于类路径),返回一个URL
对象,指向该资源文件。getFile()
:通过URL
对象的getFile()
方法,获取资源文件在文件系统中的绝对路径。
最终,将获取到的绝对路径赋值给file
变量
关于类加载器
类加载器对象(ClassLoader Object)是Java中用于加载类文件的工具。它负责将类的字节码文件加载到Java虚拟机中,并转换为可执行的类对象。
在Java中,每个类加载器都是一个ClassLoader对象。ClassLoader对象负责查找类文件、加载类文件、定义类和管理类的生命周期。每个类加载器都有一个父类加载器(除了引导类加载器),它们按照一定的层次结构进行组织。
package com.itheima.controller; import com.itheima.pojo.Emp; import com.itheima.pojo.Result; import com.itheima.utils.XmlParserUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @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);//XmlParserUtils对象用来处理xml文件 //2. 对数据进行转换处理 - gender, job(处理数据) empList.stream().forEach(emp -> {//使用lambda表达式,相当于js中的箭头函数。 //处理 gender 1: 男, 2: String gender = emp.getGender();//类里面 //为什么emp没有声明为Emp类型的数据却能使用Emp类中的方法? //因为lambda表达式中的emp(这个位置的变量)是通过上下文来判断类型。 //而empList是Emp类数据 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); } }
package com.itheima.pojo; public class Emp { private String name; private Integer age; private String image; private String gender; private String job; public Emp() { } public Emp(String name, Integer age, String image, String gender, String job) { this.name = name; this.age = age; this.image = image; this.gender = gender; this.job = job; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getJob() { return job; } public void setJob(String job) { this.job = job; } @Override public String toString() { return "Emp{" + "name='" + name + '\'' + ", age=" + age + ", image='" + image + '\'' + ", gender='" + gender + '\'' + ", job='" + job + '\'' + '}'; } }
见
分层解耦
三层结构
- 使得一个类或者一个接口只做一件事
- 其中,数据的来源可能有很多。因此凭借接口实现dao层
- 这样将代码单一功能化,也称为高内聚
分层解耦(高内聚低耦合(最好没有耦合))
- 因为引用,现在会有耦合
- 要切换成b类,不止一处地方需要变动
- 使用容器来解耦
controller层与前端交互
控制反转
- 一种设计的思路
@Component
是一个注解(Annotation),在Spring框架中用于标识一个类为组件(Component)。
在Spring中,组件是指可被自动扫描和实例化的类。通过使用@Component
注解,告诉Spring框架将被标注的类作为组件进行管理。被标注的EmpserviceA称为loc中的bean@Autowired
是一个注解(Annotation),在Spring框架中用于实现依赖注入(Dependency Injection)。
依赖注入是指将一个对象的依赖关系由容器动态地注入到对象中,而不是由对象自己创建或查找依赖对象。通过使用@Autowired
注解,可以告诉Spring框架自动装配相应的依赖对象。- 容器需要把要用的都加到容器里去
当要切换不同的dao层时,就通过操作@Component来改变容器存储不同
- 寻找RestController的实现
组件扫描
- 指定后,默认扫描包会更改,因此还要加上原来的包
- Primary更改优先级别
- Qualifier/Resource设置访问
数据库(有重点)
通用规则
流程
- 创建数据库一般有这两个字段
DQL
查询所有字段不要用星号,效率低下
-- if语句 select if(gender=1,'男性','女性'),count(*) from tb_emp group by gender ; -- case语句 select (case job when 1 then '班主任' when 2 then '讲师' when 3 then '学工主管' when 4 then '教研主管' else '无职位' end) ,count(*) from tb_emp group by job;
快速入门Web开发(中)后端开发(有重点)(3):https://developer.aliyun.com/article/1548588