SpringBoot 整合 Minio 实现文件切片极速上传技术

Centos7安装Minio

创建目标文件夹

mkdir minio

图片

使用docker查看目标镜像状况

大家需要注意,此处我们首先需要安装docker,对于相关安装教程,大家可以查看我之前的文章,按部就班就可以,此处不再赘述!!!

docker search minio

图片

使用docker拉去镜像

docker pull minio/minio

图片

查看镜像是否拉取成功

docker images

图片

启动Minio容器

docker run -p 9000:9000 -p 9090:9090      --net=host      --name minio      -d --restart=always      -e "MINIO_ACCESS_KEY=IT@WangHui"      -e "MINIO_SECRET_KEY=IT@WangHui"            minio/minio server      /data --console-address ":9000" -address ":9090"

图片

注意一下,对于密码强度是有要求的,不然报错

图片

这是一个运行 MinIO 容器的 Docker 命令,具体参数解释如下:

  • -p: 映射容器内部的端口到宿主机上。其中 9000 和 9090 分别映射到宿主机的 9000 和 9090 端口上。

  • --net=host: 将容器加入到主机网络中,共享宿主机的 IP 地址。

  • --name minio: 指定容器的名称为 minio。

  • --restart=always: 设置容器在退出后自动重新启动。

  • -e: 设置环境变量。这里设置了两个环境变量:MINIO_ACCESS_KEY 和 MINIO_SECRET_KEY,值分别为 IT@WangHui 和 IT@WangHui

  • --mount: 将容器内部的目录挂载到宿主机上。这里将容器内的 /data 目录挂载到了宿主机的 /data 目录上。

  • --console-address: 指定容器的控制台地址。这里设置为 :9000,表示可以通过宿主机上的 9000 端口访问容器的控制台。

  • -address: 指定容器的网络地址。这里设置为 :9090,表示可以通过宿主机上的 9090 端口访问容器的服务。

提示:页面访问9000,代码里面9090

提示:页面访问9000,代码里面9090

提示:页面访问9000,代码里面9090

报错警告

图片

原因:

主要是因为在启动docker容器的时候或做docker配置的时候,还对防火墙设置重新启动等配置,这样会清除docker的相关配置,导致在查询防火墙规则的时候显示不到docker的链。iptables -L查询iptables链。

解决:

是由于firewalld重启导致,而docker重启又会将其注册iptables链找回来。

然后删除刚才启动失败的容器,不然会继续报错容器已存在

systemctl restart docker #重启docker
docker ps -a #查看运行容器
docker rm -f minio #根据容器名删除容器(自己注意辨别自己的)

图片

当启动后在浏览器访问http://localhost:9000就可以访问minio的图形化界面了,如图所示:

图片

用户名密码就是启动参数里面的数据

如果访问失败,那就是防火墙问题或者是启动参数最后两项没有添加,再不会有其他的,除非容器没有启动成功

查看放行端口可以使用如下命令

 firewall-cmd --list-ports

要放行CentOS 7上的9000端口和9090端口,您可以按照以下步骤操作:

1.检查防火墙状态

使用以下命令检查防火墙状态:

systemctl status firewalld

如果防火墙已停止,则启动它:

systemctl start firewalld
2.允许9000端口通过防火墙

使用以下命令允许TCP流量通过9000端口:

firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --zone=public --add-port=9090/tcp --permanent

这将向防火墙添加一个规则,以允许TCP流量通过9000端口。要永久保存此更改,请运行以下命令:

firewall-cmd --reload
3.重新启动防火墙服务shell

使用以下命令重新启动防火墙服务:

systemctl restart firewalld

现在,您已经成功地放行了CentOS 7上的9000和9090端口。

 搭建springboot 环境

代码结构

图片

引入项目依赖

<!-- 操作minio的java客户端-->
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.2</version>
</dependency>
<!-- 操作minio的java客户端--><dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.1</version>
</dependency>
<!--        jwt鉴权相应依赖-->
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.11.2</version>
</dependency>

创建容器桶

图片

图片

获取API访问凭证

图片

图片

编写配置文件

server:port: 8080
spring:servlet:multipart:max-file-size: 10MBmax-request-size: 10MB#minio配置minio:access-key: dAMaxkWaXUD1CV1JHbqwsecret-key: AXt3SD0JFkDENFbMeJKOOQb5wj8KvabZWu33Rs84url: http://192.168.18.14:9090  #访问地址bucket-name: wanghui

首先是服务器的配置:

  • 端口号为8080,用于监听请求。

  • 使用了一个Servlet来处理multipart/form-data类型的请求。

  • 在接收到multipart/form-data类型的请求时,会将上传的文件大小限制在10MB以内,并将请求大小限制在10MB以内。

接下来是minio的配置:

  • access-keysecret-key是访问minio服务的凭证,需要根据实际情况进行填写。

  • url是minio服务的地址,需要根据实际情况进行填写。

  • bucket-name是存储文件的桶名,需要根据实际情况进行填写。

http请求状态

package com.xiaohui.utils;/*** @Description http请求状态* @Author IT小辉同学* @Date 2023/06/01*/
public class HttpStatus
{/*** 操作成功*/public static final int SUCCESS = 200;/*** 对象创建成功*/public static final int CREATED = 201;/*** 请求已经被接受*/public static final int ACCEPTED = 202;/*** 操作已经执行成功,但是没有返回数据*/public static final int NO_CONTENT = 204;/*** 资源已被移除*/public static final int MOVED_PERM = 301;/*** 重定向*/public static final int SEE_OTHER = 303;/*** 资源没有被修改*/public static final int NOT_MODIFIED = 304;/*** 参数列表错误(缺少,格式不匹配)*/public static final int BAD_REQUEST = 400;/*** 未授权*/public static final int UNAUTHORIZED = 401;/*** 访问受限,授权过期*/public static final int FORBIDDEN = 403;/*** 资源,服务未找到*/public static final int NOT_FOUND = 404;/*** 不允许的http方法*/public static final int BAD_METHOD = 405;/*** 资源冲突,或者资源被锁*/public static final int CONFLICT = 409;/*** 不支持的数据,媒体类型*/public static final int UNSUPPORTED_TYPE = 415;/*** 系统内部错误*/public static final int ERROR = 500;/*** 接口未实现*/public static final int NOT_IMPLEMENTED = 501;/*** 系统警告消息*/public static final int WARN = 601;
}

通用常量信息

package com.xiaohui.utils;import io.jsonwebtoken.Claims;/*** @Description 通用常量信息* @Author IT小辉同学* @Date 2023/06/01*/
public class Constants
{/*** UTF-8 字符集*/public static final String UTF8 = "UTF-8";/*** GBK 字符集*/public static final String GBK = "GBK";/*** www主域*/public static final String WWW = "www.";/*** http请求*/public static final String HTTP = "http://";/*** https请求*/public static final String HTTPS = "https://";/*** 通用成功标识*/public static final String SUCCESS = "0";/*** 通用失败标识*/public static final String FAIL = "1";/*** 登录成功*/public static final String LOGIN_SUCCESS = "Success";/*** 注销*/public static final String LOGOUT = "Logout";/*** 注册*/public static final String REGISTER = "Register";/*** 登录失败*/public static final String LOGIN_FAIL = "Error";/*** 验证码有效期(分钟)*/public static final Integer CAPTCHA_EXPIRATION = 2;/*** 令牌*/public static final String TOKEN = "token";/*** 令牌前缀*/public static final String TOKEN_PREFIX = "Bearer ";/*** 令牌前缀*/public static final String LOGIN_USER_KEY = "login_user_key";/*** 用户ID*/public static final String JWT_USERID = "userid";/*** 用户名称*/public static final String JWT_USERNAME = Claims.SUBJECT;/*** 用户头像*/public static final String JWT_AVATAR = "avatar";/*** 创建时间*/public static final String JWT_CREATED = "created";/*** 用户权限*/public static final String JWT_AUTHORITIES = "authorities";/*** 资源映射路径 前缀*/public static final String RESOURCE_PREFIX = "/profile";/*** RMI 远程方法调用*/public static final String LOOKUP_RMI = "rmi:";/*** LDAP 远程方法调用*/public static final String LOOKUP_LDAP = "ldap:";/*** LDAPS 远程方法调用*/public static final String LOOKUP_LDAPS = "ldaps:";/*** 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)*/public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };/*** 定时任务违规的字符*/public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml","org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" };
}

创建Minio的配置类

package com.xiaohui.config;import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @Description minio配置* @Author IT小辉同学* @Date 2023/06/02*/
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.minio")
public class MinioConfig {private String accessKey;private String secretKey;private String url;private String bucketName;@Beanpublic MinioClient minioClient(){return MinioClient.builder().endpoint(url).credentials(accessKey,secretKey).build();}
}

这段代码是Java中的一个配置类,用于配置与MinIO(一个对象存储服务)相关的属性。具体来说:

  • @Configuration注解表示这是一个配置类,用于将该类中定义的属性注入到其他组件中使用。

  • @ConfigurationProperties注解表示该类使用了spring.minio.*前缀的属性来配置Minio相关的属性。

  • @Data注解表示自动生成getter和setter方法,简化了代码编写。

  • accessKeysecretKey属性分别表示访问密钥和密钥值,用于连接到MinIO服务。

  • url属性表示MinIO服务的URL地址。

  • bucketName属性表示存储桶名称。

  • @Bean注解表示将minioClient()方法返回的对象注册为bean,以便在其他组件中使用。

  • minioClient()方法返回了一个MinioClient对象,用于连接到MinIO服务并操作存储桶。其中,endpoint()方法用于设置MinIO服务的URL地址,credentials()方法用于设置访问密钥和密钥值。

创建Minio的工具类

package com.xiaohui.utils;import com.xiaohui.config.MinioConfig;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.SneakyThrows;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;/*** @Description Minio工具类* @Author IT小辉同学* @Date 2023/06/02*/@Component
public class MinioUtils {@Autowiredprivate MinioClient minioClient;@Autowiredprivate MinioConfig configuration;/*** @param name 名字* @return boolean* @Description description: 判断bucket是否存在,不存在则创建* @Author IT小辉同学* @Date 2023/06/02*/public boolean existBucket(String name) {boolean exists;try {exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());if (!exists) {minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());exists = true;}} catch (Exception e) {e.printStackTrace();exists = false;}return exists;}/*** @param bucketName 存储bucket名称* @return {@link Boolean }* @Description 创建存储bucket* @Author IT小辉同学* @Date 2023/06/02*/public Boolean makeBucket(String bucketName) {try {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** @param bucketName 存储bucket名称* @return {@link Boolean }* @Description 删除存储bucket* @Author IT小辉同学* @Date 2023/06/02*/public Boolean removeBucket(String bucketName) {try {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** @param fileName 文件名称* @param time     时间* @return {@link Map }* @Description 获取上传临时签名* @Author IT小辉同学* @Date 2023/06/02*/@SneakyThrowspublic Map getPolicy(String fileName, ZonedDateTime time) {PostPolicy postPolicy = new PostPolicy(configuration.getBucketName(), time);postPolicy.addEqualsCondition("key", fileName);try {Map<String, String> map = minioClient.getPresignedPostFormData(postPolicy);HashMap<String, String> map1 = new HashMap<>();map.forEach((k, v) -> {map1.put(k.replaceAll("-", ""), v);});map1.put("host", configuration.getUrl() + "/" + configuration.getBucketName());return map1;} catch (ErrorResponseException e) {e.printStackTrace();} catch (InsufficientDataException e) {e.printStackTrace();} catch (InternalException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (InvalidResponseException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (ServerException e) {e.printStackTrace();} catch (XmlParserException e) {e.printStackTrace();}return null;}/*** @param objectName 对象名称* @param method     方法* @param time       时间* @param timeUnit   时间单位* @return {@link String }* @Description 获取上传文件的url* @Author IT小辉同学* @Date 2023/06/02*/public String getPolicyUrl(String objectName, Method method, int time, TimeUnit timeUnit) {try {return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(method).bucket(configuration.getBucketName()).object(objectName).expiry(time, timeUnit).build());} catch (ErrorResponseException e) {e.printStackTrace();} catch (InsufficientDataException e) {e.printStackTrace();} catch (InternalException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (InvalidResponseException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (XmlParserException e) {e.printStackTrace();} catch (ServerException e) {e.printStackTrace();}return null;}/*** @param file     文件* @param fileName 文件名称* @Description 上传文件* @Author IT小辉同学* @Date 2023/06/02*/public void upload(MultipartFile file, String fileName) {// 使用putObject上传一个文件到存储桶中。try {InputStream inputStream = file.getInputStream();minioClient.putObject(PutObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).stream(inputStream, file.getSize(), -1).contentType(file.getContentType()).build());} catch (ErrorResponseException e) {e.printStackTrace();} catch (InsufficientDataException e) {e.printStackTrace();} catch (InternalException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (InvalidResponseException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (ServerException e) {e.printStackTrace();} catch (XmlParserException e) {e.printStackTrace();}}/*** @param objectName 对象名称* @param time       时间* @param timeUnit   时间单位* @return {@link String }* @Description 根据filename获取文件访问地址* @Author IT小辉同学* @Date 2023/06/02*/public String getUrl(String objectName, int time, TimeUnit timeUnit) {String url = null;try {url = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(configuration.getBucketName()).object(objectName).expiry(time, timeUnit).build());} catch (ErrorResponseException e) {e.printStackTrace();} catch (InsufficientDataException e) {e.printStackTrace();} catch (InternalException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (InvalidResponseException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (XmlParserException e) {e.printStackTrace();} catch (ServerException e) {e.printStackTrace();}return url;}/*** @param fileName* @return {@link ResponseEntity }<{@link byte[] }>* @Description description: 下载文件* @Author IT小辉同学* @Date 2023/06/02*/public ResponseEntity<byte[]> download(String fileName) {ResponseEntity<byte[]> responseEntity = null;InputStream in = null;ByteArrayOutputStream out = null;try {in = minioClient.getObject(GetObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());out = new ByteArrayOutputStream();IOUtils.copy(in, out);//封装返回值byte[] bytes = out.toByteArray();HttpHeaders headers = new HttpHeaders();try {headers.add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();}headers.setContentLength(bytes.length);headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);headers.setAccessControlExposeHeaders(Arrays.asList("*"));responseEntity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.SUCCESS);} catch (Exception e) {e.printStackTrace();} finally {try {if (in != null) {try {in.close();} catch (IOException e) {e.printStackTrace();}}if (out != null) {out.close();}} catch (IOException e) {e.printStackTrace();}}return responseEntity;}/*** @param objectFile 对象文件* @return {@link String }* @Description 根据文件名和桶获取文件路径* @Author IT小辉同学* @Date 2023/06/02*/public String getFileUrl(String objectFile) {try {return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().method(Method.GET).bucket(configuration.getBucketName()).object(objectFile).build());} catch (Exception e) {e.printStackTrace();}return null;}}

该代码是一个工具类,用于使用阿里云的对象存储服务(OSS)进行文件上传和下载。具体功能如下:

  • getPolicy(String fileName, ZonedDateTime time):根据文件名和时间戳获取上传临时签名。

  • getPolicyUrl(String objectName, Method method, int time, TimeUnit timeUnit):获取上传文件的url。

  • upload(MultipartFile file, String fileName):将文件上传到OSS中。

  • getUrl(String objectName, int time, TimeUnit timeUnit):获取文件的下载url。

代码中使用了枚举类型来定义不同的上传和下载方法。

使用了注解@Autowired来自动注入MinioClient对象。

该工具类没有提供异常处理机制,需要根据实际情况进行补充。

创建Ajax请求工具类

/*** @Description ajax结果* @Author IT小辉同学* @Date 2023/06/01*/
public class AjaxResult extends HashMap<String, Object>
{private static final long serialVersionUID = 1L;/** 状态码 */public static final String CODE_TAG = "code";/** 返回内容 */public static final String MSG_TAG = "msg";/** 数据对象 */public static final String DATA_TAG = "data";/*** 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。*/public AjaxResult(){}/*** 初始化一个新创建的 AjaxResult 对象** @param code 状态码* @param msg 返回内容*/public AjaxResult(int code, String msg){super.put(CODE_TAG, code);super.put(MSG_TAG, msg);}/*** 初始化一个新创建的 AjaxResult 对象** @param code 状态码* @param msg 返回内容* @param data 数据对象*/public AjaxResult(int code, String msg, Object data){super.put(CODE_TAG, code);super.put(MSG_TAG, msg);if (data!=null){super.put(DATA_TAG, data);}}/*** 返回成功消息** @return 成功消息*/public static AjaxResult success(){return AjaxResult.success("操作成功");}/*** 返回成功数据** @return 成功消息*/public static AjaxResult success(Object data){return AjaxResult.success("操作成功", data);}/*** 返回成功消息** @param msg 返回内容* @return 成功消息*/public static AjaxResult success(String msg){return AjaxResult.success(msg, null);}/*** 返回成功消息** @param msg 返回内容* @param data 数据对象* @return 成功消息*/public static AjaxResult success(String msg, Object data){return new AjaxResult(HttpStatus.SUCCESS, msg, data);}/*** 返回警告消息** @param msg 返回内容* @return 警告消息*/public static AjaxResult warn(String msg){return AjaxResult.warn(msg, null);}/*** 返回警告消息** @param msg 返回内容* @param data 数据对象* @return 警告消息*/public static AjaxResult warn(String msg, Object data){return new AjaxResult(HttpStatus.WARN, msg, data);}/*** 返回错误消息** @return 错误消息*/public static AjaxResult error(){return AjaxResult.error("操作失败");}/*** 返回错误消息** @param msg 返回内容* @return 错误消息*/public static AjaxResult error(String msg){return AjaxResult.error(msg, null);}/*** 返回错误消息** @param msg 返回内容* @param data 数据对象* @return 错误消息*/public static AjaxResult error(String msg, Object data){return new AjaxResult(HttpStatus.ERROR, msg, data);}/*** 返回错误消息** @param code 状态码* @param msg 返回内容* @return 错误消息*/public static AjaxResult error(int code, String msg){return new AjaxResult(code, msg, null);}/*** 方便链式调用** @param key 键* @param value 值* @return 数据对象*/@Overridepublic AjaxResult put(String key, Object value){super.put(key, value);return this;}
}

创建Minio文件操作接口层

package com.xiaohui.controller;import com.xiaohui.utils.AjaxResult;
import com.xiaohui.utils.MinioUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.util.HashMap;/*** @Description minio文件上传控制器* @Author IT小辉同学* @Date 2023/06/02*/
@CrossOrigin
@RestController
@RequestMapping("/api")
public class MinioFileUploadController {@Autowiredprivate MinioUtils minioUtils;/*** @param file     文件* @param fileName 文件名称* @return {@link AjaxResult }* @Description 上传文件* @Author IT小辉同学* @Date 2023/06/02*/@GetMapping("/upload")public AjaxResult uploadFile(@RequestParam("file") MultipartFile file, String fileName) {minioUtils.upload(file, fileName);return AjaxResult.success("上传成功");}/*** @param fileName 文件名称* @return {@link ResponseEntity }* @Description dowload文件* @Author IT小辉同学* @Date 2023/06/02*/@GetMapping("/dowload")public ResponseEntity dowloadFile(@RequestParam("fileName") String fileName) {return minioUtils.download(fileName);}/*** @param fileName 文件名称* @return {@link AjaxResult }* @Description 得到文件url* @Author IT小辉同学* @Date 2023/06/02*/@GetMapping("/getUrl")public AjaxResult getFileUrl(@RequestParam("fileName") String fileName){HashMap map=new HashMap();map.put("FileUrl",minioUtils.getFileUrl(fileName));return AjaxResult.success(map);}
}

功能测试

Minio大文件上传

图片

图片

Minio大文件地址

图片

图片

最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

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

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

相关文章

uniapp入门

一、新建项目 进入到主界面&#xff0c;左上角点击新建——1.项目 输入项目名称&#xff0c;Vue版本选择3 二、创建页面 选中左侧文件目录里的pages文件夹&#xff0c;右键&#xff0c;选择新建页面 1输入名称 2选中“创建同名目录” 3选择模板&…

将json对象转为xml进行操作属性

将json对象转为xml进行操作属性 文章目录 将json对象转为xml进行操作属性前端发送json数据格式写入数据库格式-content字段存储&#xff08;varchar(2000)&#xff09;Question实体类-接口映射对象QuestionContent 接收参数对象DAO持久层Mapper层Service层Controller控制层接收…

普元EOS学习笔记-低开实现图书的增删改查

前言 在前一篇《普元EOS学习笔记-创建精简应用》中&#xff0c;我已经创建了EOS精简应用。 我之前说过&#xff0c;EOS精简应用就是自己创建的EOS精简版&#xff0c;该项目中&#xff0c;开发者可以进行低代码开发&#xff0c;也可以进行高代码开发。 本文我就记录一下自己在…

2024年6月 | deepin 深度应用商店-应用更新记录

新增应用 序号应用名称depein 系统版本应用分类应用类型1bkViewer 照片浏览器deepin 20.9 deepin V23网络应用wine291助手deepin 20.9 deepin V23编程开发wine3风云CAD转换器deepin 20.9 deepin V23编程开发wine4Disk Savvydeepin 20.9 deepin V23系统工具wine5飞猫盘…

miniconda3 安装jupyter notebook并配置网络访问

由于服务器安装的miniconda3&#xff0c;无jupyter notebook&#xff0c;所以手工安装jupyter notebook 1 先conda 安装相关包 在base 环境下 conda install ipython conda install jupyter notebook 2 生成配置文件 jupyter notebook --generate-config Writing defaul…

Nginx 常用配置与应用

Nginx 常用配置与应用 官网地址&#xff1a;https://nginx.org/en/docs/ 目录 Nginx 常用配置与应用 Nginx总架构 正向代理 反向代理 Nginx 基本配置反向代理案例 负载均衡 Nginx总架构 进程模型 正向代理 反向代理 Nginx 基本配置反向代理案例 负载均衡 Nginx 基本配置…

新人程序员接手丑陋的老代码怎么办?改还是不改......

许多小伙伴在初入职场的时候&#xff0c;都会遇到要接手老代码的情况&#xff0c;那么问题来了&#xff0c;如果老代码十分丑陋&#xff0c;你是改还是不改&#xff1f; 不改吧&#xff0c;心里难受&#xff1b;改吧&#xff0c;指不定会遇到什么情况&#xff0c;比如…… 1.…

【嫦娥四号】月球着陆器中子和剂量测量(LND)实验

一、引言 嫦娥四号任务是中国月球探测计划的重要里程碑&#xff0c;实现了人类首次在月球背面软着陆&#xff0c;并展开了月面巡视和中继通信。本文所描述的嫦娥四号着陆器上的中子与剂量测定实验&#xff08;Lunar Lander Neutrons and Dosimetry Experiment, LND&#xff09…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【17】认证服务01 环境搭建验证码倒计时短信服务邮件服务验证码短信形式&#xff1a;邮件形式&#xff1a; 异常机制MD5参考 环境搭建 C:\Windows\System32\drivers\etc\hosts 192.168.…

JAVA每日作业day7.1-7.3小总结

ok了家人们前几天学了一些知识&#xff0c;接下来一起看看吧 一.API Java 的 API &#xff08; API: Application( 应用 ) Programming( 程序 ) Interface(接口 ) &#xff09; Java API 就是 JDK 中提供给我们使用的类&#xff0c;这些类将底层 的代码实现封装了起来&#x…

【echarts】拖拽滑块dataZoom-slider自定义样式,简单适配移动端

电脑端 移动端 代码片段 dataZoom: [{type: inside,start: 0,end: 100},{type: slider,backgroundColor: #F2F5F9,fillerColor: #BFCCE3,height: 13, // 设置slider的高度为15start: 0,end: 100,right: 60,left: 60,bottom: 15,handleIcon:path://M30.9,53.2C16.8,53.2,5.3,41.…

Linux源码阅读笔记12-RCU案例分析

在之前的文章中我们已经了解了RCU机制的原理和Linux的内核源码&#xff0c;这里我们要根据RCU机制写一个demo来展示他应该如何使用。 RCU机制的原理 RCU&#xff08;全称为Read-Copy-Update&#xff09;,它记录所有指向共享数据的指针的使用者&#xff0c;当要修改构想数据时&…

不要把面子太当回事

新手拍短视频真人出镜&#xff0c;会觉得拍视频不自然怎么办&#xff1f;感觉自己好傻。 其实不要把面子太当回事&#xff0c;坚持不把面子太当回事&#xff0c;反正刚开始也没人看。这是真的事实&#xff0c;大家都非常忙&#xff0c;在你身上停留的时间就几秒钟。不要在脑海…

systemctl命令使用

systemctl 作用&#xff1a;可以控制软件&#xff08;服务&#xff09;的启动、关闭、开机自启动 系统内置服务均可被systemctl控制第三方软件&#xff0c;如果自动注册了可以被systemctl控制第三方软件&#xff0c;如果没有自动注册&#xff0c;可以手动注册 语法 systemct…

企业出海如何应对国际差旅报销的复杂性?

在全球化浪潮的推动下&#xff0c;越来越多的中国企业开始迈向国际市场。然而&#xff0c;企业在“走出去”的过程中不仅面临新的商机&#xff0c;也需要克服诸多挑战。尤其是国际差旅报销的复杂性&#xff0c;成为出海企业必须解决的重要问题。 国际差旅报销的四大挑战 多元…

【分布式数据仓库Hive】常见问题及解决办法

目录 一、启动hive时发现log4j版本和hadoop的版本有冲突 解决办法&#xff1a;删除hive下高版本的slf4j 二、启动hive报错 Exception in thread "main" java.lang.NoSuchMethodError:com.google.common.base.Preconditions.checkArgument(ZLjava/lang/Object;)V …

postgres数据库的流复制

1. 流复制和逻辑复制的差异 逻辑复制和流复制最直观的不同是&#xff0c;逻辑复制支持表级别复制区分点事原理不同 逻辑日志是在wal日志产生的数据库上&#xff0c;由逻辑解析模块对wal日志进行初步的解析&#xff0c;解析结果是ReorderBufferChange&#xff08;理解为HeapTup…

干货分享|如何将前端代理服务器(BFF)接入身份认证(3完结篇)

续集3 前篇文章在前面发布&#xff0c;同学们可以自行找一下。 本篇文章将继续通过实例来详细讲解如何将前端代理服务器&#xff08;BFF&#xff09;接入身份认证。我们将使用一个示例应用来演示 BFF 与身份认证的集成过程。 3 在 Full BFF 中接入认证平台 本小节将介绍如何…

Raylib 坐标系适应与GPU绘制参数

通过750 - 鼠标坐标&#xff0c;把原点在左上角的鼠标坐标变成左下角 实现输入数据后的坐标系同GPU原点在左下角坐标相同&#xff0c; 比数组0&#xff0c;0对应左上角好&#xff0c; 此时实际上数组0&#xff0c;0对应左下角 #include <raylib.h> // 感受&#xff1a…

【SpringBoot配置文件读取】无法读取yaml文件中文字符

1. yaml配置文件 注意要将该文件编码格式改为UTF-8 spring:application:name: 好好学习admin:name: 李斯age: 24books:- name: 数据结构desc: 数据书- name: 编译原理desc: 编译书2.配置实体类 Data设置get&#xff0c;set方法Component注册为BeanConfigurationProperties(p…