当前位置: 首页 > news >正文

SpringBoot整合阿里云OSS文件上传、下载、查看、删除

SpringBoot整合阿里云OSS文件上传、下载、查看、删除

  • 1、开发准备
    • 1.1 前置知识
    • 1.2 环境参数
    • 1.3 你能学到什么
  • 2. 使用阿里云OSS
    • 2.1 创建Bucket
    • 2.2 管理文件
    • 2.3 阿里云OSS文档
  • 3. 项目初始化
    • 3.1 创建SpringBoot项目
    • 3.2 Maven依赖
    • 3.3 安装lombok插件
  • 4. 后端服务编写
    • 4.1 阿里云OSS配置
    • 4.2 后端业务
      • 4.2.1 vo
      • 4.2.2 service
      • 4.2.3 controller
  • 5. 前端页面编写与测试
    • 5.1 文件上传页面
    • 5.2 文件管理页面

1、开发准备

1.1 前置知识

java基础以及SpringBoot简单基础知识即可。

1.2 环境参数

  • 开发工具:IDEA
  • 基础环境:Maven+JDK8
  • 所用技术:SpringBoot、lombok、阿里云OSS存储服务
  • SpringBoot版本:2.1.4

1.3 你能学到什么

  • OSS简介,以及阿里云OSS控制台快速入门使用
  • SpringBoot 整合 阿里云OSS 存储服务,进行文件上传、下载、查看、删除
  • 阿里云OSS文档介绍,以及快速入门使用
  • lombak入门使用以及IDEA lombak插件安装
  • SpringMVC与AJAX前后端分离交互
  • AJAX文件异步上传

2. 使用阿里云OSS

对象存储OSS的多重冗余架构设计,为数据持久存储提供可靠保障。

2.1 创建Bucket

使用OSS,首先需要创建Bucket,Bucket翻译成中文是水桶的意思,把存储的图片资源看做是水,想要盛水必须得
有桶。
进入控制台,https://oss.console.aliyun.com/overview
在这里插入图片描述
在这里插入图片描述
创建完成后,在左侧可以看到已经创建好的Bucket:
在这里插入图片描述
选择Bucket后,即可看到对应的信息,如:url、消耗流量等
在这里插入图片描述

2.2 管理文件

可以通过在线的方式进行管理文件
在这里插入图片描述

2.3 阿里云OSS文档

阿里云OSS文档
在这里插入图片描述
右侧的开发指南说的更加详细
在这里插入图片描述
阿里云虽然提供了完整的文档,但是做一个完整的前后端交互的文件上传、下载、查看、删除等操作,对于小白来说还是有点难度的,所以我把自己学习OSS的步骤以及代码分享了出来,共有需要的人使用。

3. 项目初始化

3.1 创建SpringBoot项目

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

3.2 Maven依赖

<dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>2.8.3</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.4</version><scope>provided</scope></dependency><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>2.9.9</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.8.1</version></dependency>

3.3 安装lombok插件

因为项目中使用了lombok的@Data注解,当然你也可以自己写get、set等方法。
File——>settings——>Plugins
在这里插入图片描述
在这里插入图片描述
然后restart IDEA即可。

4. 后端服务编写

在这里插入图片描述

4.1 阿里云OSS配置

在resource下新建一个application-oss.properties

aliyun.endpoint=oss-cn-shanghai.aliyuncs.com
aliyun.accessKeyId=你的accessKeyId
aliyun.accessKeySecret=你的accessKeySecret
aliyun.bucketName=gaojun-testbucket
aliyun.urlPrefix=http://gaojun-testbucket.oss-cn-shanghai.aliyuncs.com/

在这里插入图片描述
在这里插入图片描述
在java的包下新建一个config包,创建一个AliyunConfig.java

package com.example.ossdemo.config;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
/*** @desc** @author gaojun* @email 15037584397@163.com*/
@Configuration
@PropertySource(value = {"classpath:application-oss.properties"})
@ConfigurationProperties(prefix = "aliyun")
@Data
public class AliyunConfig {private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketName;private String urlPrefix;@Beanpublic OSS oSSClient() {return new OSSClient(endpoint, accessKeyId, accessKeySecret);}
}

4.2 后端业务

4.2.1 vo

package com.example.ossdemo.vo;
import lombok.Data;
/*** @author gaojun* @desc 用于前后端交互的返回值* @email 15037584397@163.com*/
@Data
public class FileUploadResult {// 文件唯一标识private String uid;// 文件名private String name;// 状态有:uploading done error removedprivate String status;// 服务端响应内容,如:'{"status": "success"}'private String response;
}

4.2.2 service

package com.example.ossdemo.service;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.*;
import com.example.ossdemo.config.AliyunConfig;
import com.example.ossdemo.vo.FileUploadResult;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.List;
/*** @author gaojun* @desc* @email 15037584397@163.com*/
@Service
public class FileUploadService {// 允许上传的格式private static final String[] IMAGE_TYPE = new String[]{".bmp", ".jpg",".jpeg", ".gif", ".png"};@Autowiredprivate OSS ossClient;@Autowiredprivate AliyunConfig aliyunConfig;/*** @author gaojun* @desc 文件上传*  文档链接 https://help.aliyun.com/document_detail/84781.html?spm=a2c4g.11186623.6.749.11987a7dRYVSzn* @email 15037584397@163.com*/public FileUploadResult upload(MultipartFile uploadFile) {// 校验图片格式boolean isLegal = false;for (String type : IMAGE_TYPE) {if (StringUtils.endsWithIgnoreCase(uploadFile.getOriginalFilename(),type)) {isLegal = true;break;}}//封装Result对象,并且将文件的byte数组放置到result对象中FileUploadResult fileUploadResult = new FileUploadResult();if (!isLegal) {fileUploadResult.setStatus("error");return fileUploadResult;}//文件新路径String fileName = uploadFile.getOriginalFilename();String filePath = getFilePath(fileName);// 上传到阿里云try {ossClient.putObject(aliyunConfig.getBucketName(), filePath, newByteArrayInputStream(uploadFile.getBytes()));} catch (Exception e) {e.printStackTrace();//上传失败fileUploadResult.setStatus("error");return fileUploadResult;}fileUploadResult.setStatus("done");fileUploadResult.setResponse("success");//this.aliyunConfig.getUrlPrefix() + filePath 文件路径需要保持数据库fileUploadResult.setName(this.aliyunConfig.getUrlPrefix() + filePath);fileUploadResult.setUid(String.valueOf(System.currentTimeMillis()));return fileUploadResult;}/*** @author gaojun* @desc 生成路径以及文件名 例如://images/2019/04/28/15564277465972939.jpg* @email 15037584397@163.com*/private String getFilePath(String sourceFileName) {DateTime dateTime = new DateTime();return "images/" + dateTime.toString("yyyy")+ "/" + dateTime.toString("MM") + "/"+ dateTime.toString("dd") + "/" + System.currentTimeMillis() +RandomUtils.nextInt(100, 9999) + "." +StringUtils.substringAfterLast(sourceFileName, ".");}/*** @author gaojun* @desc 查看文件列表* 文档链接 https://help.aliyun.com/document_detail/84841.html?spm=a2c4g.11186623.2.13.3ad5b5ddqxWWRu#concept-84841-zh* @email 15037584397@163.com*/public List<OSSObjectSummary> list() {// 设置最大个数。final int maxKeys = 200;// 列举文件。ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(aliyunConfig.getBucketName()).withMaxKeys(maxKeys));List<OSSObjectSummary> sums = objectListing.getObjectSummaries();return sums;}/*** @author gaojun* @desc 删除文件* 文档链接 https://help.aliyun.com/document_detail/84842.html?spm=a2c4g.11186623.6.770.4f9474b4UYlCtr* @email 15037584397@163.com*/public FileUploadResult delete(String objectName) {ossClient.deleteObject(aliyunConfig.getBucketName(), objectName);FileUploadResult fileUploadResult = new FileUploadResult();fileUploadResult.setName(objectName);fileUploadResult.setStatus("removed");fileUploadResult.setResponse("success");return fileUploadResult;}/*** @author gaojun* @desc 下载文件* 文档链接 https://help.aliyun.com/document_detail/84823.html?spm=a2c4g.11186623.2.7.37836e84ZIuZaC#concept-84823-zh* @email 15037584397@163.com*/public InputStream exportOssFile(String objectName) {// ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。OSSObject ossObject = ossClient.getObject(aliyunConfig.getBucketName(), objectName);// 读取文件内容。InputStream is = ossObject.getObjectContent();return is;}
}

4.2.3 controller

package com.example.ossdemo.controller;
import com.aliyun.oss.model.OSSObjectSummary;
import com.example.ossdemo.service.FileUploadService;
import com.example.ossdemo.vo.FileUploadResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/*** @author gaojun* @desc* @email 15037584397@163.com*/
@Controller
public class FileUploadController {@Autowiredprivate FileUploadService fileUploadService;/*** @author gaojun* @desc 文件上传到oss* @return FileUploadResult* @Param uploadFile*/@RequestMapping("file/upload")@ResponseBodypublic FileUploadResult upload(@RequestParam("file") MultipartFile uploadFile)throws Exception {return this.fileUploadService.upload(uploadFile);}/*** @return FileUploadResult* @desc 根据文件名删除oss上的文件* http://localhost:8080/file/delete?fileName=images/2019/04/28/1556429167175766.jpg* @author gaojun* @Param objectName*/@RequestMapping("file/delete")@ResponseBodypublic FileUploadResult delete(@RequestParam("fileName") String objectName)throws Exception {return this.fileUploadService.delete(objectName);}/*** @author gaojun* @desc 查询oss上的所有文件* http://localhost:8080/file/list* @return List<OSSObjectSummary>* @Param*/@RequestMapping("file/list")@ResponseBodypublic List<OSSObjectSummary> list()throws Exception {return this.fileUploadService.list();}/*** @author gaojun* @desc 根据文件名下载oss上的文件* http://localhost:8080/file/delete* @return ResponseEntity<byte[]>* @Param objectName*/@RequestMapping("file/download")@ResponseBodypublic ResponseEntity<byte[]> download(@RequestParam("fileName") String objectName) throws IOException {HttpHeaders headers = new HttpHeaders();
//         以流的形式下载文件,这样可以实现任意格式的文件下载headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//         文件名包含中文时乱码问题
//        headers.setContentDispositionFormData("attachment", new String(exportFile.getName().getBytes("utf-8"), "ISO8859-1"));headers.setContentDispositionFormData("attachment", objectName);InputStream is = this.fileUploadService.exportOssFile(objectName);return new ResponseEntity<byte[]>(is.toString().getBytes(),headers, HttpStatus.CREATED);}
}

5. 前端页面编写与测试

5.1 文件上传页面

使用ajax异步文件上传到后端对接的OSS上。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>oss文件上传</title><script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.11.2/jquery.js"></script><script>function uploadfile() {$("#fileTypeError").html('');//获得文件名称var fileName = $('#file_upload').val();//截取文件类型,如(.jpg)                var fileType = fileName.substr(fileName.length - 4, fileName.length);if (fileType == '.bmp' || fileType == '.jpg' || fileType == '.jpeg' || fileType == '.gif' || fileType == '.png') {     //验证文件类型,此处验证也可使用正则$.ajax({url: 'file/upload',//上传地址type: 'POST',cache: false,data: new FormData($('#uploadForm')[0]),//表单数据processData: false,contentType: false,success: function (rtn) {if (rtn.status == 'error') {$("#fileTypeError").html('*上传文件类型错误,支持类型:  .bmp .jpg .jpeg .gif .png');  //根据后端返回值,回显错误信息} else {$('div').append('<img src="' + rtn.name + '" style="width: 300px;height: 300px"></img>')}}});} else {$("#fileTypeError").html('*上传文件类型错误,支持类型: .bmp .jpg .jpeg .gif .png');}}</script>
</head>
<body>
<form id="uploadForm" enctype="multipart/form-data">  <!-- 声明文件上传 --><input id="file_upload" type="file" name="file"/>  <!-- 定义change事件,选择文件后触发 --><br/><span style="color: red" id="fileTypeError"></span>    <!-- 文件类型错误回显,此处通过前后端两次验证文件类型 --><br/><input type="button" onclick="uploadfile()" value="上传">
</form>
<div></div>
</body>
</html>

效果展示:
在这里插入图片描述
在这里插入图片描述

5.2 文件管理页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>oss文件管理</title><script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.11.2/jquery.js"></script><script type="text/javascript">var pre = 'https://gaojun-testbucket.oss-cn-shanghai.aliyuncs.com/';$(function () {listfile();});//文件列表function listfile() {$.ajax({url: "http://localhost:8080/file/list",type: 'POST',success: function (rtn) {console.log(rtn.length);for (var i = 0; i < rtn.length; i++) {$('div').append('<img src="' + pre + rtn[i].key + '" style="width: 300px;height: 300px; padding: 10px" ondblclick="deletefile(this.src)" onclick="downloadfile(this.src)"></img>')}}});}//文件下载function downloadfile(src) {var fileName = src.split(pre)[1];window.location.href = "http://localhost:8080/file/download?fileName=" + fileName;}//文件删除function deletefile(src) {var fileName = src.split(pre)[1];var param = {fileName: fileName};$.ajax({url: "http://localhost:8080/file/delete",data: param,success: function () {alert('删除成功',fileName);//删除页面location.reload();}});}</script>
</head>
<body>
单击下载oss上的图片、双击删除oss上的图片<br>
<div>
</div>
</body>
</html>

效果展示:

刚才上传了一张照片,可以立马看到
在这里插入图片描述
单击页面即可下载图片
在这里插入图片描述

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

相关文章:

SpringBoot整合阿里云OSS文件上传、下载、查看、删除

SpringBoot整合阿里云OSS文件上传、下载、查看、删除1、开发准备1.1 前置知识1.2 环境参数1.3 你能学到什么2. 使用阿里云OSS2.1 创建Bucket2.2 管理文件2.3 阿里云OSS文档3. 项目初始化3.1 创建SpringBoot项目3.2 Maven依赖3.3 安装lombok插件4. 后端服务编写4.1 阿里云OSS配置…...

对话数字化经营新模式:第2届22客户节(22Day)年猪宴圆满结束!

2023年2月22日&#xff0c;由杭州电子商务研究院联合贰贰网络(集团)、TO B总监联盟等发起举办的“第二届客户节22Day”暨2022年度爱名奖 AM AWARDS颁奖及22年猪宴沙龙活动圆满结束。 &#xff08;主持人&#xff1a;杜灵芝&#xff09; 本次沙龙邀请到浙江工业大学管理学院程志…...

数据结构——第二章 线性表(5)——双向循环链表

双向循环链表1.双向循环链表的定义2.双向循环链表的基本操作实现2.1 双向循环链表的初始化操作2.2.双向循环链表的插入操作2.3. 双向循环链表的删除操作1.双向循环链表的定义 单向链表便于查询后继结点&#xff0c;不便于查询前驱结点。为了方便两个方向的查询&#xff0c;可以…...

4面美团软件测试工程师,却忽略了这一点,直接让我前功尽弃

说一下我面试别人时候的思路 反过来理解&#xff0c;就是面试时候应该注意哪些东西&#xff1b;用加粗部分标注了 一般面试分为这么几个部分&#xff1a; 一、自我介绍 这部分一般人喜欢讲很多&#xff0c;其实没必要。大约5分钟内说清楚自己的职业经历&#xff0c;自己的核…...

robot remote server用这个server去远程获取ip

server端配置&#xff1a; 1、安装python环境 2、下载robot remote server 下载地址&#xff1a;https://pypi.python.org/pypi/robotremoteserver/&#xff08;不要用pip下载&#xff0c;把robotremoteserver.py文件下载下来&#xff09; 3、首先创建一个目录E:\rfremote\ &a…...

【WSL】Windows 上安装并启动

一、什么是 WSL Windows Subsystem for Linux 适用于 Linux 的 Windows 子系统 可以帮助我们自然、方便地在 Windows 上使用 Linux 子系统 二、安装 我们要安装的是 WSL2 &#xff0c; 因为其功能相对来说更加完善 1. 简化安装 — 本人亲测不好用 简化安装&#xff1a;高…...

SAFe(Scaled Agile Framework)学习笔记

1.SAFe 概述 SAFe&#xff08;Scaled Agile Framework&#xff09;是一种面向大型企业的敏捷开发框架&#xff0c;旨在协调多个团队和部门的协同工作&#xff0c;以实现高效的软件开发和交付。下面是SAFe框架的简单介绍总结&#xff1a; SAFe框架包括以下四个层次&#xff1a…...

Redis 集群搭建

前缀参考文章1&#xff1a;Centos7 安装并启动 Redis-6.2.6 前缀参考文章2&#xff1a;Redis 主从复制-服务器搭建【薪火相传/哨兵模式】 管道符查看所有redis进程&#xff1a;ps -ef|grep redis 杀死所有redis进程&#xff1a;killall redis-server 1. 首先修改 redis.conf 配…...

【Unity VR开发】结合VRTK4.0:创建物理按钮

语录&#xff1a; 如今我努力奔跑&#xff0c;不过是为了追上那个曾经被寄予厚望的自己 前言&#xff1a; 使用线性关节驱动器和碰撞体从动器可以轻松创建基于物理的按钮&#xff0c;以使交互者能够在物理上按下按钮控件&#xff0c;然后挂钩到驱动器事件中以了解按钮何时被按…...

【软件测试】web自动化测试如何开展合适?自动化测试用例如何设计?资深测试的总结......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 首先&#xff0c;还…...

ARouter::Compiler The user has configuration the module name, it was

学习组件化使用的是阿里的ARouter&#xff0c;我是照着案例敲的&#xff0c;在编译的时候报了这么一个错。 我查了好多资料&#xff0c;大部分都是说build.gradle 配置出现了问题&#xff0c;比如没有配置 javaCompileOptions {annotationProcessorOptions {arguments [AROUTE…...

Jmeter(GUI模式)详细教程

Jmeter&#xff08;GUI模式&#xff09;详细教程 目录&#xff1a;导读 一、安装Jmeter 二、Jmeter工作原理 三、Jmeter操作步骤 Jmeter界面 1、测试计划 2、线程组 3、HTTP请求 4、监听器 四、压力测试 写在最后 前些天&#xff0c;领导让我做接口的压力测试。What…...

2023年CDGA考试-第14章-大数据和数据科学(含答案)

2023年CDGA考试-第14章-大数据和数据科学(含答案) 单选题 1.MapReduce模型有三个主要步骤 () A.剖析、关联、聚类 B.提取、转换、加载 C.映射、修正、转换 D.映射、洗牌、归并 答案 D 2.以下哪种技术已经成为面向数据科学的大数据集分析标准平台。 A.MPP技术。 B.Hado…...

【阿旭机器学习实战】【36】糖尿病预测---决策树建模及其可视化

【阿旭机器学习实战】系列文章主要介绍机器学习的各种算法模型及其实战案例&#xff0c;欢迎点赞&#xff0c;关注共同学习交流。 【阿旭机器学习实战】【36】糖尿病预测—决策树建模及其可视化 目录【阿旭机器学习实战】【36】糖尿病预测---决策树建模及其可视化1. 导入数据并…...

简易黑客初级教程:黑客技术,分享教学

第一节&#xff0c;伸展运动。这节操我们要准备道具&#xff0c;俗话说&#xff1a;“工欲善其事&#xff0c;必先利其器”(是这样吗?哎!文化低……)说得有道理&#xff0c;我们要学习黑客技术&#xff0c;一点必要的工具必不可少。 1&#xff0c;一台属于自己的可以上网的电…...

日本公派访问学者的具体申请流程

公派日本访问学者的具体申请流程&#xff0c;知识人网整理了相关的资料以供大家参考。第一、申请材料一般申请CSC日本访问学者&#xff0c;截止日是每年的1月15号左右&#xff0c;但是学院在1月10号之前就审查材料了。材料包括&#xff1a;CSC网页的报名表&#xff0c;教授邀请…...

投票点赞链接制作投票链接在线制作投票图文链接制作点赞

用户在使用微信投票的时候&#xff0c;需要功能齐全&#xff0c;又快捷方便的投票小程序。而“活动星投票”这款软件使用非常的方便&#xff0c;用户可以随时使用手机微信小程序获得线上投票服务&#xff0c;很多用户都很喜欢“活动星投票”这款软件。“活动星投票”小程序在使…...

PHY设备驱动

1. 概述 MAC控制器的驱动使用的是platform总线的连接方式&#xff0c;PHY设备驱动是基于device、driver、bus的连接方式。 其驱动涉及如下几个重要部分&#xff1a; 总线 - sturct mii_bus (mii stand for media independent interface) 设备 - struct phy_device 驱动 - struc…...

Linux——UDP协议与相关套接字编程

一.概念在网络通信中&#xff0c;传输层中最常用的通信协议有两个&#xff1a;TCP协议与UDP协议。这两种协议虽然都可以用于网络通信&#xff0c;但是通信方式不同决定了应用场景的不同。与TCP协议相比&#xff0c;UDP协议最具特色的不同点有两个&#xff1a;无连接与面向数据报…...

EM算法 简明理解

E&#xff1a;Expection&#xff0c;期望步&#xff0c;利用估计的参数&#xff0c;来确定未知因变量的概率&#xff0c;并利用其来计算期望值。 M&#xff1a;Maximization&#xff0c;最大化&#xff0c;使用最大似然法更新参数值&#xff0c;使E步中期望值出现的概率最大。…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Java 二维码

Java 二维码 **技术&#xff1a;**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…...

uni-app学习笔记三十五--扩展组件的安装和使用

由于内置组件不能满足日常开发需要&#xff0c;uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件&#xff0c;需要安装才能使用。 一、安装扩展插件 安装方法&#xff1a; 1.访问uniapp官方文档组件部分&#xff1a;组件使用的入门教程 | uni-app官网 点击左侧…...

StarRocks 全面向量化执行引擎深度解析

StarRocks 全面向量化执行引擎深度解析 StarRocks 的向量化执行引擎是其高性能的核心设计&#xff0c;相比传统行式处理引擎&#xff08;如MySQL&#xff09;&#xff0c;性能可提升 5-10倍。以下是分层拆解&#xff1a; 1. 向量化 vs 传统行式处理 维度行式处理向量化处理数…...

数据挖掘是什么?数据挖掘技术有哪些?

目录 一、数据挖掘是什么 二、常见的数据挖掘技术 1. 关联规则挖掘 2. 分类算法 3. 聚类分析 4. 回归分析 三、数据挖掘的应用领域 1. 商业领域 2. 医疗领域 3. 金融领域 4. 其他领域 四、数据挖掘面临的挑战和未来趋势 1. 面临的挑战 2. 未来趋势 五、总结 数据…...