Spring - 3 ( 12000 字 Spring 入门级教程 )

news2024/12/23 18:13:55

一:Spring Web MVC入门

1.1 响应

在我们前⾯的代码例子中,都已经设置了响应数据, Http 响应结果可以是数据, 也可以是静态页面,也可以针对响应设置状态码, Header 信息等.

1.2 返回静态页面

创建前端页面 index.html(注意路径)

在这里插入图片描述

  1. html代码
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<title>Index⻚⾯</title>
</head>

<body>
Hello,Spring MVC,我是Index⻚⾯.
</body>

</html>
  1. 后台代码:
@RestController
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
		//返回index.html
        return "/index.html";
    }
}

运行结果:http://127.0.0.1:8080/index

在这里插入图片描述
结果却发现, 页面未正确返回, http响应把 “/index.html” 当做了http响应正文的数据,那 Spring MVC 如何才能识别出来 index.html 是⼀个静态页面, 并进行返回呢?

我们需要把 @RestController 改为 @Controller

正确代码如下:

@Controller
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        return "/index.html";
    }
}

再次运行: http://127.0.0.1:8080/index

在这里插入图片描述
发现页面正确展示了

@RestController 和 @Controller 有着什么样的关联和区别呢,咱们前⾯讲了MVC模式, 后端会返回视图, 这是早期时的概念

在这里插入图片描述
随着互联网的发展, 目前项目开发流行"前后端分离"模式, Java 主要是用来做后端项目的开发, 所以也就不再处理前端相关的内容了

因此 MVC 的概念也逐渐发生了变化, View 不再返回视图, 而是返回显示视图时需要的数据.所以前⾯使⽤的 @RestController 其实是返回的数据.

其实 @RestController = @Controller + @ResponseBody

  • @Controller : 定义⼀个控制器, Spring 框架启动时加载, 把这个对象交给Spring管理.
  • @ResponseBody : 定义返回的数据格式为非视图, 返回⼀个 text/html 信息

所以如果想返回视图的话, 只需要用 @Controller 就可以了

1.3 返回数据@ResponseBody

我们上⾯讲到, @ResponseBody 表示返回数据.

@Controller
@ResponseBody
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        return "/index.html";
    }
}

加上 @ResponseBody 注解, 该方法就会把 “/index.html” 当做⼀个数据返回给前端.

运行:http://127.0.0.1:8080/index

在这里插入图片描述
@ResponseBody 既是类注解, ⼜是方法注解

  • 如果作用在类上, 表示该类的所有方法, 返回的都是数据,
  • 如果作用在方法上, 表示该方法返回的是数据.

也就是说: 在类上添加 @ResponseBody 就相当于在所有的方法上添加了 @ResponseBody 注解.同样, 如果类上有 @RestController 注解时:表示所有的方法上添加了 @ResponseBody 注解

如果⼀个类的方法里, 既有返回数据的, 又有返回页面的, 就把 @ResponseBody 注解添加到需要返回页面的方法上即可.

@Controller
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        return "/index.html";
    }
    @RequestMapping("/returnData")
    @ResponseBody
    public String returnData(){
        return "该⽅法返回数据";
    }
}

多个注解时, 没有先后顺序, 先写哪个都可以

运行程序, 浏览器响应结果如下: http://127.0.0.1:8080/returnData

在这里插入图片描述
如果去掉 @ResponseBody 注解, 程序会报404错误,程序会认为需要返回的是视图, 根据内容去查找文件, 但是查询不到, 路径不存在, 报404

在这里插入图片描述

1.4 返回HTML代码片段

后端返回数据时, 如果数据中有 HTML 代码, 也会被浏览器解析

@RequestMapping("/returnHtml")
@ResponseBody
public String returnHtml() {
        return "<h1>Hello,HTML~</h1>";
}

运行程序, 浏览器响应结果如下: http://127.0.0.1:8080/returnHtml

在这里插入图片描述
通过 Fiddler 观察响应结果, Content-Type 为 text/html

在这里插入图片描述
响应中的 Content-Type 常见取值有以下几种:

  • text/html : body 数据格式是 HTML
  • text/css : body 数据格式是 CSS
  • application/javascript : body 数据格式是 JavaScript
  • application/json : body 数据格式是 JSON

1.5 返回JSON

Spring MVC 也可以返回 JSON

后端方法返回结果为对象:

@RequestMapping("/returnJson")
@ResponseBody
public HashMap<String, String> returnJson() {
        HashMap<String, String> map = new HashMap<>();
        map.put("Java", "Java Value");
        map.put("MySQL", "MySQL Value");
        map.put("Redis", "Redis Value");
        return map;
}

运行程序, 浏览器响应结果如下: http://127.0.0.1:8080/returnJson

在这里插入图片描述
过 Fiddler 观察响应结果, Content-Type 为 application/json

在这里插入图片描述

1.6 设置状态码

Spring MVC 会根据我们方法的返回结果自动设置响应状态码, 程序员也可以手动指定状态码,状态码可以通过 Spring MVC 的内置对象 HttpServletResponse 提供的方法来进行设置

@RequestMapping(value = "/setStatus")
@ResponseBody
public String setStatus(HttpServletResponse response) {
        response.setStatus(401);
        return "设置状态码成功";
}

运行程序, 浏览器响应结果如下: http://127.0.0.1:8080/setStatus

在这里插入图片描述
通过 Fiddler 来观察设置的结果:

在这里插入图片描述

1.7 设置Header (了解)

Http 响应报头也会向客户端传递⼀些附加信息,这些信息通过 @RequestMapping 注解的属性来实现

先来看 @RequestMapping 的源码:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";
    @AliasFor("path")
    String[] value() default {};
    @AliasFor("value")
    String[] path() default {};
    RequestMethod[] method() default {};
    String[] params() default {};
    String[] headers() default {};
    String[] consumes() default {};
    String[] produces() default {};
}
  1. value: 指定映射的URL
  2. method: 指定请求的 method 类型, 如GET, POST等
  3. consumes: 指定处理请求的 Content-Type,例如 application/json,text/html;
  4. produces: 指定返回的内容类型,仅当 request 请求头中的 Accept 类型中包含该指定类型才返回
  5. Params: 指定 request 中必须包含某些参数值时,才让该方法处理
  6. headers: 指定 request 中必须包含某些指定的 header 值,才能让该方法处理请求

1.8 设置 Content-Type

我们通过设置 produces 属性的值, 设置响应的报头 Content-Type

@RequestMapping(value = "/returnJson2",produces = "application/json")
@ResponseBody
public String returnJson2() {
        return "{\"success\":true}";
}

运行程序, 浏览器响应结果如下:http://127.0.0.1:8080/returnJson2

在这里插入图片描述
通过 Fiddler 来观察设置的结果:

在这里插入图片描述
如果不设置 produces , 方法返回结果为 String 时, Spring MVC 默认返回类型是 text/html.

1.9 设置其他Header

设置其他 Header 的话, 需要使⽤ Spring MVC 的内置对象 HttpServletResponse 提供的方法来进行设置

@RequestMapping(value = "/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {
        response.setHeader("MyHeader","MyHeaderValue");
        return "设置Header成功";
}

void setHeader(String name, String value) 设置⼀个带有给定的名称和值的 header. 如果 name已经存在, 则覆盖旧的值.

运行程序, 浏览器响应结果如下: http://127.0.0.1:8080/setHeader

在这里插入图片描述
通过 Fiddler 来观察设置的结果:
在这里插入图片描述

二:综合性练习

结合上述内容, 我们可以做⼀些小案例,主要掌握知识点:

  1. 理解前后端交互过程
  2. 接口传参, 数据返回, 以及页面展示

2.1 加法计算器

需求: 输入两个整数, 点击 “点击相加” 按钮, 显示计算结果

在这里插入图片描述

  1. 创建 SpringBoot 项目: 引⼊ Spring Web 依赖, 把前端页面放在项目中

在这里插入图片描述

  1. 约定前后端交互接口:

首先进行需求分析:加法计算器功能, 对两个整数进行相加, 需要客户端提供参与计算的两个数, 服务端返回这两个整数计算的结果,基于以上分析, 我们来定义接口:

接口定义:

请求路径:calc/sum
请求⽅式:GET/POST
接⼝描述:计算两个整数相加

请求参数:

参数名类型是否必须备注
num1Integer参与计算的第⼀个数
num2Integer参与计算的第⼆个数

响应数据:

Content-Type: text/html
响应内容: 计算机计算结果: 8

2.1.1 服务器代码

@RestController
@RequestMapping("/calc")
public class CalcController {
    @RequestMapping("/sum")
    public String sum(Integer num1,Integer num2){
        Integer sum = num1+num2;
        return "<h1>计算机计算结果: "+sum+"</h1>";
    }
}

2.1.2 调整前端页面代码

<form action="calc/sum" method="post">
    <h1>计算器</h1>
    数字1:<input name="num1" type="text"><br>
    数字2:<input name="num2" type="text"><br>
    <input type="submit" value=" 点击相加">
</form>

2.1.3 运行测试

启动服务, 运行并测试
在这里插入图片描述

2.2 图书管理系统

需求:

  1. 登录: 用户输⼊账号,密码完成登录功能
  2. 列表展示: 展示图书

在这里插入图片描述
在这里插入图片描述

  1. 准备工作

创建新项目, 引入对应依赖, 把前端页面放在项目中

  1. 约定前后端交互接口

需求分析:图书管理系统是⼀个相对较大一点的案例, 咱们先实现其中的⼀部分功能.

  • 用户登录

在这里插入图片描述

  • 图书列表

在这里插入图片描述

根据需求可以得知, 后端需要提供两个接口

  1. 账号密码校验接口: 根据输入用户名和密码校验登录是否通过
  2. 图书列表: 提供图书列表信息

接口定义:

  1. 登录接⼝
[URL]
POST /user/login
[请求参数]
name=admin&password=admin
[响应]
true //账号密码验证成功
false//账号密码验证失败
  1. 图书列表展示
[URL]
POST /book/getList
[请求参数][响应]
返回图书列表
[
{
"id": 1,
"bookName": "活着",
"author": "余华",
"count": 270,
"price": 20,
"publish": "北京⽂艺出版社",
"status": 1,
"statusCN": "可借阅"
},
...
]
  1. 字段说明:
参数名类型是否必须备注
idInteger图书ID
bookNameString图书名称
authorString作者
countInteger数量
priceDouble定价
publishString图书出版社
statusInteger图书状态
statusCNString图书状态中文含义

2.2.1 服务器代码

  1. 创建图书类 BookInfo
@Data
public class BookInfo {
    //图书ID
    private Integer id;
    //书名
    private String bookName;
    //作者
    private String author;
    //数量
    private Integer count;
    //定价
    private BigDecimal price;
    //出版社
    private String publish;
    //状态 0-⽆效 1-允许借阅   2-不允许借阅
    private Integer status;
    private String statusCN;
    //创建时间
    private Date createTime;
    //更新时间
    private Date updateTime;
}
  1. 创建 UserController, 实现登录验证接口
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/login")
    public boolean login(String name, String password, HttpSession session){
		//账号或密码为空
        if (!StringUtils.hasLength(name) || !StringUtils.hasLength(password)){
            return false;
        }
		//模拟验证数据, 账号密码正确
        if("admin".equals(name) && "admin".equals(password)){
            session.setAttribute("userName",name);
            return true;
        }
		//账号密码错误
        return false;
    }
}
  1. 创建 BookController, 获取图书列表
@RequestMapping("/book")
@RestController
public class BookController {
    @RequestMapping("/getList")
    public List<BookInfo> getList(){
		//获取数据
        List<BookInfo> books = mockData();
		//处理⻚⾯展⽰
        for (BookInfo book:books){
            if (book.getStatus()==1){
                book.setStatusCN("可借阅");
            }else {
                book.setStatusCN("不可借阅");
            }
        }
        return books;
    }
		/**
		 * 数据Mock 获取图书信息
		 *
		 * @return
		 */
public List<BookInfo> mockData() {
    List<BookInfo> books = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
        BookInfo book = new BookInfo();
        book.setId(i);
        book.setBookName("书籍" + i);
        book.setAuthor("作者" + i);
        book.setCount(i * 5 + 3);
        book.setPrice(new BigDecimal(new Random().nextInt(100)));
        book.setPublish("出版社" + i);
        book.setStatus(1);
        books.add(book);
    }
    return books;
}

}

在这个实例中数据采⽤ mock(假数据) 的方式, 实际数据应该从数据库中获取

2.2.2 调整前端页面代码

  1. 登录页面:

添加登录处理逻辑

<script src="js/jquery.min.js"></script>
<script>
    function login() {
        $.ajax({
            type: "post",
            url: "/user/login",
            data: {
                name: $("#userName").val(),
                password: $("#password").val()
            },
            success: function (result) {
                if (result) {
                    location.href = "book_list.html";
                } else {
                    alert("账号或密码不正确!");
                }
            }
        });
    }
</script>
  1. 图书列表展示:

删除前端伪造的代码, 从后端获取数据并渲染到页面上

function getBookList() {
    $.ajax({
        type: "get",
        url: "/book/getList",
        success: function(result) {
            console.log(result);
            if (result != null) {
                var finalHtml = "";
                for (var book of result) {
                    finalHtml += '<tr>';
                    finalHtml += '<td><input type="checkbox" name="selectBook"></td>';
                    finalHtml += '<td>' + book.id + '</td>';
                    finalHtml += '<td>' + book.bookName + '</td>';
                    finalHtml += '<td>' + book.author + '</td>';
                    finalHtml += '<td>' + book.count + '</td>';
                    finalHtml += '<td>' + book.price + '</td>';
                    finalHtml += '<td>' + book.publish + '</td>';
                    finalHtml += '<td>' + book.statusCN + '</td>';
                    finalHtml += '<td><div class="op">';
                    finalHtml += '<a href="book_update.html?bookId=' + book.id + '">Update</a>';
                    finalHtml += '<a href="javascript:void(0)" οnclick="deleteBook(' + book.id + ')">Delete</a>';
                    finalHtml += '</div></td>';
                    finalHtml += '</tr>';
                }
                $("tbody").html(finalHtml);
            }
        }
    });
}

2.2.3 运行测试

访问: http://127.0.0.1:8080/login.html

输入账号密码: admin admin, 登录成功, 跳转到图书列表页,界⾯展示:

在这里插入图片描述

三:lombok

3.1 lombok介绍

Lombok 是⼀个 Java 工具库,通过添加注解的方式,简化 Java 的开发.

下面来简单来学习下它的使用:

  1. 引入依赖
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<optional>true</optional>
</dependency>
  1. 使用

lombok通过⼀些注解的方式, 可以帮助我们消除⼀些冗长代码, 使代码看起来简洁⼀些,比如之前的 Person 对象 就可以改为

@Data
public class Person {
    private int id;
    private String name;
    private String password;
}

@Data 注解会帮助我们⾃动⼀些方法, 包含 getter/setter, equals, toString 等

  1. 原理解释

加了 @Data 注解之后, Idea 反编译的 class ⽂件,不是真正的字节码文件,而是 Idea 根据字节码进行反编译后的文件

反编译是将可执行的程序代码转换为某种形式的高级编程语言, 使其具有更易读的格式. 反编译是⼀种逆向工程,它的作用与编译器的作用相反

在这里插入图片描述
在这里插入图片描述
可以看出来, lombok 是⼀款在编译期生成代码的工具包.

  • Java 程序的运行原理:

在这里插入图片描述

  • Lombok 的作用如下图所示:

在这里插入图片描述
4. 更多使用

如果觉得 @Data 比较粗暴(生成方法太多), lombok 也提供了⼀些更精细粒度的注解

注解作用
@Getter自动添加 getter 方法
@Setter自动添加 setter 方法
@ToString自动添加 toString 方法
@EqualsAndHashCode自动添加 equals 和 hashCode 方法
@NoArgsConstructor自动添加无参构造方法
@AllArgsConstructor自动添加全属性构造方法,顺序按照属性的定义顺序
@NonNull属性不能为 null
@RequiredArgsConstructor自动添加必需属性的构造方法,final + @NonNull 的属性为必需

@Data = @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor+@NoArgsConstructor

3.2 更快捷的引入依赖

上述引入 lombok 依赖, 需要去找 lombok 的坐标,接下来介绍更简单引入依赖的⽅式

  1. 安装插件 EditStarter, 重启 Idea

在这里插入图片描述

  1. 在 pom.xml ⽂件中, 单击右键, 选择 Generate, 操作如下图所示

在这里插入图片描述

  1. 进入 Edit Starters 的编辑界⾯, 添加对应依赖即可.

在这里插入图片描述

注意:不是所有依赖都可以在这里添加的, 这个界面和 SpringBoot 创建项目界⾯⼀样,依赖不在这里的, 还需要去 Maven 仓库查找坐标, 添加依赖.

四: 应用分层

通过上面的练习, 我们学习了 Spring MVC 简单功能的开发, 但是我们也发现了⼀些问题:目前我们程序的代码有点 “杂乱”, 然而当前只是 “⼀点点功能” 的开发. 如果我们把整个项目功能完成呢?代码会更加的 “杂乱无章”

基于此, 咱们接下来学习应用分层.

在这里插入图片描述

阿里开发手册中, 关于工程结构部分, 定义了常见工程的应用分层结构:

在这里插入图片描述

  • 那么什么是应用分层呢?

应用分层是⼀种软件开发设计思想, 它将应用程序分成N个层次, 这N个层次分别负责各自的职责, 多个层次之间协同提供完整的功能,根据项目的复杂度, 把项目分成三层, 四层或者更多层

  • 为什么需要应用分层?

在最开始的时候,为了让项目快速上线,我们通常是不考虑分层的.

但是随着业务越来越复杂,大量的代码混在⼀起,会出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动⼀处就牵⼀发而动全身等问题. 所以我们需要对应用进行分层

  • 如何分层(三层架构)

咱们上⼀节中学习的 MVC, 就是把整体的系统分成了 Model(模型), View(视图)和Controller(控制器)三个层次

也就是将用户视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是⼀种标准的软件分层架构。

在这里插入图片描述

目前现在更主流的开发方式是 “前后端分离” 的方式, 后端开发工程师不再需要关注前端的实现,

所以对于Java后端开发者, ⼜有了⼀种新的分层架构: 把整体架构分为表现层、业务逻辑层和数据层. 这种分层⽅式也称之为"三层架构".

  1. 表现层: 就是展示数据结果和接受用户指令的,是最靠近用户的⼀层;
  2. 业务逻辑层: 负责处理业务逻辑, 里面有复杂业务的具体实现;
  3. 数据层: 负责存储和管理与应用程序相关的数据

可以看到, 咱们前面的代码, 并不符合这种设计思想, 我们将所有的代码堆砌在⼀起

在这里插入图片描述
按照上面的层次划分, Spring MVC 站在后端开发人员的角度上, 也进行了支持, 把上面的代码划分为三个部分:

  • 请求处理、响应数据:负责,接收页面的请求,给页面响应数据.
  • 逻辑处理:负责业务逻辑处理的代码.
  • 数据访问:负责业务数据的维护操作,包括增、删、改、查等操作.

这三个部分, 在Spring的实现中, 均有体现:

在这里插入图片描述

  • Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据。
  • Service:业务逻辑层。处理具体的业务逻辑。
  • Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查.

4.1 MVC 和三层架构的区别和联系

Spring MVC 是针对 Web 应用程序的一个具体框架,而三层架构是一种通用的软件架构模式,Spring MVC 是在表示层的基础上实现了 MVC 设计模式,而三层架构涵盖了整个应用程序,包括表示层、业务逻辑层和数据访问层。

在这里插入图片描述

4.2 代码重构

我们使用上⾯的分层思想, 来对代码进行改造

  1. 先创建对应的包路径, 并把代码移到对应的目录

在这里插入图片描述

  1. 控制层: 接收前端发送的请求,对请求进行处理,并响应数据
package com.example.demo.controller;
import com.example.demo.model.BookInfo;
import com.example.demo.service.BookService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequestMapping("/book")
@RestController
public class BookController {
    @RequestMapping("/getList")
    public List<BookInfo> getList(){
        BookService bookService = new BookService();
		//获取数据
        List<BookInfo> books = bookService.getBookList();
        return books;
    }
}
  1. 业务逻辑层: 处理具体的业务逻辑。
import com.example.demo.dao.BookDao;
import com.example.demo.model.BookInfo;
import java.util.List;
public class BookService {
    public List<BookInfo> getBookList(){
        BookDao bookDao = new BookDao();
        List<BookInfo> books = bookDao.mockData();
        for (BookInfo book:books){
            if (book.getStatus()==1){
                book.setStatusCN("可借阅");
            }else {
                book.setStatusCN("不可借阅");
            }
        }
        return books;
    }
}
  1. 数据访问层: 负责数据访问操作,包括数据的增、删、改、查
import java.util.List;
import java.util.Random;
public class BookDao {
    /**
     * 数据Mock 获取图书信息
     * @return
     */
    public List<BookInfo> mockData(){
        List<BookInfo> books = new ArrayList<>();
        for (int i=0;i<5;i++){
            BookInfo book = new BookInfo();
            book.setId(i);
            book.setBookName("书籍"+i);
            book.setAuthor("作者"+i);
            book.setCount(i*5+3);
            book.setPrice(new BigDecimal(new Random().nextInt(100)));
            book.setPublish("出版社"+i);
            book.setStatus(1);
            books.add(book);
        }
        return books;
    }
}

4.3 应用分层的好处

  • 降低层与层之间的依赖, 结构更加的明确, 利于各层逻辑的复用
  • 开发人员可以只关注整个结构中的其中某⼀层, 极大地降低了维护成本和维护时间
  • 可以很容易的用新的实现来替换原有层次的实现
  • 有利于标准化

4.4 5. 企业规范

  1. 类名使用大驼峰风格,但以下情形例外:DO/BO/DTO/VO/AO
  2. 方法名、参数名、成员变量、局部变量统⼀使用小驼峰风格
  3. 包名统⼀使⽤小写,点分隔符之间有且仅有⼀个自然语义的英语单词.

常见命名命名风格介绍

  • 大驼峰: 所有单词首字⺟都需要大写, 又叫帕斯卡命名法, 比如: UserController
  • 小驼峰: 除了第⼀个单词,其他单词首字⺟大写,比如: userController
  • 蛇形: 用下划线(_)作⽤单词间的分隔符, ⼀般小写, 又叫下划线命名法, 比如: user_controller
  • 串形: 用短横线(-)作⽤单词间的分隔符, ⼜叫脊柱命名法,比如: user-controller

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

frp 实现 http / tcp 内网穿透(穿透 wordpress )

frp 实现 http / tcp 内网穿透&#xff08;穿透 wordpress &#xff09; 1. 背景简介与软件安装2. 服务端配置2.1 配置文件2.2 wordpress 配置文件2.3 frps 自启动 3.客户端配置3.1 配置文件3.2 frpc 自启动 同步发布在个人笔记frp 实现 http / tcp 内网穿透&#xff08;穿透 w…

HZNUCTF -- web

HZNUCTF第五届校赛实践赛初赛 Web方向 WriteUp-CSDN博客 ezssti 下载文件 访问 /login 可由源代码中看到 Eval 函数 &#xff0c;可以任意命令执行 按照格式&#xff0c;可执行命令 POST &#xff1a;name{{.Eval "env"}} 可以得到flag &#xff08;尝试ls 只能列出…

就业班 第三阶段(负载均衡) 2401--4.19 day3

二、企业 keepalived 高可用项目实战 1、Keepalived VRRP 介绍 keepalived是什么keepalived是集群管理中保证集群高可用的一个服务软件&#xff0c;用来防止单点故障。 ​ keepalived工作原理keepalived是以VRRP协议为实现基础的&#xff0c;VRRP全称Virtual Router Redundan…

微软发布Phi-3 Mini,性能媲美GPT-3.5、Llama-3,可在手机端运行

前言 微软发布了最新版的Phi系列小型语言模型(SLM) - Phi-3。这个系列包括3个不同参数规模的版本&#xff1a;Phi-3 Mini (38亿参数)、Phi-3 Small (70亿参数)和Phi-3 Medium (140亿参数)。 Phi系列模型是微软研究团队开发的小规模参数语言模型。从第一代Phi-1到第二代Phi-2&…

kubebuilder(3)实现operator

在前面的文章我们已经了解了operator项目的基本结构。现在我们来写一点简单的代码&#xff0c;然后把我们的crd和operator部署到k8s集群中。 需求 这是一个真实的需求&#xff0c;只不过做了简化。 在开发公司自己的paas平台&#xff0c;有一个需求是&#xff0c;用户在发版…

【Linux高性能服务器编程】两种高性能并发模式剖析——领导者/追随者模式

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的Linux高性能服务器编程系列之两种高性能并发模式介绍&#xff0c;在这篇文章中&#xff0c;你将会学习到高效的创建自己的高性能服务器&#xff0c;并且我会给出源码进行剖析&#xff0c;以及手绘UML图来帮助大家来理解…

RK3588S和ARM阵列服务器在虚拟化云平台的应用

RK3588是瑞芯微2021年底推出的首款高端8nm旗舰芯片&#xff0c;而RK3588S 则是针对消费端市场在RK3588基础上缩减了部分外围接口&#xff0c;CPU、GPU和NPU等主要参数得到了保留&#xff0c;主要应用范围为高端ARM平板、ARM笔电产品&#xff0c;会议平板类、ARM服务器、智能机器…

利用遥感影像计算大蒜种植面积

大家对大蒜应该不陌生&#xff0c;近几年也经常以"蒜你狠"出现在大众视野。我国是世界大蒜的主要生产国、消费国和出口国&#xff0c;从事大蒜生产的蒜农达500万之多,大蒜产品也远销东南亚、东亚、中东、美洲、 欧洲等地区。大蒜的种植面积是大蒜市场行情的重要影响因…

DRF: 序列化器、View、APIView、GenericAPIView、Mixin、ViewSet、ModelViewSet的源码解析

前言&#xff1a;还没有整理&#xff0c;后续有时间再整理&#xff0c;目前只是个人思路&#xff0c;文章较乱。 注意路径匹配的“/” 我们的url里面加了“/”&#xff0c;但是用apifox等非浏览器的工具发起请求时没有加“/”&#xff0c;而且还不是get请求&#xff0c;那么这…

el-popover放在el-table中点击无反应问题

我们想在table中给btn加弹框但是 el-popover点击按钮没有任何反应思考:通过插槽去添加这个组件el-popover的id是否绑定了一个值解决思路&#xff1a;给每个el-popover都加上单独的id 效果 &#xff1a; 代码 给每个组件都绑定ref <template slot-scope"scope"&g…

组合预测 | Matlab实现LSTM-XGBoost长短期记忆网络组合极限梯度提升树多输入单输出回归预测

组合预测 | Matlab实现LSTM-XGBoost长短期记忆网络组合极限梯度提升树多输入单输出回归预测 目录 组合预测 | Matlab实现LSTM-XGBoost长短期记忆网络组合极限梯度提升树多输入单输出回归预测效果一览基本描述模型描述代码实现参考资料效果一览 基本描述 组合预测 | Matlab实现L…

【性能测试】ChaosTesting(混沌测试)ChaosBlade(混沌实验工具)(四)-k8s容器混沌实验

5. 创建 kubernetes 相关的实验场景 5.0 blade create k8s 5.0.1 介绍 创建 kubernetes 相关的实验场景&#xff0c;除了使用 blade 命令创建场景外&#xff0c;还可以将实验使用 yaml 文件描述&#xff0c;使用 kubectl 命令执行。目前支持的实验场景如下&#xff1a; [bl…

【VueUse】重新定义状态管理在 Vue 中的体验

在 Vue 生态系统中&#xff0c;状态管理一直是开发者们关注的焦点之一。而随着 VueUse 的出现&#xff0c;我们迎来了一种全新的方式来处理状态管理&#xff0c;它让我们能够以更简单、更灵活的方式来管理应用程序的状态。 在本文中我们将深入探讨 VueUse 中与状态管理相关的内…

成功解决ImportError: cannot import name ‘builder‘ from ‘google.protobuf.internal

成功解决ImportError: cannot import name builder from google.protobuf.internal 目录 解决问题 解决思路 解决方法 解决问题 ImportError: cannot import name builder from google.protobuf.internal 解决思路 导入错误:无法从“google.protobuf.internal”导入名称“…

Vscode配置C/C++编程环境@配置C和CPP的运行和调试环境@配置过程的相关问题@中文文件名乱码@build和debug方案组合配置

文章目录 abstractgcc/g文档和用法常见用例 目录.vscode中的相关文件说明tasks.jsonlaunch.jsonc_cpp_properties.json IDE或编辑器配置vscode配置相关指令和快捷键默认task配置和取消默认 配置文件C/C共用一组tasks.json/launch.json文件?关于注释内容示例&#x1f47a;tasks…

【linux】进程地址被占用

在强制关闭一个udp程序后&#xff0c;重启该程序报错&#xff1a; bind error: Address already in use 查找并关闭占用端口的进程&#xff1a; 首先&#xff0c;确定哪个进程占用了目标端口。在Linux系统中&#xff0c;可以使用以下命令&#xff1a; netstat -tulnp | grep …

TensorFlow进阶二(高阶操作)

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

Flutter 上架如何解决 ITMS-91053 问题

最近&#xff0c;我的 Flutter App 发布到 TestFlight 后&#xff0c;就会收到一封邮件&#xff1a;The uploaded build for YOUR APP has one or more issues. 上面的邮件主要是说&#xff0c;我的 App 缺少了调用 API 的声明&#xff0c;以前从来没看到过&#xff0c;上网一查…

Python构建学生信息管理系统:构建RESTful API - 学生信息管理系统的后端逻辑

在之前的博客里&#xff0c;我们已经完成了项目初始化&#xff0c;在本篇博客中&#xff0c;我们将深入探讨如何使用Flask框架实现学生信息管理系统的后端逻辑&#xff0c;特别是通过RESTful API来实现学生信息的增删改查&#xff08;CRUD&#xff09;操作。 Flask RESTful AP…

传染病模型SIR及其变体(python版本)

文章目录 传染病模型及其变体1. SI模型1.1代码2. SIS模型2.1 代码3. 基本再生数 basic reproductive number4. SIR模型4.1 代码5. SEIR模型5.1 代码6. SEIJR模型6.1 代码7. SEIJRD模型7.1 代码传染病模型及其变体 1. SI模型 在该模型里面,群体中只有两种人:易感者和感染者。…