首页 > 其他分享 >整合华为云OBS上传工具类

整合华为云OBS上传工具类

时间:2024-10-19 09:42:43浏览次数:1  
标签:return String objectName param public 华为 bucketName 上传 OBS

项目启动的要加上配置文件的扫描路径

import com.example.config.ObsProperties;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@MapperScan("com.example.dao")
@SpringBootApplication
@EnableConfigurationProperties({ObsProperties.class})
public class DemoApplication {

    public static void main(String[] args) {
        System.out.println("----------服务开始启动----------");
        SpringApplication.run(VirtualNumberApplication.class, args);
        System.out.println("-----------服务启动成功----------");
    }

}

 

 

ObsProperties

在项目启动的时候初始化HuaWeiOBSUtil类

import com.example.utils.HuaWeiOBSUtil;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * @description: 华为云OBS配置信息
 */
@ConfigurationProperties(prefix = "obs")
public class ObsProperties {
    private String domainName;
    private String bucketName;
    private String accessKeyId;
    private String accessKeySecret;
    private String endPoint;
    private String privateFile;

    public String getDomainName() {
        return domainName;
    }

    public void setDomainName(String domainName) {
        this.domainName = domainName;
    }

    public String getBucketName() {
        return bucketName;
    }

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

    public String getAccessKeyId() {
        return accessKeyId;
    }

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

    public String getAccessKeySecret() {
        return accessKeySecret;
    }

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

    public String getEndPoint() {
        return endPoint;
    }

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

    public String getPrivateFile() {
        return privateFile;
    }

    public void setPrivateFile(String privateFile) {
        this.privateFile = privateFile;
    }

    @Bean
    public HuaWeiOBSUtil huaWeiOBSUtil() {
        return new HuaWeiOBSUtil(bucketName, accessKeyId, accessKeySecret, endPoint, privateFile);
    }
}

 

 

 

HuaWeiOBSUtil

package com.example.utils;

import com.exampleenums.IntegerValueEnum;
import com.example.enums.StringEnum;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.*;
import io.micrometer.common.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @description: 华为云OBS工具类
 */
public class HuaWeiOBSUtil {
    /*** 文件外链过期时间,7天 */
    private static long expire = 7 * 24 * 60 * 60;
    /*** 文件外链访问端口 */
    private static String port = ":443";
    private static String bucketName;
    private static String ak;
    private static String sk;
    private static String endPoint;
    private static String privateFile;
    /*** OBS操作客户端 */
    private static ObsClient obsClient = null;
    private static final String SEPARATOR = StringEnum.STRING_RIGHT_SLASH.getValue();
    private static Logger log = LoggerFactory.getLogger(HuaWeiOBSUtil.class);

    public HuaWeiOBSUtil(String bucketName, String ak, String sk, String endPoint, String privateFile) {
        HuaWeiOBSUtil.bucketName = bucketName;
        HuaWeiOBSUtil.ak = ak;
        HuaWeiOBSUtil.sk = sk;
        HuaWeiOBSUtil.endPoint = endPoint;
        HuaWeiOBSUtil.privateFile = privateFile;
        createObsClientInstance();
    }

    public static String getBucketName() {
        return bucketName;
    }

    public static String getAk() {
        return ak;
    }

    public static String getSk() {
        return sk;
    }

    public static String getEndPoint() {
        return endPoint;
    }

    /**
     * 获取OBS操作客户端
     */
    private static void createObsClientInstance() {
        synchronized (ObsClient.class) {
            try {
                if (obsClient == null) {
                    obsClient = new ObsClient(ak, sk, endPoint);
                }
                createBucket(bucketName, endPoint);
            } catch (Exception e) {
                log.error("连接华为云存储服务器异常:" + e.getMessage(), e);
            }
        }
    }

    /**
     * 创建存储桶
     *
     * @param bucketName
     * @param endPoint
     */
    public static void createBucket(String bucketName, String endPoint) {
        try {
            if (!headBucket(bucketName)) {
                CreateBucketRequest request = new CreateBucketRequest();
                // 设置存储桶名称
                request.setBucketName(bucketName);
                // 设置桶区域位置,从endPoint中截取,如果Location设置的区域与endPoint中的区域不是同一个,则创建会报错
                request.setLocation(getRegion(endPoint));
                // 设置桶访问权限为公共读,默认是私有读写
                request.setAcl(AccessControlList.REST_CANNED_PUBLIC_READ);
                // 创建桶成功
                ObsBucket bucket = obsClient.createBucket(request);
                log.info("创建桶成功,返回RequestId:{}", bucket.getRequestId());
            }
        } catch (ObsException e) {
            // 创建桶失败
            log.error("HTTP Code: {}", e.getResponseCode());
            log.error("Error Code: {}", e.getErrorCode());
            log.error("Error Message: {}", e.getErrorMessage());
            log.error("Request ID: {}", e.getErrorRequestId());
            log.error("Host ID: {}", e.getErrorHostId());
        }

    }

    public AccessControlList getObjectAcl(String objectName) {
        AccessControlList objectAcl = obsClient.getObjectAcl(bucketName, objectName);
        return objectAcl;
    }

    /**
     * 获取上传文件的基础路径
     *
     * @return
     */
    public static String getBasisUrl() {
        // 实示例:http协议 + 存储桶名称 + . + endPoint + port + /
        return getHttpProtocol(endPoint)
                + StringEnum.STRING_TWO_RIGHT_SLASH.getValue() + bucketName + StringEnum.STRING_POINT.getValue() + endPoint
                .replace(getHttpProtocol(endPoint) + StringEnum.STRING_TWO_RIGHT_SLASH.getValue(), StringEnum.STRING_EMPTY.getValue())
                + port + SEPARATOR;
    }

    /**
     * 获取上传文件的基础路径
     *
     * @param bucketName
     * @return
     */
    public static String getBasisUrl(String bucketName) {
        // 实示例:http协议 + 存储桶名称 + . + endPoint + port + /
        return getHttpProtocol(endPoint)
                + StringEnum.STRING_TWO_RIGHT_SLASH.getValue() + bucketName + StringEnum.STRING_POINT.getValue() + endPoint
                .replace(getHttpProtocol(endPoint) + StringEnum.STRING_TWO_RIGHT_SLASH.getValue(), StringEnum.STRING_EMPTY.getValue())
                + port + SEPARATOR;
    }

    /**
     * 获取区域
     *
     * @param endPoint
     * @return
     */
    public static String getRegion(String endPoint) {
        String substring = endPoint.substring(endPoint.indexOf(StringEnum.STRING_POINT.getValue()) + IntegerValueEnum.ONE.getValue());
        return substring.substring(IntegerValueEnum.ZERO.getValue(), substring.indexOf(StringEnum.STRING_POINT.getValue()));
    }

    /**
     * 获取http协议
     *
     * @param endPoint
     * @return
     */
    public static String getHttpProtocol(String endPoint) {
        return endPoint.substring(IntegerValueEnum.ZERO.getValue(), endPoint.indexOf(StringEnum.STRING_COLON.getValue()));
    }

    /***
     * 删除存储桶** @param bucketName*
     *
     * @return
     */
    public static HeaderResponse deleteBucket(String bucketName) {
        return obsClient.deleteBucket(bucketName);
    }

    /***
     * 判断存储桶是否存在** @param bucketName*
     *
     * @return
     */
    public static boolean headBucket(String bucketName) {
        return obsClient.headBucket(bucketName);
    }

    /**
     * 上传字符
     *
     * @param bucketName
     * @param objectName
     * @param content
     * @return
     */
    public static PutObjectResult putObjectByStr(String bucketName, String objectName, String content) {
        if (StringUtils.isBlank(content)) {
            return null;
        }
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        return obsClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()));
    }

    /**
     * 上传byte
     *
     * @param bucketName
     * @param objectName
     * @param content
     * @return
     */
    public static PutObjectResult putObjectByByte(String bucketName, String objectName, byte[] content, String fileName) {
        return putObjectByInput(bucketName, objectName, new ByteArrayInputStream(content), fileName);
    }

    /**
     * 上传byte
     *
     * @param bucketName
     * @param objectName
     * @param content
     * @return
     */
    public static PutObjectResult putPrivateObjectByByte(String bucketName, String objectName, byte[] content, String fileName) {
        return putObjectByInput(bucketName, objectName, new ByteArrayInputStream(content), fileName);
    }

    /**
     * 上传输入流
     *
     * @param bucketName
     * @param objectName
     * @param inputStream
     * @return
     */
    public static PutObjectResult putObjectByInput(String bucketName, String objectName, InputStream inputStream,
                                                   String fileName) {
        String acl = "private";
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        PutObjectRequest putObjectRequest = setObjectMetadata(bucketName, objectName, fileName, acl);
        putObjectRequest.setInput(inputStream);
        return obsClient.putObject(putObjectRequest);
    }

    /**
     * 上传文件输入流
     *
     * @param bucketName
     * @param objectName
     * @param fileInputStream
     * @return
     */
    public static PutObjectResult putObjectByFileInput(String bucketName, String objectName,
                                                       FileInputStream fileInputStream) {
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        return obsClient.putObject(bucketName, objectName, fileInputStream);
    }

    /**
     * 通过MultipartFile,上传文件
     *
     * @param bucketName
     * @param objectName
     * @param media
     * @return
     * @throws IOException
     */
    public static PutObjectResult putObjectByMultipartFile(String bucketName, String objectName, MultipartFile media)
            throws IOException {
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        return obsClient.putObject(bucketName, objectName, media.getInputStream());
    }

    /**
     * 上传本地文件
     *
     * @param bucketName
     * @param objectName 上传保存的路径
     * @param file
     * @return
     */
    public static PutObjectResult putObjectByFile(String bucketName, String objectName, File file, String acl) {
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        PutObjectRequest putObjectRequest = setObjectMetadata(bucketName, objectName, file.getName(), acl);
        putObjectRequest.setFile(file);
        return obsClient.putObject(putObjectRequest);
    }

    /**
     * 下载文件到本地
     *
     * @param bucketName
     * @param objectName
     * @param filePath
     * @return
     * @throws Exception
     */
    public static boolean downloadObject(String bucketName, String objectName, String filePath) throws Exception {
        if (StringUtils.isBlank(filePath)) {
            return false;
        }
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        filePath = filePath.replace("\\", SEPARATOR);
        InputStream input = null;
        FileOutputStream fileOutputStream = null;
        try {
            // 获取对象
            ObsObject obsObject = obsClient.getObject(bucketName, objectName);
            // 读取对象内容
            input = obsObject.getObjectContent();
            if (input == null) {
                return false;
            }
            // 获取文件夹路径
            if (filePath.contains(SEPARATOR)) {
                String dir = filePath.substring(IntegerValueEnum.ZERO.getValue(), filePath.lastIndexOf(SEPARATOR));
                File difFile = new File(dir);
                if (!difFile.exists()) {
                    // 创建文件夹
                    boolean mkdirs = difFile.mkdirs();
                }
            }
            File file = new File(filePath);
            fileOutputStream = new FileOutputStream(file);
            byte[] b = new byte[1024];
            int len;
            while ((len = input.read(b)) != IntegerValueEnum.NEGATIVE_ONE.getValue()) {
                fileOutputStream.write(b, IntegerValueEnum.ZERO.getValue(), len);
            }
            return true;
        } finally {
            if (fileOutputStream != null) {
                fileOutputStream.close();
            }
            if (input != null) {
                input.close();
            }
        }
    }

    /**
     * 获取文件内容
     *
     * @param bucketName
     * @param objectName
     * @return
     * @throws IOException
     */
    public static String getObjectContent(String bucketName, String objectName) throws IOException {
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        InputStream input = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            ObsObject obsObject = obsClient.getObject(bucketName, objectName);
            // 读取对象内容
            input = obsObject.getObjectContent();
            byte[] b = new byte[1024];
            int len;
            while ((len = input.read(b)) != IntegerValueEnum.NEGATIVE_ONE.getValue()) {
                bos.write(b, IntegerValueEnum.ZERO.getValue(), len);
            }
            return new String(bos.toByteArray());
        } finally {
            bos.close();
            if (input != null) {
                input.close();
            }
        }
    }

    /**
     * 获取文件输入流
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    public static InputStream getObject(String bucketName, String objectName) {
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        return obsClient.getObject(bucketName, objectName).getObjectContent();
    }

    /**
     * 指定数目和前缀列举
     *
     * @param bucketName
     * @param prefix
     * @param maxKeys
     * @return
     */
    public static List<ObsObject> listObjects(String bucketName, String prefix, Integer maxKeys) {
        prefix = prefix.startsWith(StringEnum.STRING_RIGHT_SLASH.getValue()) ? prefix.substring(IntegerValueEnum.ONE.getValue()) : prefix;
        ListObjectsRequest request = new ListObjectsRequest(bucketName);
        // 设置列举的对象个数
        request.setMaxKeys(maxKeys);
        // 设置列举的对象需要带有指定前缀
        request.setPrefix(prefix);
        ObjectListing result = obsClient.listObjects(request);
        return result.getObjects();
    }

    /**
     * 列举指定前缀的全部对象
     *
     * @param bucketName
     * @param prefix
     * @return
     */
    public static List<ObsObject> listAllObjects(String bucketName, String prefix) {
        prefix = prefix.startsWith(StringEnum.STRING_RIGHT_SLASH.getValue()) ? prefix.substring(IntegerValueEnum.ONE.getValue()) : prefix;
        List<ObsObject> list = new ArrayList<>();
        ListObjectsRequest request = new ListObjectsRequest(bucketName);
        // 设置列举的对象个数
        request.setMaxKeys(1000);
        // 设置列举的对象需要带有指定前缀
        request.setPrefix(prefix);
        ObjectListing result;
        do {
            result = obsClient.listObjects(request);
            request.setMarker(result.getNextMarker());
            list.addAll(result.getObjects());
        } while (result.isTruncated());
        return list;
    }

    /**
     * 删除单个对象
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    public static DeleteObjectResult deleteObject(String bucketName, String objectName) {
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        return obsClient.deleteObject(bucketName, objectName);
    }

    /**
     * 复制对象
     *
     * @param sourceBucketName
     * @param sourceObjectName
     * @param destBucketName
     * @param destObjectName
     * @return
     */
    public static CopyObjectResult copyObject(String sourceBucketName, String sourceObjectName, String destBucketName,
                                              String destObjectName) {
        return obsClient.copyObject(sourceBucketName, sourceObjectName, destBucketName, destObjectName);
    }

    /**
     * 复制对象
     *
     * @param sourceBucketName
     * @param sourceObjectName
     * @param destBucketName
     * @param destObjectName
     * @return
     */
    public static CopyObjectResult copyObject1(String sourceBucketName, String sourceObjectName, String destBucketName,
                                               String destObjectName) {
        // 重新构建objectName
        sourceObjectName = buildObjectName(sourceObjectName);
        destObjectName = buildObjectName(destObjectName);
        return obsClient.copyObject(sourceBucketName, sourceObjectName, destBucketName, destObjectName);
    }

    /**
     * 判断对象是否存在
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    public static boolean doesObjectExist(String bucketName, String objectName) {
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        return obsClient.doesObjectExist(bucketName, objectName);
    }

    /**
     * 获取文件外链
     *
     * @param bucketName
     * @param objectName
     * @param expires    大于等于0的整型数,单位:秒
     * @return
     */
    public static String getSignedUrl(String bucketName, String objectName, Long expires) {
        // 重新构建objectName
        objectName = buildObjectName(objectName);
        TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expires);
        request.setBucketName(bucketName);
        request.setObjectKey(objectName);
        TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
        return response.getSignedUrl();
    }

    /**
     * 获取文件外链-url有效时间默认7天
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    public static String getSignedUrl(String bucketName, String objectName) {
        return getSignedUrl(bucketName, objectName, expire);
    }

    /**
     * 重新构建objectName
     *
     * @param objectName
     * @return
     */
    private static String buildObjectName(String objectName) {
        if (StringUtils.isBlank(objectName)) {
            return objectName;
        }
        // 去除开头的/
        objectName = objectName.startsWith(StringEnum.STRING_RIGHT_SLASH.getValue()) ? objectName.substring(IntegerValueEnum.ONE.getValue())
                : objectName;
        // 去除?后边的参数
        objectName = objectName.contains(StringEnum.STRING_QUESTION.getValue())
                ? objectName.substring(IntegerValueEnum.ZERO.getValue(), objectName.indexOf(StringEnum.STRING_QUESTION.getValue())) : objectName;
        return objectName;
    }

    /**
     * 传入文件访问外链,返回objectName
     *
     * @param url
     * @return
     */
    public static String getObjectNameByUrl(String url) {
        if (StringUtils.isBlank(url)) {
            return url;
        }
        if (url.contains(getBasisUrl())) {
            // 去除minio基础路径
            url = url.replace(getBasisUrl(), StringEnum.STRING_EMPTY.getValue());
            // 去除?后边的参数
            url = url.contains(StringEnum.STRING_QUESTION.getValue())
                    ? url.substring(IntegerValueEnum.ZERO.getValue(), url.indexOf(StringEnum.STRING_QUESTION.getValue())) : url;
        }
        return url;
    }

    public static String getContentType(String fileName) {
        // 文件的后缀名
        if (fileName.lastIndexOf(StringEnum.STRING_POINT.getValue()) < IntegerValueEnum.ZERO.getValue()) {
            // 默认返回类型
            return StringEnum.STRING_EMPTY.getValue();
        }
        String fileExtension = fileName.substring(fileName.lastIndexOf(StringEnum.STRING_POINT.getValue()));
        if (".bmp".equalsIgnoreCase(fileExtension)) {
            return "image/bmp";
        }
        if (".gif".equalsIgnoreCase(fileExtension)) {
            return "image/gif";
        }
        if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension)
                || ".png".equalsIgnoreCase(fileExtension)) {
            return "image/jpeg";
        }
        if (".png".equalsIgnoreCase(fileExtension)) {
            return "image/png";
        }
        if (".html".equalsIgnoreCase(fileExtension)) {
            return "text/html";
        }
        if (".txt".equalsIgnoreCase(fileExtension)) {
            return "text/plain";
        }
        if (".vsd".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.visio";
        }
        if (".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if (".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
            return "application/msword";
        }
        if (".xml".equalsIgnoreCase(fileExtension)) {
            return "text/xml";
        }
        // 默认返回类型
        return StringEnum.STRING_EMPTY.getValue();
    }

    /**
     * 获取文件路径
     *
     * @param profiles
     * @param fileName
     * @return
     */
    public static String getFilePath(String profiles, String fileName) {
        String acl = "private";
        // 获取文件后缀
        String suffix = fileName.substring(fileName.lastIndexOf(StringEnum.STRING_POINT.getValue()));
        // 按时间生产一个目录
        String date = DateUtils.dateToString(new Date(), "yyyyMMdd");
        StringBuffer buffer = new StringBuffer();
        if (StringUtils.isNotEmpty(acl) && AccessControlList.REST_CANNED_PRIVATE.equals(convertAcl(acl))) {
            buffer.append(privateFile);
        }
        buffer.append(profiles).append(StringEnum.STRING_RIGHT_SLASH.getValue()).append(date)
                .append(StringEnum.STRING_RIGHT_SLASH.getValue());
        buffer.append(UUID.randomUUID().toString().replace(StringEnum.STRING_MINUS.getValue(), StringEnum.STRING_EMPTY.getValue()))
                .append(suffix);
        return buffer.toString();
    }

    /**
     * 获取文件访问地址
     *
     * @param acl
     * @param filePath
     * @return
     */
    public static String getFileUrl(String filePath, Long expires) {
        filePath = getSignedUrl(bucketName, filePath, expires);
        return filePath;
    }

    /**
     * 设置上传对象属性权限
     *
     * @param fileName
     * @param acl
     * @return
     */
    public static PutObjectRequest setObjectMetadata(String bucketName, String objectName, String fileName,
                                                     String acl) {
        PutObjectRequest request = new PutObjectRequest();
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(getContentType(fileName));
        request.setMetadata(metadata);
        // 设置文件访问权限 这里是私有
        if (StringUtils.isNotEmpty(acl) && AccessControlList.REST_CANNED_PRIVATE.equals(convertAcl(acl))) {
            request.setAcl(AccessControlList.REST_CANNED_PRIVATE);
        }
        request.setBucketName(bucketName);
        request.setObjectKey(objectName);
        return request;
    }

    /**
     * 转换字符串权限
     *
     * @param acl
     * @return
     */
    public static AccessControlList convertAcl(String acl) {
        AccessControlList aclObj;
        switch (acl) {
            case "private":
                aclObj = AccessControlList.REST_CANNED_PRIVATE;
                break;
            case "read_write":
                aclObj = AccessControlList.REST_CANNED_PUBLIC_READ_WRITE;
                break;
            default:
                aclObj = AccessControlList.REST_CANNED_PUBLIC_READ;
        }
        return aclObj;
    }
}

 

标签:return,String,objectName,param,public,华为,bucketName,上传,OBS
From: https://www.cnblogs.com/dawenyang/p/18475511

相关文章

  • Unity 华为快游戏JS桥接 实现写日志等功能
    之前接入微信小游戏本身代码js桥接比较完善,抖音小游戏有缺少但也没缺的这么多,华为这边的API,大残啊!官方转换插件Github仓库上一次提交在3月份。(截至现在)API给的很简略,接入js代码那里说看demo,但unity的demo里面没jslib,另一个比较完善的demo看起来像是cocos的,比较无奈。还好用unity......
  • 苹果(ios)应用ipa文件上传到苹果商店app store步骤
    这篇文章的前提是你已经用苹果打包证书打包好ipa文件,准备将ipa文件上传到appstore。假如你还没有苹果证书,还没有打包好ipa文件,你还不知道证书怎么创建,可以参考这篇文章先生成证书和证书profile文件:https://www.cnblogs.com/handsome0916/p/18329211然后你到iosdevcenter,也......
  • Vue3 - 详细实现移动端H5网页调用摄像头拍照功能,微信公众号网页h5页面打开本地摄像头
    前言PC网站端,请访问这篇文章。在vue3手机移动端开发中,详解H5页面/微信公众号网页调用浏览器摄像头并拍照完整示例,在手机浏览器上开启摄像头并拍照上传服务器或保存到本地功能(实时预览使用图片临时路径或base64数据),切换转换前置摄像头与后置摄像头,vue3手机H5打开摄像......
  • nginx+lua实现文件上传功能
    需要用到nginx实现文件上传,刚好手里面的版本支持lua,下面是完整实现:首先是nginx的配置如下:注意$home_path设置的是上传文件的保存目录location/uploadFile{set$home_path"/root/up2";content_by_lua_fileconf/upfile.lua;}接着在web根目录放入Html文件,命......
  • 连接人与艺术 华为平板从生产力到创作力的跃迁
    以“共绘自然”为主题的2024天生会画数字创作大赛,正在如火如荼地进行。华为平板正在吸引全球越来越多的用户拿起画笔,通过数字绘画捕捉、创作世界独特的美。以前,提到专业创作力大家往往想到的只有苹果的Procreate,而今天华为平板在创作方面的能力已经被众多专业人士认可,在很多专业......
  • 【2024华为OD-E卷-100分-内存资源分配】(题目+思路+Java&C++&Python解析+在线测试)
    在线评测链接题目描述有一个简易内存池,内存按照大小粒度分类,每个粒度有若干个可用内存资源,用户会进行一系列内存申请,需要按需分配内存池中的资源返回申请结果成功失败列表。分配规则如下:分配的内存要大于等于内存的申请量,存在满足需求的内存就必须分配,优先分配粒度小的......
  • DAY53WEB 攻防-XSS 跨站&SVG&PDF&Flash&MXSS&UXSS&配合上传&文件添加脚本
    知识点:1、XSS跨站-MXSS&UXSS2、XSS跨站-SVG制作&配合上传3、XSS跨站-PDF制作&配合上传4、XSS跨站-SWF制作&反编译&上传XSS分类:https://www.fooying.com/the-art-of-xss-1-introduction/(失效了)MXSS现在基本上见不到UXSS:UniversalCross-SiteScripting针对浏览器的漏......
  • 解析华为鸿蒙next:Web组件自适应布局与渲染模式详解
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。Web组件大小自适应页面内容布局使用......
  • 全方位探索华为鸿蒙ArkWeb:构建高性能跨平台新闻阅读应用
    本文旨在深入探讨华为鸿蒙HarmonyOSNext系统(截止目前API12)的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。一、引言:ArkWeb的优势与跨平台应用的......
  • 强大灵活的文件上传库:FilePond 详解hD
    文件上传是Web开发中常见的功能,尤其是对于图片、视频、文档等大文件的处理,如何既保证用户体验,又兼顾安全和性能,是每位开发者关心的问题。在这样的背景下,FilePond作为一款灵活强大的文件上传库,逐渐在前端开发者中脱颖而出。FilePond提供了优雅的用户界面和全面的功能,同时兼容多......