快速入门Web开发(中)后端开发(有重点)(2)

本文涉及的产品
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 快速入门Web开发(中)后端开发(有重点)(2)

快速入门Web开发(中)后端开发(有重点)(1):https://developer.aliyun.com/article/1548582


什么是控制器?

控制器(Controller)是MVC(Model-View-Controller)设计模式中的一个组件,用于接收用户的请求并处理请求的逻辑。控制器负责从用户请求中提取数据,调用合适的业务逻辑进行处理,并返回响应给用户。

控制器在Web应用程序中起到了桥梁的作用,它接收来自用户的请求,并根据请求的内容决定如何处理。控制器通常包含多个处理方法,每个方法对应不同的请求路径和请求方法,用于处理不同的请求。

控制器的主要作用包括:

  1. 接收请求:控制器监听来自客户端的请求,根据请求的路径和方法来确定调用哪个处理方法。
  2. 处理请求:控制器中的处理方法会根据业务逻辑对请求进行处理,可能会操作数据库、调用其他服务等。
  3. 提取数据:控制器从请求中提取所需的数据,例如请求参数、请求头、请求体等。
  4. 调用服务:控制器可能需要调用其他服务或组件来完成请求的处理,例如调用业务逻辑组件、数据访问组件等。
  5. 返回响应:控制器根据请求的处理结果生成响应数据,可以是HTML页面、JSON数据、XML数据等。

在Web开发中,控制器通常与视图(View)和模型(Model)一起工作,通过模型从数据库或其他数据源中获取数据,并将数据传递给视图进行渲染,最终返回给用户显示。

  • 控制器的表现形式就是注解

@RestController

  • 是一个注解,用于将类标记为RESTful风格的控制器。

@RequestMapping

  • 这个注解使得被拦截的请求能与被注解的方法进行配对,配对成功了,就按照方法内的代码工作。其中,返回是返回给客户端的

**基本用法:**在控制器类或方法上使用 @RequestMapping 注解,指定请求的 URL 路径。例如:

javaCopy code@RequestMapping("/hello")
public String hello() {
  return "Hello, World!";
  • 该注解有很多用法,自行百度

为什么你能通过一小段代码来访问网页?(重点)

要明白这件事,首先要知道我们是如何访问网站的

访问网页的本质涉及多个技术层面,从用户输入网址到最终在浏览器上看到页面的过程包含了多个步骤:

  1. 域名解析:当你在浏览器中输入一个网址(URL),比如 http://www.example.com,浏览器首先需要将这个域名解析成对应的 IP 地址。这个过程通过域名系统(DNS)完成,将易于记忆的域名映射到实际的服务器 IP 地址。(本地)
  2. 发起连接:一旦浏览器获得了服务器的 IP 地址,它就会通过网络协议(通常是 HTTP 或 HTTPS)与服务器建立连接。这个过程涉及多个网络层的交互,包括 TCP/IP 协议等。(网络通信)
  3. 发送请求:浏览器发送一个 HTTP 请求给服务器,这个请求包含了请求的类型(GET、POST 等)、路径、头部信息(例如浏览器类型)、可能的请求体(对于 POST 请求)等。(网络通信)
  4. 服务器处理:服务器接收到请求后,根据请求的路径以及其他信息,决定要执行哪些操作。这通常涉及到服务器端的应用程序,比如一个 Web 应用程序。在以上的图片中,就是 Spring Boot 中的控制器方法。(服务器本地)
  5. 生成响应:服务器处理请求后,会生成一个 HTTP 响应。这个响应包括了响应的状态码(例如 200 OK、404 Not Found)、响应头部(例如内容类型),以及响应体(实际的数据内容)。(服务器本地)
  6. 传输响应:服务器将生成的 HTTP 响应通过网络传输回浏览器。(网络通信)
  7. 浏览器处理:浏览器接收到响应后,会根据响应的内容类型(例如 HTML、CSS、JavaScript 等)进行处理。浏览器会解析 HTML,构建 DOM(文档对象模型),加载和解析 CSS 样式,执行 JavaScript 等操作。(本地)
  8. 渲染页面:浏览器根据 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();
  1. this.getClass():获取当前对象所属的类。
  2. getClassLoader():获取类加载器对象。
  3. getResource("emp.xml"):通过类加载器对象的getResource()方法,传入资源文件的相对路径(相对于类路径),返回一个URL对象,指向该资源文件。
  4. 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 + '\'' +
                '}';
    }
}

https://www.bilibili.com/video/BV1m84y1w7Tb?p=74&spm_id_from=pageDriver&vd_source=077127c579b82c23164b07dbc24cd570

分层解耦

三层结构

  • 使得一个类或者一个接口只做一件事
  • 其中,数据的来源可能有很多。因此凭借接口实现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

目录
相关文章
|
4天前
|
IDE Java 开发工具
Spring Boot:加速Java后端开发的现代化利器
在当今快速迭代的软件开发环境中,Spring Boot 已成为Java后端开发领域的首选框架。作为Spring家族的一员,它以“约定优于配置”的设计理念,极大地简化了传统Spring应用的配置和部署过程,让开发者能够更加专注于业务逻辑的实现。本文将探讨Spring Boot的核心优势,并通过一个简单的示例展示如何快速启动一个基于Spring Boot的Java Web应用。
22 1
|
2天前
|
安全 编译器 API
探索PHP 8的新特性及其对现代Web开发的影响
随着PHP 8的正式发布,这一版本带来了多项重大改进和新特性,旨在提升性能、增加语言的灵活性并简化开发流程。本文将详细探讨PHP 8中的关键更新,包括JIT编译器、联合类型、命名参数、匹配表达式等,并分析这些新特性如何影响现代Web开发的实践。通过引用最新的性能数据和开发者反馈,我们将深入理解PHP 8带来的变革,以及它对现有项目和未来趋势的潜在影响。
|
2天前
|
安全 大数据 PHP
深入理解PHP 7中的新特性及其对现代Web开发的影响
【6月更文挑战第28天】本文将深入探讨PHP 7带来的革新,从性能提升到语法改进,揭示这些变化如何重塑Web开发领域。我们将一窥未来PHP的发展趋势,并分析开发者如何利用这些新特性来构建更快、更安全、更易于维护的应用程序。
7 1
|
1天前
|
分布式计算 并行计算 安全
在Python Web开发中,Python的全局解释器锁(Global Interpreter Lock,简称GIL)是一个核心概念,它直接影响了Python程序在多线程环境下的执行效率和性能表现
【6月更文挑战第30天】Python的GIL是CPython中的全局锁,限制了多线程并行执行,尤其是在多核CPU上。GIL确保同一时间仅有一个线程执行Python字节码,导致CPU密集型任务时多线程无法充分利用多核,反而可能因上下文切换降低性能。然而,I/O密集型任务仍能受益于线程交替执行。为利用多核,开发者常选择多进程、异步IO或使用不受GIL限制的Python实现。在Web开发中,理解GIL对于优化并发性能至关重要。
14 0
|
2天前
|
安全 编译器 测试技术
探索PHP 8的新特性及其对现代Web开发的影响
随着PHP 8的发布,这一广泛使用的服务器端脚本语言迎来了重大更新。本文将深入探讨PHP 8引入的关键新特性,如JIT编译器、联合类型、命名参数等,并通过性能测试和案例研究,揭示这些更新如何优化代码效率、增强类型安全和提升开发体验。我们还将分析PHP 8对现有项目升级路径的挑战与机遇,以及它如何影响未来Web开发的走向。
|
3天前
|
缓存 Java 测试技术
Java中的Web服务开发与优化技巧
Java中的Web服务开发与优化技巧
|
3天前
|
设计模式 监控 测试技术
后端开发中的微服务架构:优势、挑战与实践策略
在现代软件开发领域,微服务架构已成为一种重要的设计范式,特别是在后端系统中。本文旨在深入探讨微服务架构的核心优势、面临的主要挑战以及实施该架构的策略。通过引用最新的研究成果和行业案例,文章将提供对微服务架构实际应用的深刻见解,并指导开发者如何有效地采用和优化微服务架构以提升系统性能和可维护性。
|
5天前
|
JavaScript 程序员 应用服务中间件
快速入门Web开发(上) 黑马程序员JavaWeb开发教程(2)
快速入门Web开发(上) 黑马程序员JavaWeb开发教程(2)
19 7
|
5天前
|
JSON 前端开发 Java
一文读Web开发 之接口后端接口、类与前端请求、拦截器编写
一文读Web开发 之接口后端接口、类与前端请求、拦截器编写
21 6
|
5天前
|
XML 存储 JavaScript
快速入门Web开发(上) 黑马程序员JavaWeb开发教程(1)
快速入门Web开发(上) 黑马程序员JavaWeb开发教程(1)
16 5