最近的项目有许多图片,决定上传到腾讯云存储桶,由我负责写一个工具包,因为项目的图片都是以base64形势传到后台的,所以采用后台先转为本地图片然后再上传的方式。
1、首先需要新增sdk的依赖

<!-- 腾讯云COS服务sdk -->
		<dependency>
			<groupId>com.qcloud</groupId>
			<artifactId>cos_api</artifactId>
			<version>5.6.54</version>
		</dependency>

2、新建一个工具类CosUtils
主要需要的云存储信息为:

static String accessID = "";//密匙ID
	static String secretKey = "";//密匙
	static String bucketName = ""; //存储桶名称
    static String key = "";//上传路径,这里指的是文件夹/文件名
    static String region = "";//存储桶所属区域区域
    static String appId = ""; //APPID
    static COSCredentials cred = null;//初始化类便于使用
    static COSClient cosClient = null;//客户端

3、图片上传方法
由于我这边是base64转文件之后在上传,所以方法里面只包含了文件名和图片本地地址,需求有区别的老哥自行更改

* 上传图片对接腾讯COS
     *
     * @param fileDataFileName 文件
     * @param key 文件名
     * @param filePath 文件地址
     * @return
     */
    @SuppressWarnings("unused")
	public Map<String, Object> ContentCOS( String key,String filePath) throws IOException {
        Map<String, Object> map = new HashMap<>();
        // 1 初始化用户身份信息(secretId, secretKey)
        COSCredentials cred = new BasicCOSCredentials(accessKey, secretKey);
        // 2 设置bucket的区域, COS地域在上面有提到
        ClientConfig clientConfig = new ClientConfig(new Region(region));
        // 3 生成cos客户端
        COSClient cosclient = new COSClient(cred, clientConfig);
        //根据当前日期选择上传的文件夹
        LocalDate date = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");  
        key = date.format(formatter) + "/" + key;
        String url = null;
        try {
            // 根据路径获取图片
            File localFile = new File(filePath);
            // 报错请求对象
            AppendObjectRequest appendObjectRequest = new AppendObjectRequest(bucketName, key, localFile);
            // 设置节点
            appendObjectRequest.setPosition(0L);
            AppendObjectResult appendObjectResult = cosclient.appendObject(appendObjectRequest);
            // 文件大小
            long nextAppendPosition = appendObjectResult.getNextAppendPosition();
            // 获取返回对象
            GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key);
            COSObject cosObject = cosclient.getObject(getObjectRequest);
            //获取返回地址
            url = cosObject.getObjectContent().getHttpRequest().getURI().toString();
            log.info("图片上传成功地址为"+url );
            map.put("fileUrl", url);
            map.put("flag", "success");
        } catch (CosServiceException e) {
            e.printStackTrace();
        } catch (CosClientException e) {
            e.printStackTrace();
        } finally {
            cosclient.shutdown();
        }
        return map;
    }

4、base64转图片并保存到本地
因为base64流会包含一个头部,根据不同类型需要将头部裁剪掉,代码示例如下:

if(image.startsWith("data:image/jpeg;base64,")) {
	image = image.substring(23, image.length());
}else if(image.startsWith("data:image")) {
	image = image.substring(22, image.length());
}

将前端用户数据加时间戳标识图片名唯一

/**
	 * 保存图片并返回图片地址
	 * @return
	 */
	public Map<String,Object> saveImage(Map<String,Object> m){
		//存储地址信息及文件名
		Map<String,Object> returnMap = new HashMap<String,Object>();
		String name = MapUtils.getString(m, "Name");
		//图片信息保存
		Long startTs = System.currentTimeMillis();//时间戳
		String picture = MapUtils.getString(m, "picture","");//base64
		String fileName = name +"_"+ startTs+".png";//姓名+时间戳
		String url = imageUrl + fileName;//图片生成路径
		if(picture.startsWith("data:image/jpeg;base64,")) {
			picture = picture.substring(23, picture.length());
		}else if(picture.startsWith("data:image")) {
			picture = picture.substring(22, picture.length());
		}
		boolean flag = GenerateImage(picture,url);
		if(flag) {
			returnMap.put("imageurl", url);
			returnMap.put("fileName", fileName);
			log.info("本地图片保存地址:"+url);
		}
		return returnMap;
	}

裁剪过后的base64编码就可以直接转换为图片进行存储了,代码示例如下:

/**
	 * Base64生成图片
	 * @param imgStr  base64码
	 * @param imgFilePath  要生成的文件路径 我这边传的都是绝对路径 例D:\\code\\code\\
	 * @return
	 */
	public boolean GenerateImage(String imgStr, String imgFilePath) {// 对字节数组字符串进行Base64解码并生成图片
		// 图像数据为空
        if (imgStr == null) {
        	return false;
        }
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] bytes = decoder.decodeBuffer(imgStr);
            for (int i = 0; i < bytes.length; ++i) {
                if (bytes[i] < 0) {// 调整异常数据
                    bytes[i] += 256;
                }
            }
            //图片路径生成
            File dir = new File(new File(imgFilePath).getAbsolutePath());
    		if (!dir.getParentFile().exists()) {
    			dir.getParentFile().mkdirs();
    		}
    		// 生成jpeg图片
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(bytes);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
        	e.printStackTrace();
            return false;
        }
    }

5、踩坑,在代码弄完无问题之后上传图片报错,排查为http依赖包版本太老,报错如下:

java.lang.NoSuchMethodError: org.apache.http.impl.conn.PoolingHttpClientConn
java.lang.ClassNotFoundException: org.apache.http.ssl.SSLContexts
java.lang.ClassNotFoundException: org.apache.commons.codec.digest.HmacUtils

修改后依赖版本如下:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
    <version>4.4</version>
</dependency>

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.6</version>
</dependency>

总结:因为也是初版,目前就只写了上传方法,删除是根据key直接删的也没啥好说的,本人也是编程萌新,欢迎大家交流,有问题可以在评论区提出