【SpringBoot】从零开始全面解析SpringMVC (二)

news2025/5/17 9:11:00

在这里插入图片描述

本篇博客给大家带来的是SpringBoot的知识点, 本篇是SpringBoot入门, 介绍SpringMVC相关知识.
🐎文章专栏: JavaEE进阶
🚀若有问题 评论区见
👉gitee链接: 薯条不要番茄酱
欢迎大家点赞 评论 收藏 分享
如果你不知道分享给谁,那就分享给薯条.
你们的支持是我不断创作的动力 .

王子,公主请阅🚀

  • 要开心
    • 要快乐
      • 顺便进步
  • 1. 关于SpringMVC 请求传递信息
    • 1.1 传递 JSON 数据
    • 1.2 获取URL中参数(@PathVariable)
    • 1.3 上传文件 (@RequestPart)
    • 1.4 Cookie 和 Seesion
      • 1.4.1 回顾 Cookie, 理解 Session
      • 1.4.2 获取Cookie 和 Session
    • 1.5 获取Header
  • 2. 关于SpringMVC 响应传递信息
    • 2.1 返回静态页面
    • 2.2 返回数据@ResponseBody
    • 2.3 返回HTML代码片段
    • 2.4 返回JSON数据
    • 2.5 设置状态码
    • 2.6 设置Header(了解即可)
  • 3. 综合练习
    • 3.1 加法计算器
      • 3.1.1 准备工作
      • 3.1.2 约定前后端交互接口
      • 3.1.3 服务器代码
      • 3.1.4 前端页面代码
      • 3.1.5 运行测试
    • 3.2 用户登录
      • 3.2.1 准备工作
      • 3.2.2 约定前后端交互接口
      • 3.2.3 实现服务器端代码
      • 3.2.4 前端页面代码

要开心

要快乐

顺便进步

1. 关于SpringMVC 请求传递信息

1.1 传递 JSON 数据


Ⅰ JSON概念

JSON:JavaScript Object Notation 【JavaScript 对象表示法】

JSON是一种轻量级的数据交互格式. 它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。-- 来自百度百科

简单来说:JSON就是一种数据格式, 有自己的格式和语法, 使用文本表示一个对象或数组的信息,
因此JSON本质是字符串. 主要负责在不同的语言中数据传递和交换.


类似于:
① 国际通用语言 - 英语.
② 中国56个民族不同地区的通用语言 - 普通话.


Ⅱ JSON 与 Javascript 的关系

没有关系, 只是语法相似, js开发者能更快的上手而已, 但是他的语法本身比较简单, 所以也很好学.

Ⅲ JSON语法

JSON 是一个字符串,其格式非常类似于 JavaScript 对象字面量的格式.

{
 "squadName": "Super hero squad",
 "homeTown": "Metro City",
 "formed": 2016,
 "secretBase": "Super tower",
 "active": true,
 "members": [{
 "name": "Molecule Man",
 "age": 29,
 "secretIdentity": "Dan Jukes",
 "powers": ["Radiation resistance", "Turning tiny", "Radiation blast"
 }, {
 "name": "Madame Uppercut",
 "age": 39,
 "secretIdentity": "Jane Wilson",
 "powers": ["Million tonne punch", "Damage resistance", "Superhuman r
 }, {
 "name": "Eternal Flame",
 "age": 1000000,
 "secretIdentity": "Unknown",
 "powers": ["Immortality", "Heat Immunity", "Inferno", "Teleportation
 }]
}


Ⅳ JSON的语法:

1. 数据在 键值对(Key/Value) 中.
2. 数据由逗号 ’ , ’ 分隔.
3. 对象用 {} 表示.
4. 数组用 [] 表示.
5. 值可以为对象, 也可以为数组, 数组中可以包含多个对象.


Ⅴ JSON的两种结构

1. 对象: 大括号 {} 保存的对象是一个无序的 键值对 集合. 一个对象以左括号 { 开始, 右括号 } 结束。每个"键"后跟⼀个冒号 : 键值对使用逗号 , 分隔开。

2. 数组: 中括号 [] 保存的数组是值(value)的有序集合. 一个数组以左中括号 [ 开始, 右中括
号 ] 结束,值之间使用逗号 , 分隔。


可以使用在线JSON格式化工具来进行校验和书写: JSON校验工具 .

Ⅵ JSON优点
1. 简单易用: 语法简单,易于理解和编写,可以快速地进行数据交换.

2. 跨平台支持: JSON可以被多种编程语言解析和生成, 可以在不同的平台和语言之间进行数据交换和传输.

3. 轻量级: 相较于XML格式, JSON数据格式更加轻量级, 传输数据时占用带宽较小, 可以提高数据传输速度.

4. 易于扩展: JSON的数据结构灵活,支持嵌套对象和数组等复杂的数据结构,便于扩展和使用.

5. 安全性: JSON数据格式是一种纯文本格式,不包含可执行代码, 不会执行恶意代码,因此具有较高的安全性.

Ⅶ 传递 JSON 数据

接收 JSON 对象,需要使用 @RequestBody 注解

RequestBody: 请求正文,意思是这个注解作用在请求正文的数据绑定,请求参数必须在写在请求正文中.

使用 Postman 来发送 json 请求参数:

在这里插入图片描述

如果去掉@RequestBody 注解的话会怎么样? 👇

在这里插入图片描述

可以看到, 后端未能成功给 Student对象赋值.

1.2 获取URL中参数(@PathVariable)


path variable: 路径变量.
和字面表达的意思一样, 这个注解主要作用在请求URL路径上的数据绑定.


后端实现代码:

 @RequestMapping("/r9/{articleId}")
    public String r9(@PathVariable("articleId") Integer articleId) {
        return "接到参数,articleId:"+articleId;
    }


使用Postman 发送请求:

在这里插入图片描述

可以看到, 后端正确获取到了URL中的参数.

1.3 上传文件 (@RequestPart)


直接看后端代码实现:

    @RequestMapping("/r10")
    public String r10(@RequestPart("file")MultipartFile imgFile) {
        String originalFilename = imgFile.getOriginalFilename();
        return "接到文件,文件名称:"+originalFilename;
    }


使用 Postman 发送请求:

在这里插入图片描述


文件上传成功.

1.4 Cookie 和 Seesion

1.4.1 回顾 Cookie, 理解 Session

Ⅰ 回顾 Cookie

HTTP 协议 自身 是属于 “无状态” 协议.
“无状态” 的含义指的是:默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系.

实际开发中, 我们很多时候是需要知道请求之间的关联关系的.
例如登陆网站成功后, 第二次访问的时候服务器就能知道该请求是否是已经登陆过了.

在这里插入图片描述

上图过程中的令牌通常就存储在Cookie 子段当中. 此时在服务器这边就需要记录"令牌"信息, 以及令牌对应的用户信息, 这个就是 session 机制所做的工作.

比如去医院挂号 :

1. 看病之前先挂号. 挂号时候需要提供身份证号, 同时得到了一张 “就诊卡”, 这个就诊卡就相当于患者的 “令牌”.
2. 后续去各个科室进行检查, 诊断, 开药等操作, 都不必再出示身份证了, 只要凭就诊卡即可识别出当前患者的身份.
3. 看完病了之后, 不想要就诊卡了, 就可以注销这个卡. 此时患者的身份和就诊卡的关联就销毁了. (类似于网站的注销操作).
4. 又来看病, 可以办一张新的就诊卡, 此时就得到了一个新的 “令牌”.

Ⅱ 理解 Session (会话)

服务器同一时刻收到的请求是很多的. 服务器需要清楚的区分每个请求是从属于哪个用户, 也就是属于哪个会话, 就需要在服务器这边记录每个会话以及与用户的信息的对应关系. Session是服务器为了保存用户信息而创建的一个特殊的对象.

Session 的本质就是一个 “哈希表”, 存储了一些键值对结构. Key 就是SessionID, Value 就是用户信息.
SessionId 是由服务器生成的一个 “唯一性字符串”, 这就是Session能够区分同一请求不同用户信息的根本原因.

Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失.

Ⅲ Cookie 和 Session 的区别

① Cookie 是客户端保存用户信息的一种机制. Session 是服务器端保存用户信息的一种机制.
② Cookie 和 Session之间主要是通过 SessionId 关联起来的, SessionId 是 Cookie 和 Session 之间的桥梁.
③ Cookie 和 Session 经常会在一起配合使用. 但 不是必须配合.
1. 完全可以用 Cookie 来保存一些数据在客户端. 这些数据不一定是用户身份信息, 也不一定是 SessionId.
2. Session 中的 sessionId 也不需要非得通过 Cookie/Set-Cookie 传递, 比如通过URL传递.

1.4.2 获取Cookie 和 Session


Ⅰ 获取Cookie

代码如下:

    @RequestMapping("/r11")
    public String r11(HttpServletRequest request, HttpServletResponse response) {
        //获取所有 cookie信息
        Cookie[] cookies = request.getCookies();
        //打印 cookie信息
        if(cookies != null) {
            Arrays.stream(cookies).forEach(ck -> System.out.println(ck.getName()+":"+ck.getValue()));
        }
        return "获取cookies成功";
    }


此时没有设置Cookie, 通过浏览器访问: http://127.0.0.1:8080/req/r11, 得到 Cookie为 null . 按下图提示设置 Cookie 👇

在这里插入图片描述

设置完成之后再次访问就可以在IDEA 上看到 刚刚设置的Cookie. 👇

在这里插入图片描述

Ⅱ 简洁获取Cookie的方式, 使用@CookieValue注解

    @RequestMapping("/r12")
    public String r12(String ck) {
        return "cookie: " + ck;
    }


Ⅲ 获取 Session 的方式

Session是服务器端的机制, 我们需要先存储, 才能再获取.
Session 也是基于HttpServletRequest 来存储和获取的.

//设置Session
    @RequestMapping("/setSess")
    public String r13(HttpServletRequest request) {
        //获取 Session 对象
        HttpSession session = request.getSession();
        if(session != null) {
            session.setAttribute("username","大帅锅");
        }
        return "session 存储成功";
    }

    //获取Session
    @RequestMapping("/getSess")
    public String r14(HttpServletRequest request) {
        //如果 session 不存在, 不会⾃动创建
        HttpSession session = request.getSession(false);
        String username = null;
        if(session != null && session.getAttribute("username") != null) {
            username = (String)session.getAttribute("username");
        }
        return "username: " + username;
    }

先设置Session

在这里插入图片描述

再获取 Session

在这里插入图片描述

上述获取Session 的方式有点麻烦, 有没有跟简单点的?

其实就是对 HttpServletRequest获取session的方法进行封装就能通过 HttpSession 直接获取.

    @RequestMapping("/getSess2")
    public String r15(HttpSession session) {
        String name = (String)session.getAttribute("username");
        return "从session中获取username: " + name;
    }


还是一样的, 先设置 Session 再获取 Session,下面只给出获取的截图👇:

在这里插入图片描述

为了图方便, 能不能把上述获取Session的方式进一步封装成注解? 实际上也确实有这种方式:

    @RequestMapping("/getSess3")
    public String r16(@SessionAttribute("username") String name) {
        return "从Session中获取name: "+name;
    }


通过注解 @SessionAttribute就可以获取 Session 中的任意信息.

1.5 获取Header


Ⅰ 传统获取 header

从 HttpServletRequest 中获取

    //获取header.
    @RequestMapping("/r8")
    public String r8(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        return "userAgent: "+userAgent;
    }


使用浏览器访问后,得到如下:👇

在这里插入图片描述

通过Fiddler观察, 获取的 User-Agent 是否正确。

在这里插入图片描述

Ⅱ 使用@RequestHeader注解 简洁获取Header

    @RequestMapping("/r9")
    public String r9(@RequestHeader("User-Agent") String userAgent) {
        return userAgent;
    }


2. 关于SpringMVC 响应传递信息

2.1 返回静态页面


创建前端页面 index.html(注意是在resources/static 目录下)。

在这里插入图片描述

前端页面代码如下:

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>用户登录首页</title>
</head>

<body>
	我是Index页面。
</body>

</html>


后端代码:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/res")
@RestController
public class ResponseController {
    @RequestMapping("/index")
    public String index() {
        return "/index.html";
    }
}


使用浏览器访问 http://127.0.0.1:8080/res/index

在这里插入图片描述

发现, 页面未正确返回, http 响应把 “/index.html” 当做了 http响应正文的数据。
那Spring MVC如何才能识别出来 index.html 是一个静态页面, 并进行返回呢?


把 @RestController 改为 @Controller

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/res")
@Controller
public class ResponseController {
    @RequestMapping("/index")
    public String index() {
        return "/index.html";
    }
}


再次访问 http://127.0.0.1:8080/res/index
在这里插入图片描述
发现页面正确展示了。

@RestController 和 @Controller 有着什么样的关联和区别呢? 我们来看@RestController 的源码 👇

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}


不难发现有如下关系:
@RestController = @Controller + @ResponseBody。

@RestController 返回的是数据 。 @Controller 返回的是视图(页面)。可以推出@ResponseBody返回的是数据。

2.2 返回数据@ResponseBody


上面讲到, @ResponseBody 表示返回数据。我们来验证下:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@RequestMapping("/res")
@Controller
@ResponseBody
public class ResponseController {
    @RequestMapping("/index")
    public String index() {
        return "/index.html";
    }
}


加上 @ResponseBody 该方法就会把“/index.html" 当做一个数据返回给前端。

在这里插入图片描述

@ResponseBody 既是类注解, 又是方法注解。
如果作用在类上, 表示该类的所有方法, 返回的都是数据, 如果作用在方法上, 表示该方法返回的是数据。

2.3 返回HTML代码片段


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

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


响应结果👇:

在这里插入图片描述
通过Fiddler抓包,观察响应结果:

在这里插入图片描述

响应中的 Content-Type 常见取值有以下几种:


①text/html : body 数据格式是 HTML。
② text/css : body 数据格式是 CSS。
③ application/javascript : body 数据格式是 JavaScript。
④ application/json : body 数据格式是 JSON。

2.4 返回JSON数据


Spring MVC 也可以返回JSON

    @RequestMapping("/returnJson")
    @ResponseBody
    public HashMap<String,String> returnJson() {
        HashMap<String,String> map = new HashMap<>();
        map.put("糯香:","柠檬茶");
        map.put("牢大: ","坠机");
        map.put("ikun炒粉: ","放鸡精");
        return map;
    }


运行程序,浏览器响应结果如下:

在这里插入图片描述

通过 Fiddler 观察响应结果, Content-Type 为 application/json.

在这里插入图片描述

2.5 设置状态码


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

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


通过Fiddler 抓包来观察设置的结果:

在这里插入图片描述

2.6 设置Header(了解即可)


Http 响应报头也会向客户端传递一些附加信息, 比如服务程序的名称,请求的资源已移动到新地址等, 如:
Content-Type, Local等.



3. 综合练习


结合上述内容, 我们可以做一些小案例: 重在理解前后端交互的实现.

3.1 加法计算器


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

在这里插入图片描述

3.1.1 准备工作


gitee链接: 薯条不要番茄酱
从我的码云上直接下载spring-mvc文件夹, 并把 calc.html 复制到static 目录下👇

在这里插入图片描述

3.1.2 约定前后端交互接口


接口设计:

1. 接收什么是看后端完成这个功能需要什么.
2. 返回什么是看前端页面展示需要什么.

对于此练习:
路径: calc/sum
参数: num1 和 num2
返回值: sum

3.1.3 服务器代码

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

3.1.4 前端页面代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
     <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>
</body>

</html>

3.1.5 运行测试

在这里插入图片描述

注意点: 前端接收的参数为num1 和 num2, 那么后端方法参数也必须是 num1 和 num2.(顺序无所谓,名字必须和前端保持一致

3.2 用户登录


需求: 用户输入账号和密码, 后端进行校验密码是否正确.
1. 如果不正确, 前端进行用户告知.
2. 如果正确, 跳转到首页. 首页显示当前登录用户.
3. 后续再访问首页, 可以获取到登录用户信息.

在这里插入图片描述

3.2.1 准备工作

gitee链接: 薯条不要番茄酱

还是一样的前端页面代码直接在我的码云上拿就可以了.

在这里插入图片描述

3.2.2 约定前后端交互接口


用户登录:
url: /user/login
参数: userName,password
返回结果: true / false



获取当前登录用户:
url: /user/index
参数: 无
返回结果: userName

3.2.3 实现服务器端代码

import jakarta.servlet.http.HttpSession;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;

@RequestMapping("/user")
@RestController
public class LoginController {
    @RequestMapping("/login")
    public Boolean login(String userName, String password, HttpSession session) {
        //校验用户名和密码是否为空
//        if(userName == null || userName.length() == 0 || password == null || password.length() == 0) {
//            return false;
//        }

        //上面代码可以改写成 ↓, 可以点过去看 hasLength 的源码,其实和上面的代码是类似的
        if(!StringUtils.hasLength(userName) || !StringUtils.hasLength(password)) {
            return false;
        }

        //注意接下来的写法, 由于已经对 userName进行判断处理, 所以userName不会为null.
        //还没学 mybatis, 所以只能先把用户名和密码写死了, 后面学了再改.
        if("admin".equals(userName) && "admin".equals(password)) {
            //从需求上看: 如果成功登录就需要 获取用户名,
            // 所以这里得先设置 session, 将用户名放到session中, 后面得方法通过session 来获取.
            session.setAttribute("userName",userName);
            return true;
        }
        return false;
    }
    @RequestMapping("/index")
    public String getUserName(@SessionAttribute("userName") String userName) {
        return userName;
    }
}

3.2.4 前端页面代码


login.html :

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>登录页面</title>
</head>

<body>
  <h1>用户登录</h1>
  用户名:<input name="userName1" type="text" id="userName"><br>
  密码:<input name="password1" type="password" id="password"><br>
  <input type="button" value="登录" onclick="login()">
  
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
  <script>
  //下列代码需要自己写,ajax必须要会:
    function login() {
      $.ajax({
        url:"/user/login",
        type:"post",
        data: {
          userName: $("#userName").val(),
          password: $("#password").val()
        },
        //http响应成功
        success:function(result) {
          if(result==true) {
            //页面跳转
            location.href = "index.html";
            //也可以写成
            // location.assign("index.html");
          }else {
            alert("密码错误");
          }
        }
        });
      }

  </script>
</body>

</html>


index.html :

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>用户登录首页</title>
</head>

<body>
    登录人: <span id="loginUser"></span>

    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script>
     //下列代码需要自己写,ajax必须要会:
        $.ajax({
            url:"/user/index",
            type:"get",
            success:function(loginName) {
                $("#loginUser").text(loginName);
            }
        });
    </script>
</body>

</html>






本篇博客到这里就结束啦, 感谢观看 ❤❤❤

🐎期待与你的下一次相遇😊😊😊

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

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

相关文章

蒟蒻编程日志

ORZ &#xff08;用于记录你这个“人”是不是真的&#xff0c;也就是说CSDN的流量是否属合适&#xff09; 2025/4/14 21:25 开坑 前言 2024/10/26&#xff1a;CSP-J 260pts&#xff0c;CSP-S 45pts。 2025/3/1&#xff1a;%你赛 180pts rk34 寄&#xff01;这就是不认真的…

git克隆github项目到本地的三种方式

本文旨在使用git工具将别人发布在github上的项目保存到本地 1.安装git&#xff0c;创建github账户&#xff0c;并使用ssh关联自己的github账号和git&#xff0c;具体教程可以参照下面两篇文章&#xff1a; Github入门教程&#xff0c;适合新手学习&#xff08;非常详细&#…

EtherCAT转EtherNet/IP解决方案-泗博网关CEI-382

一、应用场景 在智能制造快速发展的背景下&#xff0c;工业自动化领域对设备间通信提出了更高要求&#xff0c;需要同时满足实时性、可靠性和灵活性的需求。EtherCAT 与 EtherNet/IP 作为工业通信领域的两大核心协议&#xff0c;各自在不同应用场景中发挥着关键作用。EtherCAT …

子查询对多层join优化记录

需求背景 查询某个用户是否具有某个角色 表 CREATE TABLE mdm_platform_role_user (ID bigint NOT NULL AUTO_INCREMENT,ROLE_ID varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,USER_ID varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci …

分布式AI推理的成功之道

随着AI模型逐渐成为企业运营的核心支柱&#xff0c;实时推理已成为推动这一转型的关键引擎。市场对即时、可决策的AI洞察需求激增&#xff0c;而AI代理——正迅速成为推理技术的前沿——即将迎来爆发式普及。德勤预测&#xff0c;到2027年&#xff0c;超半数采用生成式AI的企业…

PR-2021

推荐深蓝学院的《深度神经网络加速&#xff1a;cuDNN 与 TensorRT》&#xff0c;课程面向就业&#xff0c;细致讲解CUDA运算的理论支撑与实践&#xff0c;学完可以系统化掌握CUDA基础编程知识以及TensorRT实战&#xff0c;并且能够利用GPU开发高性能、高并发的软件系统&#xf…

Linux复习笔记(六)shell编程

遇到的问题&#xff0c;都有解决方案&#xff0c;希望我的博客能为你提供一点帮助。 三、shell编程简明教程 一、Shell基础概念 ​​1. Shell的作用​​ 是用户与Linux内核交互的桥梁&#xff0c;既是命令解释器&#xff0c;也是一种脚本语言。运行机制&#xff1a;用户输入…

Unity 拖尾烟尘效果及参数展示

亮点&#xff1a;在移动特效过后 &#xff0c;粒子会顺着惯性继续向前移动一小段距离。 以unity-URP管线为例&#xff0c;下图是Particle System参数分享&#xff1a; Start Color参数&#xff1a; UnityEditor.GradientWrapperJSON:{"gradient":{"serialized…

Vue3 Echarts 3D饼图(3D环形图)实现讲解附带源码

文章目录 前言一、准备工作1. 所需工具2. 引入依赖方式一&#xff1a;CDN 快速引入方式二&#xff1a;npm 本地安装&#xff08;推荐&#xff09; 二、实现原理解析三、echarts-gl 3D插件 使用回顾grid3D 常用通用属性&#xff1a;series 常用通用属性&#xff1a;surface&…

Kafka快速安装与使用

引言 这篇文章是一篇Ubuntu(Linux)环境下的Kafka安装与使用教程&#xff0c;通过本文&#xff0c;你可以非常快速搭建一个kafka的小单元进行日常开发与调测。 安装步骤 下载与解压安装 首先我们需要下载一下Kafka&#xff0c;这里笔者采用wget指令&#xff1a; wget https:…

Java EE初阶——wait 和 notify

1. 线程饥饿 线程饥饿是指一个或多个线程因长期无法获取所需资源&#xff08;如锁&#xff0c;CPU时间等&#xff09;而持续处于等待状态&#xff0c;导致其任务无法推进的现象。 典型场景 优先级抢占&#xff1a; 在支持线程优先级的系统中&#xff0c;高优先级线程可能持续…

RPA vs. 传统浏览器自动化:效率与灵活性的终极较量

1. 引言 在数字化转型的大潮下&#xff0c;企业和开发者对浏览器自动化的需求日益增长。无论是网页数据抓取、自动化测试&#xff0c;还是用户行为模拟&#xff0c;浏览器自动化已经成为提升效率的关键工具。然而&#xff0c;面对越来越严格的反自动化检测、复杂的 Web 结构和…

docker 快速部署若依项目

1、首先创建一个自定义网络&#xff0c;作用是使连接到该网络的容器能够通过容器名称进行通信&#xff0c;无需使用复杂的IP地址配置&#xff0c;方便了容器化应用中各个服务之间的交互。 sudo docker network create ruoyi 2、创建一个文件夹&#xff0c;创建compose.yml文件…

polarctf-web-[rce1]

考点&#xff1a; (1)RCE(exec函数) (2)空格绕过 (3)执行函数(exec函数) (4)闭合(ping命令闭合) 题目来源&#xff1a;Polarctf-web-[rce1] 解题&#xff1a; 这段代码实现了一个简单的 Ping 测试工具&#xff0c;用户可以通过表单提交一个 IP 地址&#xff0c;服务器会执…

Redis+Caffeine构造多级缓存

一、背景 项目中对性能要求极高&#xff0c;因此使用多级缓存&#xff0c;最终方案决定是RedisCaffeine。其中Redis作为二级缓存&#xff0c;Caffeine作为一级本地缓存。 二、Caffeine简单介绍 Caffeine是一款基于Java 8的高性能、灵活的本地缓存库。它提供了近乎最佳的命中…

docker(四)使用篇二:docker 镜像

在上一章中&#xff0c;我们介绍了 docker 镜像仓库&#xff0c;本文就来介绍 docker 镜像。 一、什么是镜像 docker 镜像本质上是一个 read-only 只读文件&#xff0c; 这个文件包含了文件系统、源码、库文件、依赖、工具等一些运行 application 所必须的文件。 我们可以把…

AXI4总线协议 ------ AXI_LITE协议

一、AXI 相关知识介绍 https://download.csdn.net/download/mvpkuku/90841873 AXI_LITE 选出部分重点&#xff0c;详细文档见上面链接。 1.AXI4 协议类型 2.握手机制 二、AXI_LITE 协议的实现 1. AXI_LITE 通道及各通道端口功能介绍 2.实现思路及框架 2.1 总体框架 2.2 …

Ubuntu24.04 安装 5080显卡驱动以及cuda

前言 之前使用Ubuntu22.04版本一直报错,然后换了24.04版本才能正常安装 一. 配置基础环境 Linux系统进行环境开发环境配置-CSDN博客 二. 安装显卡驱动 1.安装驱动 按以下步骤来&#xff1a; sudo apt update && sudo apt upgrade -y#下载最新内核并安装 sudo add…

SpringAI-RC1正式发布:移除千帆大模型!

续 Spring AI M8 版本之后&#xff08;5.1 发布&#xff09;&#xff0c;前几日 Spring AI 悄悄的发布了最新版 Spring AI 1.0.0 RC1&#xff08;5.13 发布&#xff09;&#xff0c;此版本也将是 GA&#xff08;Generally Available&#xff0c;正式版&#xff09;发布前的最后…

操作系统之进程和线程听课笔记

计算机的上电运行就是构建进程树,进程调度就是在进程树节点进程进行切换 进程间通信的好处 经典模型 生产者和消费者 进程和线程的区别 线程引入带来的问题线程的优势 由于unix70年代产生,90年代有线程,当时数据库系统操作需要线程,操作系统没有来得及重造,出现了用户态线…