ps:时隔两年了没有更新博客了,今天出一篇关于又拍云Java客户端封装的工具类;都自己写的,里面的部分缺失的部分可以根据代码上下文猜出来的,就不发了。

pom.xml: 

<dependency><groupId>com.upyun</groupId><artifactId>java-sdk</artifactId><version>4.2.3</version>
</dependency>

又拍云工具类: UpyOssUtil 

package com.xx.util;import cn.hutool.core.date.StopWatch;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ReflectUtil;
import com.google.common.base.Splitter;
import com.upyun.ParallelUploader;
import com.upyun.RestManager;
import com.upyun.UpYunUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.stream.Collectors;/*** 又拍云 对象存储工具类* <p>* 注:接口返回的如http://xxxx.test.upcdn.net/test/20211215135525.png* 如果调用api的时候,添加了content-secret(文件秘钥仅支持大小写的 A-Z 以及数字 0-9 不支持符号),那么就代表这个地址的文件是私有的,* 直接用http://xxxx.test.upcdn.net/test/20211215135525.png是只会得到404,* 需要用如:http://xxxx.test.upcdn.net/test/20211215135525.png!abc(!:间隔符,abc:content-secret的值)** @author lucifer*/
@Slf4j
public class UpyOssUtil {/*** 构造对象缓存*/private static final SimpleCache<Class<?>, Object> INSTANCE_CACHE = new SimpleCache<>();/*** 上传** @param upYunConf  又拍云必填配置* @param params     又拍云的可选参数(参考:{@link com.upyun.Params})* @param biFunction function* @return*/private static <T> List<String> upload(UpYunConf upYunConf, Map<String, String> params, Class<T> clazz, BiFunction<T, Map<String, String>, List<String>> biFunction) {//校验参数check(StrUtils.isNotBlank(upYunConf.getNameSpace()) || StrUtils.isNotBlank(upYunConf.getUserName()) || StrUtils.isNotBlank(upYunConf.getPassword()) || StrUtils.isNotBlank(upYunConf.getAddress()), "upYunConf中必填属性可能存在空值");//获取对象实例(先从缓存中获取)T instance = getInstance(clazz, upYunConf.getNameSpace(), upYunConf.getUserName(), upYunConf.getPassword());List<String> urlList = biFunction.apply(instance, params);if (CollUtil.isNotEmpty(urlList)) {return urlList.stream().map(url -> {if (isRewriteUrl(url)) {//得到的URL如:https://v0.api.upyun.com/mall-cert/test/20211215135525.png//需要进行改写:又拍云控制台提供的域名/目录/文件名.文件后缀名 如:http://mall-cert.test.upcdn.net/test/20211215135525.pngObject bucketName = ReflectUtil.getFieldValue(instance, "bucketName");return removeFutileSlash(StrUtils.join(getScheme(upYunConf.getAddress()), StrUtils.substring(url, bucketName.toString())));}return url;}).collect(Collectors.toList());}return urlList;}/*** 上传** @param upYunConf     又拍云配置* @param uploadDirPath 上传至又拍云的目录路径 (/test   /test/a/)* @param data          文件字节数组* @param fileName      文件名,包含文件名后缀(.jpg .txt .png)  注:文件名重复,会出现覆盖,如果该字段不传,那么fileSuffix就必填* @param fileSuffix    文件名后缀(.jpg .txt .png),如果文件名fileName参数传值了,这个字段可以不传了,优先级fileName高* @param params        又拍云的可选参数(参考:{@link com.upyun.Params})* @param checkMD5      是否校验md5*                      // 设置待上传文件的 Content-MD5 值*                      // 如果又拍云服务端收到的文件MD5值与用户设置的不一致,将会报 406 NotAcceptable 错误* @return*/public static String upload(UpYunConf upYunConf, String uploadDirPath, byte[] data, String fileName, String fileSuffix, Map<String, String> params, boolean checkMD5) {return upload(upYunConf, params, RestManager.class, (restManager, map) -> {String url = "";try {//校验check(isDirectory(uploadDirPath), "上传至又拍云的目录路径不合法,请校验");check(StrUtils.isNotBlank(fileName) || StrUtils.isNotBlank(fileSuffix), "文件名fileName或者文件名后缀fileSuffix,两个字段必填其中一个");String fileNameTemp = fileName;if (StrUtils.isBlank(fileNameTemp)) {fileNameTemp = StrUtils.join(new Snowflake().nextIdStr(), fileSuffix);}String uploadPath = uploadDirPath.endsWith("/") ? StrUtils.join(uploadDirPath, fileNameTemp) : StrUtils.join(uploadDirPath, "/", fileNameTemp);//是否校验md5if (checkMD5) {params.put(RestManager.PARAMS.CONTENT_MD5.getValue(), UpYunUtils.md5(data));}Response response = restManager.writeFile(uploadPath, data, map);if (response.isSuccessful()) {url = response.request().url().toString();}log.debug("文件上传 message:{}", response.message());} catch (Exception e) {log.error("文件上传失败:error:{}", e);}return Collections.singletonList(url);}).get(0);}/*** 上传** @param bucketName    桶* @param userName      用户名* @param password      密码,需要MD5加密* @param hosts         如:www.baidu.com* @param uploadDirPath uploadDirPath 上传至又拍云的目录路径 (/test   /test/a/)* @param data          字节数组* @param fileSuffix    文件后缀名* @param params        又拍云的可选参数(参考:{@link com.upyun.Params})* @return*/public static String upload(String bucketName, String userName, String password, String hosts, String uploadDirPath, byte[] data, String fileSuffix, Map<String, String> params) {return upload(UpYunConf.buildUpYunConf(bucketName, userName, password, hosts), uploadDirPath, data, null, fileSuffix, params, true);}/*** 上传** @param bucketName    桶* @param userName      用户名* @param password      密码,需要MD5加密* @param hosts         如:www.baidu.com* @param uploadDirPath 上传至又拍云的目录路径 (/test   /test/a/)* @param data          字节数组* @param fileSuffix    文件后缀名* @return*/public static String upload(String bucketName, String userName, String password, String hosts, String uploadDirPath, byte[] data, String fileSuffix) {return upload(UpYunConf.buildUpYunConf(bucketName, userName, password, hosts), uploadDirPath, data, null, fileSuffix, new HashMap<>(), true);}/*** 上传,可以自己设置是否校验md5,如果文件过大,建议设置为false** @param upYunConf     又拍云配置* @param uploadDirPath 上传至又拍云的目录路径 (/test   /test/a/)* @param dataList      文件字节数组* @param fileSuffix    文件名后缀(.jpg .txt .png)* @param checkMD5      是否校验md5*                      // 设置待上传文件的 Content-MD5 值*                      // 如果又拍云服务端收到的文件MD5值与用户设置的不一致,将会报 406 NotAcceptable 错误* @return*/public static List<String> upload(UpYunConf upYunConf, String uploadDirPath, List<byte[]> dataList, String fileSuffix, boolean checkMD5) {return upload(upYunConf, uploadDirPath, dataList, fileSuffix, new HashMap<>(), checkMD5);}/*** 上传 (默认校验md5,如果文件过大,不建议使用该方法)** @param upYunConf     又拍云配置* @param uploadDirPath 上传至又拍云的目录路径 (/test   /test/a/)* @param dataList      文件字节数组* @param fileSuffix    文件名后缀(.jpg .txt .png)* @return*/public static List<String> upload(UpYunConf upYunConf, String uploadDirPath, List<byte[]> dataList, String fileSuffix) {return upload(upYunConf, uploadDirPath, dataList, fileSuffix, new HashMap<>(), true);}/*** 上传** @param upYunConf     又拍云配置* @param uploadDirPath 上传至又拍云的目录路径 (/test   /test/a/)* @param dataList      文件字节数组* @param fileSuffix    文件名后缀(.jpg .txt .png)* @param params        又拍云的可选参数(参考:{@link com.upyun.Params})* @param checkMD5      是否校验md5*                      // 设置待上传文件的 Content-MD5 值*                      // 如果又拍云服务端收到的文件MD5值与用户设置的不一致,将会报 406 NotAcceptable 错误* @return*/public static List<String> upload(UpYunConf upYunConf, String uploadDirPath, List<byte[]> dataList, String fileSuffix, Map<String, String> params, boolean checkMD5) {List<String> resultList = new ArrayList<>();try {List<Callable<String>> tasks = new ArrayList<>();for (byte[] bytes : dataList) {Callable<String> callable = () -> upload(upYunConf, uploadDirPath, bytes, null, fileSuffix, params, checkMD5);tasks.add(callable);}//提交任务resultList.addAll(submit(tasks));} catch (Exception ex) {log.error("文件上传失败:error:{}", ex);}return resultList;}/*** 上传 (默认校验md5,如果文件过大,不建议使用该方法,选择可以将md5校验设置为false的方法)** @param bucketName 桶* @param userName   用户名* @param password   密码,需要MD5加密* @param hosts      如:www.baidu.com* @param uploadPath 上传文件路径(如果上传文件路径:/test,文件名后缀:.jpg,那么就会后台算法生成文件名,得到的路径如:/test/123.jpg;如果上传文件的路径是/test/123.jpg,那么参数fileSuffix可以为空)* @param dataList   文件字节数组* @param fileSuffix 文件名后缀(.jpg .txt .png)* @return*/public static List<String> upload(String bucketName, String userName, String password, String hosts, String uploadPath, List<byte[]> dataList, String fileSuffix) {return upload(UpYunConf.buildUpYunConf(bucketName, userName, password, hosts), uploadPath, dataList, fileSuffix, new HashMap<>(), true);}/*** 上传 (默认校验md5,如果文件过大,不建议使用该方法,选择可以将md5校验设置为false的方法)** @param bucketName 桶* @param userName   用户名* @param password   密码,需要MD5加密* @param hosts      如:www.baidu.com* @param uploadPath 上传文件路径(如果上传文件路径:/test,文件名后缀:.jpg,那么就会后台算法生成文件名,得到的路径如:/test/123.jpg;如果上传文件的路径是/test/123.jpg,那么参数fileSuffix可以为空)* @param dataList   文件字节数组* @param fileSuffix 文件名后缀(.jpg .txt .png)* @param checkMD5   是否校验md5*                   // 设置待上传文件的 Content-MD5 值*                   // 如果又拍云服务端收到的文件MD5值与用户设置的不一致,将会报 406 NotAcceptable 错误* @return*/public static List<String> upload(String bucketName, String userName, String password, String hosts, String uploadPath, List<byte[]> dataList, String fileSuffix, boolean checkMD5) {return upload(UpYunConf.buildUpYunConf(bucketName, userName, password, hosts), uploadPath, dataList, fileSuffix, new HashMap<>(), checkMD5);}/*** 上传 (默认校验md5,如果文件过大,不建议使用该方法,选择可以将md5校验设置为false的方法)** @param bucketName    桶* @param userName      用户名* @param password      密码,需要MD5加密* @param hosts         如:www.baidu.com* @param uploadDirPath 上传至又拍云的目录路径 (/test   /test/a/)* @param files         多文件* @param params        又拍云的可选参数(参考:{@link com.upyun.Params})* @return*/public static List<String> parallelUpload(String bucketName, String userName, String password, String hosts, String uploadDirPath, List<File> files, Map<String, String> params) {return parallelUpload(UpYunConf.buildUpYunConf(bucketName, userName, password, hosts), uploadDirPath, files, params);}/*** 上传** @param bucketName    桶* @param userName      用户名* @param password      密码,需要MD5加密* @param hosts         如:www.baidu.com* @param uploadDirPath 上传至又拍云的目录路径 (/test   /test/a/)* @param files         多文件* @return*/public static List<String> parallelUpload(String bucketName, String userName, String password, String hosts, String uploadDirPath, List<File> files) {return parallelUpload(UpYunConf.buildUpYunConf(bucketName, userName, password, hosts), uploadDirPath, files, new HashMap<>());}/*** 上传** @param upYunConf     又拍云配置* @param uploadDirPath 上传至又拍云的目录路径 (/test   /test/a/)* @param files         多文件* @return*/public static List<String> parallelUpload(UpYunConf upYunConf, String uploadDirPath, List<File> files) {return parallelUpload(upYunConf, uploadDirPath, files, new HashMap<>());}/*** 上传** @param upYunConf     又拍云配置* @param uploadDirPath 上传至又拍云的目录路径 (/test   /test/a/)* @param files         多文件* @param params        又拍云的可选参数(参考:{@link com.upyun.Params})* @return*/public static List<String> parallelUpload(UpYunConf upYunConf, String uploadDirPath, List<File> files, Map<String, String> params) {return parallelUpload(upYunConf, uploadDirPath, files, params, true, true);}/*** 上传** @param upYunConf             又拍云配置* @param uploadDirPath         上传至又拍云的目录路径 (/test   /test/a/)* @param files                 多文件* @param checkMD5              是否校验md5,如果文件过大,建议设置为false*                              // 设置待上传文件的 Content-MD5 值*                              // 如果又拍云服务端收到的文件MD5值与用户设置的不一致,将会报 406 NotAcceptable 错误* @param isUseGenerateFileName 是否使用算法生成文件名,TRUE 使用方法中的算法生成文件名;false 则使用文件本身的文件名* @return*/public static List<String> parallelUpload(UpYunConf upYunConf, String uploadDirPath, List<File> files, boolean checkMD5, boolean isUseGenerateFileName) {return parallelUpload(upYunConf, uploadDirPath, files, new HashMap<>(), checkMD5, isUseGenerateFileName);}/*** 上传** @param upYunConf             又拍云配置* @param uploadDirPath         上传至又拍云的目录路径 (/test   /test/a/)* @param files                 多文件* @param isUseGenerateFileName 是否使用算法生成文件名,TRUE 使用方法中的算法生成文件名;false 则使用文件本身的文件名* @return*/public static List<String> parallelUpload(UpYunConf upYunConf, String uploadDirPath, List<File> files, boolean isUseGenerateFileName) {return parallelUpload(upYunConf, uploadDirPath, files, new HashMap<>(), true, isUseGenerateFileName);}/*** 上传** @param upYunConf             又拍云配置* @param uploadDirPath         上传至又拍云的目录路径 (/test   /test/a/)* @param files                 多文件* @param params                又拍云的可选参数(参考:{@link com.upyun.Params})* @param checkMD5              是否校验md5,如果文件过大,建议设置为false*                              // 设置待上传文件的 Content-MD5 值*                              // 如果又拍云服务端收到的文件MD5值与用户设置的不一致,将会报 406 NotAcceptable 错误* @param isUseGenerateFileName 是否使用算法生成文件名,TRUE 使用方法中的算法生成文件名;false 则使用文件本身的文件名* @return*/public static List<String> parallelUpload(UpYunConf upYunConf, String uploadDirPath, List<File> files, Map<String, String> params, boolean checkMD5, boolean isUseGenerateFileName) {return upload(upYunConf, params, ParallelUploader.class, (parallelUploader, map) -> {List<String> resultList = new ArrayList<>();try {check(isDirectory(uploadDirPath), "上传至又拍云的目录路径不合法,请校验");//设置上传进度监听parallelUploader.setOnProgressListener((index, total) -> log.debug("文件上传中=====:index::{},total::{}", index, index * 100 / total + "%"));//设置 MD5 校验parallelUploader.setCheckMD5(checkMD5);//利用线程池,多文件进行上传List<Callable<String>> tasks = new ArrayList<>();for (File file : files) {Callable<String> callable = () -> {String fileName = file.getName();//如果使用方法中算法生成的文件名(注:文件名重复,会出现覆盖)if (isUseGenerateFileName) {fileName = StrUtils.join(new Snowflake().nextIdStr(), getFileSuffix(file));}String uploadPath = uploadDirPath.endsWith("/") ? StrUtils.join(uploadDirPath, fileName) : StrUtils.join(uploadDirPath, "/", fileName);boolean upload = parallelUploader.upload(file.getPath(), uploadPath, params);if (upload) {return removeFutileSlash(StrUtils.join(getScheme(upYunConf.getAddress()), uploadPath));}return "";};tasks.add(callable);}//提交任务resultList.addAll(submit(tasks));} catch (Exception e) {log.error("文件上传失败:error:{}", e);}return resultList;});}/*** 下载(response.body() 包含文件流信息)** @param upYunConf 又拍云配置* @param filePath  文件路径 /test/1484464385422077952.jpg* @return*/public static byte[] read(UpYunConf upYunConf, String filePath) {RestManager restManager = new RestManager(upYunConf.getNameSpace(), upYunConf.getUserName(), upYunConf.getPassword());try {Response result = restManager.readFile(filePath);if (result.isSuccessful()) {return result.body().bytes();}} catch (Exception ex) {log.error("文件读取失败:{}", ex);}return null;}/*** 下载文件,返回未加如data:image/png;base64前缀的字符串(使用Base64编码方案将指定的字节数组编码为字符串)** @param upYunConf 又拍云配置* @param filePath  又拍云文件路径 /test/1484464385422077952.jpg* @return*/public static String readImage(UpYunConf upYunConf, String filePath) {byte[] read = read(upYunConf, filePath);return Base64.getEncoder().encodeToString(read);}/*** 下载文件,返回未加如data:image/png;base64前缀的字符串(使用Base64编码方案将指定的字节数组编码为字符串)** @param spec 要解析为 URL的字符* @return*/public static String readImage(String spec) {return Base64.getEncoder().encodeToString(IoUtil.readBytes(read(spec)));}/*** 下载文件,使用Base64编码方案将指定的字节数组编码为字符串,并在前面加上类似前缀data:image/png;base64,** @param upYunConf* @param filePath  文件后缀名 如: jpg,不带.符号* @return*/public static String base64StrToImage(UpYunConf upYunConf, String filePath) {return StrUtils.join("data:image/", getFileSuffix(filePath), ";base64,", readImage(upYunConf, filePath));}/*** 下载文件,使用Base64编码方案将指定的字节数组编码为字符串,并在前面加上类似前缀data:image/png;base64,** @param spec       要解析为 URL的字符串* @param fileSuffix 文件后缀名 如: jpg,不带.符号* @return*/public static String base64StrToImage(String spec, String fileSuffix) {//从要解析为 URL的字符串中获取文件后缀名,由于该文件设置了content-secret,所以获取文件后缀名,就会有pem!abc123,需要去掉content-secret(!abc123)return StrUtils.join("data:image/", StrUtils.isNotBlank(fileSuffix) ? fileSuffix : getFileSuffix(spec), ";base64,", readImage(spec));}/*** 下载文件,使用Base64编码方案将指定的字节数组编码为字符串,并在前面加上类似前缀data:image/png;base64,** @param spec 要解析为 URL的字符串* @return*/public static String base64StrToImage(String spec) {return base64StrToImage(spec, null);}/*** 下载文件** @param spec 要解析为 URL的字符串* @return*/public static InputStream read(String spec) {return FileUtil.getFileInputStream(spec);}/*** 获取文件后缀名(带.)** @param file 文件* @return*/private static String getFileSuffix(File file) {return "." + FileUtil.getSuffix(file);}/*** 获取文件后缀名(不带.)** @param filePath 文件路径* @return*/private static String getFileSuffix(String filePath) {String fileSuffix = FileUtil.getSuffix(filePath);//标识符可为半角字符:“!”,“-”,“_” 三种,可以在管理中进行更改。(默认是"!")if (fileSuffix.contains("!")) {fileSuffix = StrUtils.sub(fileSuffix, 0, "!");} else if (fileSuffix.contains("-")) {fileSuffix = StrUtils.sub(fileSuffix, 0, "-");} else if (fileSuffix.contains("_")) {fileSuffix = StrUtils.sub(fileSuffix, 0, "_");}return fileSuffix;}/*** 是否是又拍云的路径* 如:* /test/           true* /test            true* /test/a.txt      false* /test/a.jpg      false** @return*/private static boolean isDirectory(String path) {//这里简单判断下,路径包含1个及以上的/,并且不带.return StrUtils.countShow(path, "/") >= 1 & !path.contains(".");}/*** 判断是否为true,为false则抛异常** @param flag* @param msg* @param <T>*/public static <T> void check(boolean flag, String msg) {if (!flag) {throw new IllegalArgumentException(msg);}}/*** 是否需要重写URL** @param url* @return*/private static boolean isRewriteUrl(String url) {List<String> apiDomainList = Arrays.asList(RestManager.ED_AUTO, RestManager.ED_CNC, RestManager.ED_CTT, RestManager.ED_TELECOM);for (String apiDomain : apiDomainList) {if (url.contains(apiDomain)) {return true;}}return false;}/*** 将URL中无用的//替换成为/* 如:https://xx//test/20211215135525.png 替换成 https:/xx/test/20211215135525.png** @param text* @return*/private static String removeFutileSlash(String text) {//如果url中出现了一次以上的//,则拼接有问题if (StrUtils.countShow(text, "//") > 1) {//则将第二次及其后面的//替换成///以双斜杠拆分List<String> strList = Splitter.on("//").splitToList(text);//再将如http://或者https://与后面的字符串用/拼接text = StrUtils.join(strList.stream().findFirst().get(), "//", strList.stream().skip(1).collect(Collectors.joining("/")));}return text;}/*** "http" or "https".** @return*/private static String getScheme(String hosts) {return hosts.startsWith("http") || hosts.startsWith("https") ? hosts : "http://" + hosts;}/*** 利用反射获取构造方法,并且实例化对象* 这里返回的实例对象(可能会是RestManager、SerialUploader、ParallelUploader等其中一个)** @param clazz 类* @param args  参数* @param <T>* @return*/private static <T> T getInstance(Class<T> clazz, Object... args) {//先从缓存中获取T t = (T) INSTANCE_CACHE.get(clazz);try {if (Objects.isNull(t)) {Constructor<T> constructor = ReflectUtil.getConstructor(clazz, String.class, String.class, String.class);T newInstance = constructor.newInstance(args);INSTANCE_CACHE.put(clazz, newInstance);return newInstance;}} catch (Exception e) {log.error("获取构造方法失败,error:{}", e);}return t;}/*** 线程池 提交任务** @return*/public static List<String> submit(List<Callable<String>> tasks) throws Exception {List<String> result = new ArrayList<>();StopWatch stopWatch = new StopWatch("耗时统计:");AtomicInteger taskNum = new AtomicInteger();int availableProcessors = Runtime.getRuntime().availableProcessors();ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(availableProcessors,availableProcessors + 1,60,TimeUnit.SECONDS,new LinkedBlockingQueue<>(50),new ThreadPoolExecutor.CallerRunsPolicy());try {for (Callable<String> task : tasks) {stopWatch.start(StrUtils.join("task:", taskNum.addAndGet(1)));result.add(threadPoolExecutor.submit(task).get());stopWatch.stop();}return result;} finally {//打印耗时结果log.debug(stopWatch.prettyPrint(TimeUnit.MILLISECONDS));threadPoolExecutor.shutdown();}}}

又拍云upyun 文件上传(Java)相关推荐

  1. Java中阿里云OSS文件上传工具类

    阿里云OSS文件上传下载工具类 前言: 本质上就是获取配置文件信息,然后注入bean,调用sdk中提供的增删改方法: 为了避免同名文件会替换,用了hutool中唯一id生成+文件名做拼接 导入依赖:→ ...

  2. 又拍云使用ajax 上传

    在又拍云官网,没有提供js的demo,只有node.js,和其他的,而现在又有通过 js来上传文件到又拍云的服务器,不能通过自己的服务器进行中转操作,这样会耗费自己的服务器的带宽. 上代码吧,这个代码 ...

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

    SpringBoot整合阿里云OSS文件上传.下载.查看.删除 该项目源码地址:https://github.com/ggb2312/springboot-integration-examples ( ...

  4. 华为云OBS文件上传下载工具类

    Java-华为云OBS文件上传下载工具类 文章目录 Java-华为云OBS文件上传下载工具类 1.华为云obs文件上传下载 2.文件流转MultipartFile 3.File转换为Multipart ...

  5. 解决阿里云oss文件上传部分MP4格式视频文件上传导致上传崩溃问题

    解决阿里云oss文件上传部分MP4格式视频文件上传导致上传崩溃问题 问题描述 java程序,使用阿里云oss文件上传服务,在测试时偶然发现,我用苹果手机开启高清进行摄像,将原图通过qq传到电脑上,在电 ...

  6. 阿里云oss文件上传工具类

    阿里云oss文件上传工具类 阿里云oss 阿里云oss 导入文件阿里云oss的maven依赖 <!-- 阿里云oss依赖 --><dependency><groupId& ...

  7. 阿里云OSS文件上传下载,拿来即用

    什么是OSS 我们可以理解为就是一个资源服务器,在这之前我也尝试过Nginx当静态资源服务器,但效果比较一般,为什么选择阿里云OSS,只是因为最近刚好公司用到了,所以就接入了,还有其他的比如七牛云,腾 ...

  8. aliyun oss 文件上传 java.net.SocketTimeoutException Read timed out 问题分析及解决

    aliyun oss 文件上传 java.net.SocketTimeoutException Read timed out 问题分析及解决 参考文章: (1)aliyun oss 文件上传 java ...

  9. 华为云OBS文件上传和下载

    华为云Obs文件上传和下载 使用的技术 前端是Vue框架,element-ui 后端是Springboot项目 服务器是华为云 文件上传下载地方是华为云Obs对象存储服务 1.前端上传代码 el-up ...

最新文章

  1. What type of NoSQL database is best suited to store hierarchical data?【转】
  2. lollipods耳机蓝牙连接方法
  3. mysql mail_vpopmail+mysql
  4. 【bzoj2238】Mst(树链剖分+线段树)
  5. 【Flask】Nginx / Gunicorn入门:部署你的Flask项目
  6. python次方运算_neg__python 魔术方法1 运算符重载
  7. [转]CPoint+CSize+CRect学习大纲
  8. vue-i18n和ElementUI国际化使用
  9. 通过配置hosts.allow和hosts.deny文件允许或禁止ssh或telnet操作
  10. flutter打包出的问题
  11. React-Native组件之Text内文字垂直居中方案
  12. linux 动态输出函数名,控制linux动态链接库导出函数
  13. 详解Unity中的刚体和碰撞体组件
  14. Win8 MSDN 简中/繁中/英文正式版下载(微软官方原版)
  15. python黑网站充值_Python黑帽子:Windows系统提权
  16. 沟通CTBS物业管理行业远程接入解决方案
  17. 电话面试的技巧和注意事项
  18. [白话解析]以水浒传为例学习隐马尔可夫模型
  19. Python可视化打包神器,绝了!
  20. springboot支付宝APP支付与退款

热门文章

  1. WPS本地表格数据粘贴到钉钉在线表格
  2. Arduino改装蓝牙控制风力仿生兽
  3. java 界面线性布局_布局Layouts之LinearLayout线性布局
  4. consul命令行查看服务_Consul 命令行最全文档
  5. hosts文件为空白或删除情况修复
  6. linux 下 gtest 的安装
  7. MZB01慢直播-如何循环直播录好的视频文件
  8. kafka学习武林秘籍
  9. html js 鼠标移动图片跟着移动
  10. 百度前端学院--斌斌学院--demo---2