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

两种上传图片的方式——91张先生

上传图片的两种方式


`

文章目录

  • 上传图片的两种方式
  • 前言
  • 一、直接上传到项目jar包根目录
      • 工具类的方法
      • Untils
  • 二、上传到MinIo
      • 搭建MinIo服务就跳过了,宝塔直接一分钟搭建,然后创建Bruck
        • Controller
        • Service
  • 总结
      • 两种方式都可以,第一种更倾向于小数量,在项目下存储,第二种更倾向于大数据量存储,使用OSS上传


前言

每个程序员貌似对上传图片都有一种执念,感觉一个项目有了上传图片上传文件的功能就很难,今天就给大家分享一下怎么上传图片,直接上干货


一、直接上传到项目jar包根目录

工具类的方法

/**/*** 获取上传路径*/public static String getUploadPath(){return getProfile() + "/upload";}* 通用上传请求(单个)*/@PostMapping("/upload")public AjaxResult uploadFile(MultipartFile file) throws Exception{try{// 上传文件路径String filePath = getUploadPath();// 上传并返回新文件名称String fileName = FileUploadUtils.upload(filePath, file);String url = serverConfig.getUrl() + fileName;AjaxResult ajax = AjaxResult.success();ajax.put("url", url);ajax.put("fileName", fileName);ajax.put("newFileName", FileUtils.getName(fileName));ajax.put("originalFilename", file.getOriginalFilename());return ajax;}catch (Exception e){return AjaxResult.error(e.getMessage());}}

Untils

 public static final String[] DEFAULT_ALLOWED_EXTENSION = {// 图片"bmp", "gif", "jpg", "jpeg", "png",// word excel powerpoint"doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",// 压缩文件"rar", "zip", "gz", "bz2",// 视频格式"mp4", "avi", "rmvb",// pdf"pdf" };/*** 根据文件路径上传** @param baseDir 相对应用的基目录* @param file 上传的文件* @return 文件名称* @throws IOException*/public static final String upload(String baseDir, MultipartFile file) throws IOException{try{return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);}catch (Exception e){throw new IOException(e.getMessage(), e);}}/*** 默认的文件名最大长度 100*/public static final int DEFAULT_FILE_NAME_LENGTH = 100;
/*** 文件上传** @param baseDir 相对应用的基目录* @param file 上传的文件* @param allowedExtension 上传文件类型* @return 返回上传成功的文件名* @throws FileSizeLimitExceededException 如果超出最大大小* @throws FileNameLengthLimitExceededException 文件名太长* @throws IOException 比如读写文件出错时* @throws InvalidExtensionException 文件校验异常*/public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,InvalidExtensionException{return upload(baseDir, file, allowedExtension, false);}/*** 文件上传** @param baseDir 相对应用的基目录* @param file 上传的文件* @param useCustomNaming 系统自定义文件名* @param allowedExtension 上传文件类型* @return 返回上传成功的文件名* @throws FileSizeLimitExceededException 如果超出最大大小* @throws FileNameLengthLimitExceededException 文件名太长* @throws IOException 比如读写文件出错时* @throws InvalidExtensionException 文件校验异常*/public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension, boolean useCustomNaming)throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,InvalidExtensionException{int fileNameLength = Objects.requireNonNull(file.getOriginalFilename()).length();if (fileNameLength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH){throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);}assertAllowed(file, allowedExtension);String fileName = useCustomNaming ? uuidFilename(file) : extractFilename(file);String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();file.transferTo(Paths.get(absPath));return getPathFileName(baseDir, fileName);}/*** 默认大小 50M*/public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024L;public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" };public static final String[] FLASH_EXTENSION = { "swf", "flv" };public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg","asf", "rm", "rmvb" };public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" };/*** 文件大小校验** @param file 上传的文件* @return* @throws FileSizeLimitExceededException 如果超出最大大小* @throws InvalidExtensionException*/public static final void assertAllowed(MultipartFile file, String[] allowedExtension)throws FileSizeLimitExceededException, InvalidExtensionException{long size = file.getSize();if (size > DEFAULT_MAX_SIZE){throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);}String fileName = file.getOriginalFilename();String extension = getExtension(file);if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension)){if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION){throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION){throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION){throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,fileName);}else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION){throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,fileName);}else{throw new InvalidExtensionException(allowedExtension, extension, fileName);}}}/*** 编编码文件名(日期格式目录 + UUID + 后缀)*/public static final String uuidFilename(MultipartFile file){return StringUtils.format("{}/{}.{}", DateUtils.datePath(), IdUtils.fastSimpleUUID(), getExtension(file));}public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException{File desc = new File(uploadDir + File.separator + fileName);if (!desc.exists()){if (!desc.getParentFile().exists()){desc.getParentFile().mkdirs();}}return desc;}/*** 编码文件名(日期格式目录 + 原文件名 + 序列值 + 后缀)*/public static final String extractFilename(MultipartFile file){return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));}public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException{File desc = new File(uploadDir + File.separator + fileName);if (!desc.exists()){if (!desc.getParentFile().exists()){desc.getParentFile().mkdirs();}}return desc;}/*** 资源映射路径 前缀*/public static final String RESOURCE_PREFIX = "/profile";public static final String getPathFileName(String uploadDir, String fileName) throws IOException{int dirLastIndex = getProfile().length() + 1;String currentDir = StringUtils.substring(uploadDir, dirLastIndex);return Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;}

二、上传到MinIo

搭建MinIo服务就跳过了,宝塔直接一分钟搭建,然后创建Bruck

Controller
/*** 上传OSS对象存储** @param file 文件*/@SaCheckPermission("system:oss:upload")@Log(title = "OSS对象存储", businessType = BusinessType.INSERT)@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)public R<SysOssUploadVo> upload(@RequestPart("file") MultipartFile file) {if (ObjectUtil.isNull(file)) {return R.fail("上传文件不能为空");}SysOssVo oss = ossService.upload(file);SysOssUploadVo uploadVo = new SysOssUploadVo();uploadVo.setUrl(oss.getUrl());uploadVo.setFileName(oss.getOriginalName());uploadVo.setOssId(oss.getOssId().toString());return R.ok(uploadVo);}/*** 下载OSS对象** @param ossId OSS对象ID*/@SaCheckPermission("system:oss:download")@GetMapping("/download/{ossId}")public void download(@PathVariable Long ossId, HttpServletResponse response) throws IOException {ossService.download(ossId, response);}
Service
@Overridepublic SysOssVo upload(MultipartFile file) {String originalfileName = file.getOriginalFilename();String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());OssClient storage = OssFactory.instance();UploadResult uploadResult;try {uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());} catch (IOException e) {throw new ServiceException(e.getMessage());}SysOssExt ext1 = new SysOssExt();ext1.setFileSize(file.getSize());ext1.setContentType(file.getContentType());// 保存文件信息return buildResultEntity(originalfileName, suffix, storage.getConfigKey(), uploadResult, ext1);}
 /*** 上传 byte[] 数据到 Amazon S3,使用指定的后缀构造对象键。** @param data   要上传的 byte[] 数据* @param suffix 对象键的后缀* @return UploadResult 包含上传后的文件信息* @throws OssException 如果上传失败,抛出自定义异常*/public UploadResult uploadSuffix(byte[] data, String suffix, String contentType) {return upload(new ByteArrayInputStream(data), getPath(properties.getPrefix(), suffix), Long.valueOf(data.length), contentType);}
public static final String SLASH = "/";/*** 上传 InputStream 到 Amazon S3** @param inputStream 要上传的输入流* @param key         在 Amazon S3 中的对象键* @param length      输入流的长度* @param contentType 文件内容类型* @return UploadResult 包含上传后的文件信息* @throws OssException 如果上传失败,抛出自定义异常*/public UploadResult upload(InputStream inputStream, String key, Long length, String contentType) {// 如果输入流不是 ByteArrayInputStream,则将其读取为字节数组再创建 ByteArrayInputStreamif (!(inputStream instanceof ByteArrayInputStream)) {inputStream = new ByteArrayInputStream(IoUtil.readBytes(inputStream));}try {// 创建异步请求体(length如果为空会报错)BlockingInputStreamAsyncRequestBody body = BlockingInputStreamAsyncRequestBody.builder().contentLength(length).subscribeTimeout(Duration.ofSeconds(120)).build();// 使用 transferManager 进行上传Upload upload = transferManager.upload(x -> x.requestBody(body).addTransferListener(LoggingTransferListener.create()).putObjectRequest(y -> y.bucket(properties.getBucketName()).key(key).contentType(contentType)// 用于设置对象的访问控制列表(ACL)。不同云厂商对ACL的支持和实现方式有所不同,// 因此根据具体的云服务提供商,你可能需要进行不同的配置(自行开启,阿里云有acl权限配置,腾讯云没有acl权限配置)//.acl(getAccessPolicy().getObjectCannedACL()).build()).build());// 将输入流写入请求体body.writeInputStream(inputStream);// 等待文件上传操作完成CompletedUpload uploadResult = upload.completionFuture().join();String eTag = uploadResult.response().eTag();// 提取上传结果中的 ETag,并构建一个自定义的 UploadResult 对象return UploadResult.builder().url(getUrl() + StringUtils.SLASH + key).filename(key).eTag(eTag).build();} catch (Exception e) {throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");}}
@NotNullprivate SysOssVo buildResultEntity(String originalfileName, String suffix, String configKey, UploadResult uploadResult, SysOssExt ext1) {SysOss oss = new SysOss();oss.setUrl(uploadResult.getUrl());oss.setFileSuffix(suffix);oss.setFileName(uploadResult.getFilename());oss.setOriginalName(originalfileName);oss.setService(configKey);oss.setExt1(JsonUtils.toJsonString(ext1));baseMapper.insert(oss);SysOssVo sysOssVo = MapstructUtils.convert(oss, SysOssVo.class);return this.matchingUrl(sysOssVo);}
package org.dromara.common.oss.factory;import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.CacheNames;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.oss.constant.OssConstant;
import org.dromara.common.oss.core.OssClient;
import org.dromara.common.oss.exception.OssException;
import org.dromara.common.oss.properties.OssProperties;
import org.dromara.common.redis.utils.CacheUtils;
import org.dromara.common.redis.utils.RedisUtils;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;/*** 文件上传Factory** @author ZZW*/
@Slf4j
public class OssFactory {/*** 全局 redis key (业务无关的key)*/String GLOBAL_REDIS_KEY = "global:";/*** 默认配置KEY*/String DEFAULT_CONFIG_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "sys_oss:default_config";private static final Map<String, OssClient> CLIENT_CACHE = new ConcurrentHashMap<>();private static final ReentrantLock LOCK = new ReentrantLock();/*** 获取默认实例*/public static OssClient instance() {// 获取redis 默认类型String configKey = RedisUtils.getCacheObject(OssConstant.DEFAULT_CONFIG_KEY);if (StringUtils.isEmpty(configKey)) {throw new OssException("文件存储服务类型无法找到!");}return instance(configKey);}/*** 根据类型获取实例*/public static OssClient instance(String configKey) {String json = CacheUtils.get(CacheNames.SYS_OSS_CONFIG, configKey);if (json == null) {throw new OssException("系统异常, '" + configKey + "'配置信息不存在!");}OssProperties properties = JsonUtils.parseObject(json, OssProperties.class);// 使用租户标识避免多个租户相同key实例覆盖String key = configKey;if (StringUtils.isNotBlank(properties.getTenantId())) {key = properties.getTenantId() + ":" + configKey;}OssClient client = CLIENT_CACHE.get(key);// 客户端不存在或配置不相同则重新构建if (client == null || !client.checkPropertiesSame(properties)) {LOCK.lock();try {client = CLIENT_CACHE.get(key);if (client == null || !client.checkPropertiesSame(properties)) {CLIENT_CACHE.put(key, new OssClient(configKey, properties));log.info("创建OSS实例 key => {}", configKey);return CLIENT_CACHE.get(key);}} finally {LOCK.unlock();}}return client;}}
@Overridepublic void init() {List<SysOssConfig> list = baseMapper.selectList();// 加载OSS初始化配置for (SysOssConfig config : list) {String configKey = config.getConfigKey();if ("0".equals(config.getStatus())) {RedisUtils.setCacheObject(OssConstant.DEFAULT_CONFIG_KEY, configKey);}CacheUtils.put(CacheNames.SYS_OSS_CONFIG, config.getConfigKey(), JsonUtils.toJsonString(config));}}
package org.dromara.common.oss.constant;import org.dromara.common.core.constant.GlobalConstants;import java.util.Arrays;
import java.util.List;/*** 对象存储常量** @author ZZW*/
public interface OssConstant {/*** 默认配置KEY*/String DEFAULT_CONFIG_KEY = GlobalConstants.GLOBAL_REDIS_KEY + "sys_oss:default_config";/*** 预览列表资源开关Key*/String PEREVIEW_LIST_RESOURCE_KEY = "sys.oss.previewListResource";/*** 系统数据ids*/List<Long> SYSTEM_DATA_IDS = Arrays.asList(1L, 2L, 3L, 4L);/*** 云服务商*/String[] CLOUD_SERVICE = new String[] {"aliyun", "qcloud", "qiniu", "obs"};/*** https 状态*/String IS_HTTPS = "Y";}

总结

两种方式都可以,第一种更倾向于小数量,在项目下存储,第二种更倾向于大数据量存储,使用OSS上传

http://www.dtcms.com/a/565885.html

相关文章:

  • web3品牌RWA资产自主发行设计方案
  • 网站公司是做什么的长沙做网站备案
  • 【k8s】Kubernetes 资源限制设置规范手册 MB与MiB的概念混淆问题
  • 网站开发需要多长时间互联网有限公司
  • 撰写网站规划书网络服务示范区创建情况
  • 汇川高压变频故障码解析F134 F149 F150 F151 F154 F155 F157 F159 F160
  • 从 C 到 C++20 协程编写方法的演变。第一部分:函数 + 宏 = 协程
  • 采购管理软件选型避坑指南
  • 广州网站搭建多少钱网站的pv uv
  • ubuntu上安装交叉编译工具链说明
  • 【博资考5】网安2025
  • 怎样在别人网站做加强链接宁波网站推广专业服务
  • 做网站申请域名中国定制家具网
  • 合肥网站建设司图石家庄建设局网站怎么打不开
  • 开启学习具身智能之路
  • 使用husky+ commitlint检查提交描述是否符合规范要求
  • 【计算机软件资格考试】软考综合知识题高频考题及答案解析3
  • 达梦删除表空间的内部执行过程
  • 外贸建设网站合优做网站需要多少钱
  • 利用DeepSeek采用hugeint转字符串函数完善luadbi-duckdb的decimal处理
  • Memcached CAS 命令详解
  • 厦门市建设合同备案网站简约网站欣赏
  • 【Docker】关闭所有容器
  • 珠宝行网站建设方案搜索热度查询
  • Apache ShardingSphere-JDBC
  • 印刷网站建设网站建设总结ppt
  • 使用Qt Designer开发上位机
  • 嵌入式开发的“偷懒”高效艺术
  • 网站建设 优惠免费logo设计图
  • 苏州网站建设业务的公司全立体网站建设