jeecg-boot中上传图片到华为云obs云存储中

news2025/7/14 20:40:04

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂。

在这里插入图片描述

前言

jeecg-boot框架中,其实对接的功能还是挺多的,其中就有文件云存储服务器,不过是阿里云oss的,那如果我们使用的是七牛云,或者华为云obs呢?我们需要改哪些内容才能实现上传obs的目的呢,今天我们就来看看如何使用jeecg-boot来实现将文件(图片)上传到华为云obs中。

配置nacos

因为我们用的是微服务版本,所以配置都在nacos中,如果是普通的boot版本的话,直接在yml文件中写配置就行。
nacos的配置如下:

  1. 找到jeecg节点,修改uploadType的值:
uploadType: hwobs

记住这个hwobs的值,我们需要在代码中声明一下它,相当于一个变量,这个值必须和代码中声明的那个变量的值一样,不然就找不到了。

  1. 添加obs节点:
  #华为云oss存储配置
  obs:
    endpoint: obs.cn-xxxxx-9.myhuaweicloud.com
    accessKey: KD6BYxxxxxx
    secretKey: Zv83xxxxxx
    bucketName: xxxxx
    staticDomain: xxxxx.obs.cn-xxxxxx-9.myhuaweicloud.com

注意:对应的值需要改成你自己的ak、sk等。

修改POM文件,添加华为云obs的依赖

添加代码如下:

<!--华为云OBS-->
		<dependency>
			<groupId>com.huaweicloud</groupId>
			<artifactId>esdk-obs-java</artifactId>
			<version>3.21.8</version>
			<exclusions>
				<exclusion>
					<groupId>com.squareup.okhttp3</groupId>
					<artifactId>okhttp</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

新建OBS工具类ObsBootUtil

package org.jeecg.common.util.oss;

import com.obs.services.ObsClient;
import com.obs.services.model.ObsObject;
import com.obs.services.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.FileItemStream;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.filter.FileTypeFilter;
import org.jeecg.common.util.filter.StrAttackFilter;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.UUID;

/**
 * @Description: 华为云 oss 上传工具类(高依赖版)
 * @Date: 2019/5/10
 * @author: jeecg-boot
 */
@Slf4j
public class ObsBootUtil {

    private static String endPoint;
    private static String accessKeyId;
    private static String accessKeySecret;
    private static String bucketName;
    /**
     * oss 工具客户端
     */
    private static ObsClient ossClient = null;

    public static String getEndPoint() {
        return endPoint;
    }

    public static void setEndPoint(String endPoint) {
        ObsBootUtil.endPoint = endPoint;
    }

    public static String getAccessKeyId() {
        return accessKeyId;
    }

    public static void setAccessKeyId(String accessKeyId) {
        ObsBootUtil.accessKeyId = accessKeyId;
    }

    public static String getAccessKeySecret() {
        return accessKeySecret;
    }

    public static void setAccessKeySecret(String accessKeySecret) {
        ObsBootUtil.accessKeySecret = accessKeySecret;
    }

    public static String getBucketName() {
        return bucketName;
    }

    public static void setBucketName(String bucketName) {
        ObsBootUtil.bucketName = bucketName;
    }

    public static ObsClient getOssClient() {
        return ossClient;
    }

    /**
     * 上传文件至华为云 OBS
     * 文件上传成功,返回文件完整访问路径
     * 文件上传失败,返回 null
     *
     * @param file    待上传文件
     * @param fileDir 文件保存目录
     * @return oss 中的相对文件路径
     */
    public static String upload(MultipartFile file, String fileDir, String customBucket) throws Exception {
        //update-begin-author:liusq date:20210809 for: 过滤上传文件类型
        FileTypeFilter.fileTypeFilter(file);
        //update-end-author:liusq date:20210809 for: 过滤上传文件类型

        String filePath;
        initOss(endPoint, accessKeyId, accessKeySecret);
        StringBuilder fileUrl = new StringBuilder();
        String newBucket = bucketName;
        if (oConvertUtils.isNotEmpty(customBucket)) {
            newBucket = customBucket;
        }
        try {
            //判断桶是否存在,不存在则创建桶
            if (!ossClient.headBucket(newBucket)) {
                ossClient.createBucket(newBucket);
            }
            // 获取文件名
            String orgName = file.getOriginalFilename();
            if ("".equals(orgName) || orgName == null) {
                orgName = file.getName();
            }
            orgName = CommonUtils.getFileName(orgName);
            String fileName = !orgName.contains(".")
                    ? orgName + "_" + System.currentTimeMillis()
                    : orgName.substring(0, orgName.lastIndexOf("."))
                    + "_" + System.currentTimeMillis()
                    + orgName.substring(orgName.lastIndexOf("."));
            if (!fileDir.endsWith(SymbolConstant.SINGLE_SLASH)) {
                fileDir = fileDir.concat(SymbolConstant.SINGLE_SLASH);
            }
            //update-begin-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
            fileDir = StrAttackFilter.filter(fileDir);
            //update-end-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击
            fileUrl.append(fileDir).append(fileName);

            filePath = "https://" + newBucket + "." + endPoint + SymbolConstant.SINGLE_SLASH + fileUrl;

            PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream());
            // 设置权限(公开读)
//            ossClient.setBucketAcl(newBucket, CannedAccessControlList.PublicRead);
            if (result != null) {
                log.info("------OSS文件上传成功------" + fileUrl);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return filePath;
    }

    /**
     * 文件上传
     *
     * @param file    文件
     * @param fileDir fileDir
     * @return 路径
     */
    public static String upload(MultipartFile file, String fileDir) throws Exception {
        return upload(file, fileDir, null);
    }

    /**
     * 上传文件至华为云 OBS
     * 文件上传成功,返回文件完整访问路径
     * 文件上传失败,返回 null
     *
     * @param file    待上传文件
     * @param fileDir 文件保存目录
     * @return oss 中的相对文件路径
     */
    public static String upload(FileItemStream file, String fileDir) {
        String filePath;
        initOss(endPoint, accessKeyId, accessKeySecret);
        StringBuilder fileUrl = new StringBuilder();
        try {
            String suffix = file.getName().substring(file.getName().lastIndexOf('.'));
            String fileName = UUID.randomUUID().toString().replace("-", "") + suffix;
            if (!fileDir.endsWith(SymbolConstant.SINGLE_SLASH)) {
                fileDir = fileDir.concat(SymbolConstant.SINGLE_SLASH);
            }
            fileDir = StrAttackFilter.filter(fileDir);
            fileUrl.append(fileDir).append(fileName);

            filePath = "https://" + bucketName + "." + endPoint + SymbolConstant.SINGLE_SLASH + fileUrl;

            PutObjectResult result = ossClient.putObject(bucketName, fileUrl.toString(), file.openStream());
            // 设置权限(公开读)
            //ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            if (result != null) {
                log.info("------OSS文件上传成功------" + fileUrl);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return filePath;
    }

    /**
     * 删除文件
     *
     * @param url 路径
     */
    public static void deleteUrl(String url) {
        deleteUrl(url, null);
    }

    /**
     * 删除文件
     *
     * @param url 路径
     */
    public static void deleteUrl(String url, String bucket) {
        String newBucket = bucketName;
        if (oConvertUtils.isNotEmpty(bucket)) {
            newBucket = bucket;
        }
        String bucketUrl = "https://" + newBucket + "." + endPoint + SymbolConstant.SINGLE_SLASH;

        //TODO 暂时不允许删除云存储的文件
        //initOss(endPoint, accessKeyId, accessKeySecret);
        url = url.replace(bucketUrl, "");
        ossClient.deleteObject(newBucket, url);
    }

    /**
     * 删除文件
     *
     * @param fileName 文件名称
     */
    public static void delete(String fileName) {
        ossClient.deleteObject(bucketName, fileName);
    }

    /**
     * 获取文件流
     *
     * @param objectName 对象名
     * @param bucket     桶
     * @return 文件流
     */
    public static InputStream getOssFile(String objectName, String bucket) {
        InputStream inputStream = null;
        try {
            String newBucket = bucketName;
            if (oConvertUtils.isNotEmpty(bucket)) {
                newBucket = bucket;
            }
            initOss(endPoint, accessKeyId, accessKeySecret);
            //update-begin---author:liusq  Date:20220120  for:替换objectName前缀,防止key不一致导致获取不到文件----
            objectName = ObsBootUtil.replacePrefix(objectName, bucket);
            //update-end---author:liusq  Date:20220120  for:替换objectName前缀,防止key不一致导致获取不到文件----
            ObsObject ossObject = ossClient.getObject(newBucket, objectName);
            inputStream = new BufferedInputStream(ossObject.getObjectContent());
        } catch (Exception e) {
            log.info("文件获取失败" + e.getMessage());
        }
        return inputStream;
    }

    /**
     * 获取文件外链
     *
     * @param bucketName 桶名称
     * @param objectName 对项名
     * @param expires    日期
     * @return 外链
     */
    public static String getObjectUrl(String bucketName, String objectName, Date expires) {
        initOss(endPoint, accessKeyId, accessKeySecret);
        try {
            //update-begin---author:liusq  Date:20220120  for:替换objectName前缀,防止key不一致导致获取不到文件----
            objectName = ObsBootUtil.replacePrefix(objectName, bucketName);
            //update-end---author:liusq  Date:20220120  for:替换objectName前缀,防止key不一致导致获取不到文件----
            if (ossClient.doesObjectExist(bucketName, objectName)) {
                //URL url = ossClient.generatePresignedUrl(bucketName, objectName, expires);
                //log.info("原始url : {}", url.toString());
                //log.info("decode url : {}", URLDecoder.decode(url.toString(), "UTF-8"));
                //【issues/4023】问题 oss外链经过转编码后,部分无效,大概在三分一;无需转编码直接返回即可 #4023
                //return url.toString();
                return "";
            }
        } catch (Exception e) {
            log.info("文件路径获取失败" + e.getMessage());
        }
        return null;
    }

    /**
     * 初始化 oss 客户端
     */
    private static void initOss(String endpoint, String accessKeyId, String accessKeySecret) {
        if (ossClient == null) {
            ossClient = new ObsClient(accessKeyId, accessKeySecret, endpoint);
        }
    }


    /**
     * 上传文件到oss
     *
     * @param stream       文件流
     * @param relativePath 相对路径
     * @return 文件路径
     */
    public static String upload(InputStream stream, String relativePath) {
        String filePath = "https://" + bucketName + "." + endPoint + SymbolConstant.SINGLE_SLASH + relativePath;
        initOss(endPoint, accessKeyId, accessKeySecret);
        PutObjectResult result = ossClient.putObject(bucketName, relativePath, stream);
        // 设置权限(公开读)
        //ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
        if (result != null) {
            log.info("------OSS文件上传成功------" + relativePath);
        }
        return filePath;
    }

    /**
     * 替换前缀,防止key不一致导致获取不到文件
     *
     * @param objectName   文件上传路径 key
     * @param customBucket 自定义桶
     * @return 对象名
     * @date 2022-01-20
     * @author lsq
     */
    private static String replacePrefix(String objectName, String customBucket) {
        log.info("------replacePrefix---替换前---objectName:{}", objectName);

        String newBucket = bucketName;
        if (oConvertUtils.isNotEmpty(customBucket)) {
            newBucket = customBucket;
        }
        String path = "https://" + newBucket + "." + endPoint + SymbolConstant.SINGLE_SLASH;

        objectName = objectName.replace(path, "");

        log.info("------replacePrefix---替换后---objectName:{}", objectName);
        return objectName;
    }

    public static String getOriginalUrl(String url) {
        return url;
    }

}

新建OBS配置类

代码如下:


package org.jeecg.config.oss;

import org.jeecg.common.util.oss.ObsBootUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 华为云存储 配置
 *
 * @author: jeecg-boot
 */
@Configuration
public class ObsConfig {

    @Value("${jeecg.obs.endpoint}")
    private String endpoint;
    @Value("${jeecg.obs.accessKey}")
    private String accessKeyId;
    @Value("${jeecg.obs.secretKey}")
    private String accessKeySecret;
    @Value("${jeecg.obs.bucketName}")
    private String bucketName;


    @Bean
    public void initObsBootConfig() {
        ObsBootUtil.setEndPoint(endpoint);
        ObsBootUtil.setAccessKeyId(accessKeyId);
        ObsBootUtil.setAccessKeySecret(accessKeySecret);
        ObsBootUtil.setBucketName(bucketName);
    }
}

声明配置变量

CommonConstant接口中声明在nacos中配置的变量:

String UPLOAD_TYPE_OBS = "hwobs";

在这里插入图片描述

修改原来文件上传的方法

首先找到类CommonUtils,的uploadOnlineImage方法,修改成如下:
在这里插入图片描述

public static String uploadOnlineImage(byte[] data, String basePath, String bizPath, String uploadType) {
        String dbPath = null;
        String fileName = "image" + Math.round(Math.random() * 100000000000L);
        fileName += "." + PoiPublicUtil.getFileExtendName(data);
        try {
            if (CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)) {
                File file = new File(basePath + File.separator + bizPath + File.separator);
                if (!file.exists()) {
                    file.mkdirs();// 创建文件根目录
                }
                String savePath = file.getPath() + File.separator + fileName;
                File savefile = new File(savePath);
                FileCopyUtils.copy(data, savefile);
                dbPath = bizPath + File.separator + fileName;
            } else {
                InputStream in = new ByteArrayInputStream(data);
                String relativePath = bizPath + "/" + fileName;
                if (CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)) {
                    dbPath = MinioUtil.upload(in, relativePath);
                } else if (CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)) {
                    dbPath = OssBootUtil.upload(in, relativePath);
                } else {
                    dbPath = ObsBootUtil.upload(in, relativePath);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dbPath;
    }

修改upload方法:
在这里插入图片描述

 /**
     * 统一全局上传
     *
     * @Return: java.lang.String
     */
    public static String upload(MultipartFile file, String bizPath, String uploadType) {
        String url = "";
        try {
            if (CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)) {
                url = MinioUtil.upload(file, bizPath);
            }  else if (CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)) {
                url = OssBootUtil.upload(file, bizPath);
            }else{
                url = ObsBootUtil.upload(file, bizPath);
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return url;
    }

修改OssFileServiceImpl实现类的upload方法(当然你新写一个也行):

在这里插入图片描述

/**
 * @Description: OSS云存储实现类
 * @author: jeecg-boot
 */
@Service("ossFileService")
public class OssFileServiceImpl extends ServiceImpl<OssFileMapper, OssFile> implements IOssFileService {

	@Override
	public void upload(MultipartFile multipartFile) throws Exception {
		String fileName = multipartFile.getOriginalFilename();
		fileName = CommonUtils.getFileName(fileName);
		OssFile ossFile = new OssFile();
		ossFile.setFileName(fileName);
		//String url = OssBootUtil.upload(multipartFile,"upload/test");
		//改成华为云的
		String url = ObsBootUtil.upload(multipartFile,"upload/test");
		//update-begin--Author:scott  Date:20201227 for:JT-361【文件预览】阿里云原生域名可以文件预览,自己映射域名kkfileview提示文件下载失败-------------------
		// 返回阿里云原生域名前缀URL
		//ossFile.setUrl(OssBootUtil.getOriginalUrl(url));

		// 返回华为云原生域名前缀URL
		ossFile.setUrl(ObsBootUtil.getOriginalUrl(url));
		//update-end--Author:scott  Date:20201227 for:JT-361【文件预览】阿里云原生域名可以文件预览,自己映射域名kkfileview提示文件下载失败-------------------
		this.save(ossFile);
	}

	@Override
	public boolean delete(OssFile ossFile) {
		try {
			this.removeById(ossFile.getId());
			//OssBootUtil.deleteUrl(ossFile.getUrl());
			ObsBootUtil.deleteUrl(ossFile.getUrl());
		}
		catch (Exception ex) {
			log.error(ex.getMessage(),ex);
			return false;
		}
		return true;
	}

}

然后就大功告成了!!!

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

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

相关文章

通过TortoiseGit钩子实现提交前检查作者信息是否正确

1、需求背景 从事嵌入式开发的人运行软件依赖于特定的电脑硬件&#xff0c;可能会存在多人在同一台电脑上开发的需求。 我们使用git进行软件代码版本管理&#xff0c;通过提交时的用户名和邮箱区分某次代码是哪个人提交的信息。git自身支持提交的时临时一次设置成其他的用户信…

01.OpenWrt-写在前面

01.OpenWrt-写在前面 1.1 如何学好OpenWrt OpenWrt究竟应该怎么学,这是我一直在思考的问题! 谈到OpenWrt有相关软硬件知识的人会想到路由器,路由器是OpenWrt系统最主要的使用场景.OpenWrt是基于Linux系统构建起来的,所以其他Linux系统能够做的事情OpenWrt都是可以做到. Ope…

GD32F4(10):GD32转RS422在115200下接收乱码分析

GD32F450&#xff1a;串口转RS485在115200下接收乱码 文章目录GD32F450&#xff1a;串口转RS485在115200下接收乱码1. 知识储备2. 环境3. 操作4. 插入一个知识点&#xff1a;不同MCU串口ip核实现原理4.1 首先我们来看一下STM32f的串口是怎样识别数据的4.2 GD32F4串口识别5. 我的…

毕业设计-基于机器视觉道路视频车道线检测

目录 前言 课题背景和意义 实现技术思路 摄像机校准 ​编辑 透视变换 车道像素查找 识别车道面积 实现效果图样例 前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要…

电商商家必用的4大TikTok营销变现增长技巧

数据显示&#xff0c;TikTok是目前最热门的海外社交媒体平台&#xff0c;已超过多家老牌社媒平台。由于是个短视频平台&#xff0c;在当下环境里具有很强的营销推广优势&#xff0c;很多电商商家都会选择在TikTok营销产品。那电商商家必用哪些TikTok营销变现增长技巧呢&#xf…

基于决策树的智能网络安全入侵检测模型

基于决策树的智能网络安全入侵检测模型学习目标&#xff1a;学习内容&#xff1a;该论文模型下载数据集参考论文&#xff1a;综述/调查&#xff1a;申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计4077字&…

设备全生命周期管理第一股凌雄科技上市,京东、腾讯等长期看好

“设备全生命周期管理第一股”凌雄科技&#xff08;小熊U租&#xff09;于昨日正式在港交所挂牌上市。本次上市&#xff0c;凌雄科技的IPO发行价为7.60港元/股&#xff0c;募集资金净额约为3.372亿港元&#xff0c;上市时的总市值达到26.85亿港元。 特别说明的是&#xff0c;凌…

适用更多会议场景,华为云会议的分组讨论功能来了!

适用更多会议场景&#xff0c;华为云会议的分组讨论功能来了&#xff01; 如今&#xff0c;线上沟通成为常态&#xff0c;线上会议更是成为工作推进过程中不可缺少的环节。但在一些场景中&#xff0c;例如在跨部门协调&#xff0c;沙龙研讨&#xff0c;教育培训或者招聘面试时&…

索引生命周期管理ILM看完不懂你锤我

阅读完本文你可以学到什么是索引生命周期管理&#xff0c;各个阶段可以做的操作以及如何使用索引模版使用索引生命周期策略&#xff0c;下面就跟我一起来吧 基础理论篇 索引生命周期管理&#xff08;ILM&#xff09;是一种可以让我们随着时间推移自动化的管理索引的一种方式。…

SpringBoot SpringBoot 原理篇 1 自动配置 1.1 bean 的加载方式【一】

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇1 自动配置1.1 bean 的加载方式【一】1.1.1 环境准备1.1.2 第一种方式1.1.3 第…

Go-Excelize API源码阅读(三十四)——RemoveRow

Go-Excelize API源码阅读&#xff08;三十四&#xff09;——RemoveRow 开源摘星计划&#xff08;WeOpen Star&#xff09; 是由腾源会 2022 年推出的全新项目&#xff0c;旨在为开源人提供成长激励&#xff0c;为开源项目提供成长支持&#xff0c;助力开发者更好地了解开源&a…

OpenGL原理与实践——核心模式(五):颜色、基础光照、Phong模型、材质与光

目录 颜色相关理论 什么是颜色 如何计算颜色&#xff1f; 简单实现 Phong光照模型——局部光照模型 环境光 ​编辑 漫反射 镜面反射 材质与光 材质与纹理的关系 材质在shader的体现 材质属性与光属性 光在shader的体现 整体源码实现及渲染结果 关键代码 shade…

软件测试员如何在恶劣的内卷环境下脱颖而出?

内卷&#xff0c;是现在热度非常高的一个词汇&#xff0c;随着热度不断攀升&#xff0c;隐隐到了“万物皆可卷”的程度。 我一个很要好的朋友&#xff0c;现在就读大三&#xff0c;像很多大学生一样面临着能否顺利毕业的压力和考证的焦虑&#xff0c;看着寝室四个人每天都在玩&…

Vue--》混合文件使用以及ref的引用讲解

目录 mixin混合 前言 ref的引用DOM ref引用组件 mixin混合 在日常开发中&#xff0c;当我们开发的各种组件可能会有相同的内容&#xff0c;我们可以将相同的内容在各个相对应的组件内删除&#xff0c;然后放在同一个配置里。所谓混合&#xff1a;两个或多个组件共享一个配…

数据挖掘,在商业智能BI领域的运用

数据挖掘在商业领域&#xff0c;特别是在零售业的运用是比较成功的。由于各业务系统的普遍使用&#xff0c;再加上商业智能BI的可视化分析&#xff0c;企业可以收集到大量关于购买情况的数据&#xff0c;并且数据量在不断激增。利用数据挖掘技术可以为经营管理人员提供正确的决…

Java 集合

目录 一、概念 二、接口 2.1、 集合接口 2.2、 Set 接口 2.2.1 zise方法 2.2.2 isEmpty 方法 2.2.3 contains 方法 2.2.4 Iterator 方法 2.2.5 toArray 方法 2.2.6 add 方法 2.2.7 remove 方法 2.2.8 containsAll 方法 2.2.9 containsAll 方法 2.2.10 ret…

数据仓库基础

文章目录1 数据仓库1.1 数据仓库为何而来1.2 数据仓库主要特征1.2.1 面向主题1.2.2 集成性1.2.3 非易失性1.2.4 时变性1.3 数据仓库、数据库、数据集市1.3.1 OLTP1.3.2 OLAP1.3.3 OLTP和OLAP的对比1.3.4 数据库和数据仓库的区别1.3.5 数据仓库和数据集市的区别1.4 数据仓库分层…

Spring Boot Admin2 自定义异常监控

其他相关文章&#xff1a; Spring Boot Admin 参考指南SpringBoot Admin服务离线、不显示健康信息的问题Spring Boot Admin2 EnableAdminServer的加载Spring Boot Admin2 AdminServerAutoConfiguration详解Spring Boot Admin2 实例状态监控详解Spring Boot Admin2 自定义JVM监控…

Java项目:JSP旅游产品销售管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台&#xff0c;分为管理员与普通用户两种角色&#xff0c;管理员登录后台&#xff0c;普通用户登录前台&#xff1b; 管理员角色…

Docker-CentOS开启防火墙firewalled映射Docker端口

开启docker的Tomcat容器后&#xff0c;启动 docker run -d -p 8080:8080 tomcat 访问不了Tomcat 查看防火墙所有开放的端口 firewall-cmd --zonepublic --list-ports 一、需要防火墙开启8080 端口 1、通过systemctl status firewalld查看firewalld状态&#xff0c;发现当前…