腾讯对象存储与微信小程序之坑[Java]

腾讯对象存储与微信小程序之坑[Java]

最近写一个小程序,涉及到了文件上传,主要是上传图片。后台是Java+SSM框架,用到了腾讯云COS对象存储,下面详细介绍一下我遇到的各种坑。如有错误,请多指教。

腾讯对象存储

首先Maven工程要导入下面几个包,其中一个是腾讯云存储的官方文档中说明的必须要的包。commons-codec包腾讯的文档中并没有说要导入,但没有的话会报找不到类org.apache.commons.codec.digest…pom文件如下

<!-- 腾讯云 -->
		<dependency>
		     <groupId>com.qcloud</groupId>
		     <artifactId>cos_api</artifactId>
		     <version>5.4.10</version>
		     <exclusions>
		         <exclusion>
		             <groupId>org.slf4j</groupId>
		             <artifactId>slf4j-log4j12</artifactId>
		         </exclusion>
		     </exclusions>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
		<dependency>
		    <groupId>commons-fileupload</groupId>
		    <artifactId>commons-fileupload</artifactId>
		    <version>1.3.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
		<dependency>
		    <groupId>commons-io</groupId>
		    <artifactId>commons-io</artifactId>
		    <version>2.4</version>
		</dependency>
		<dependency>
		    <groupId>commons-codec</groupId>
		    <artifactId>commons-codec</artifactId>
		    <version>1.10</version>
		</dependency>

导入这些包之后,要写一个Util工具

package com.queue.util;

import java.io.InputStream;
import java.util.Random;

import org.springframework.web.multipart.MultipartFile;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;

public class TencentCOS {

	// 存储桶名称
	private static final String bucketName = "queue-1********610";
	// secretId
	private static final String secretId = "AKIDxwnBRi9***************************so9PdQCt";
	//secretKey
	private static final String secretKey = "jspvsjS0SnyW0*************************tq65lK";
	
	// 初始化用户身份
	private static COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
	
	// 设置bucket的区域
	private static ClientConfig clientConfig = new ClientConfig(new Region("ap-beijing"));
	
	public static String uploadfile(MultipartFile file) throws Exception {
		if (file.getSize() > 1024 * 1024) {
			throw new Exception("上传图片大小不能超过1M!");
		}
		// 生成cos客户端
		COSClient cosclient = new COSClient(cred, clientConfig);
		String fileName = null;
//			fileName = localFile.getName();
//			String substring = fileName.substring(fileName.lastIndexOf("."));
		String originalFilename = file.getOriginalFilename();
	    String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
		Random random = new Random();
		try {
			InputStream inputStream = file.getInputStream();
			// 指定要上传到 COS 上的路径
			fileName = "images/"+random.nextInt(10000) + System.currentTimeMillis() + substring;
//			PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, localFile);
			ObjectMetadata metadata = new ObjectMetadata();
			metadata.setContentLength(inputStream.available());
		    metadata.setCacheControl("no-cache");
		    metadata.setHeader("Pragma", "no-cache");
		    metadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
		    metadata.setContentDisposition("inline;filename=" + fileName);
			
			PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, inputStream, metadata);
			
			cosclient.putObject(putObjectRequest);
			
		}catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 关闭客户端(后台线程)
			cosclient.shutdown();
		}
		return fileName;
	}
	
	/**
	   * Description: 判断OSS服务文件上传时文件的contentType
	   *
	   * @param FilenameExtension 文件后缀
	   * @return String
	   */
	  public static String getcontentType(String FilenameExtension) {
	    if (FilenameExtension.equalsIgnoreCase(".bmp")) {
	      return "image/bmp";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".gif")) {
	      return "image/gif";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
	        FilenameExtension.equalsIgnoreCase(".jpg") ||
	        FilenameExtension.equalsIgnoreCase(".png")) {
	      return "image/jpeg";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".html")) {
	      return "text/html";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".txt")) {
	      return "text/plain";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".vsd")) {
	      return "application/vnd.visio";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".pptx") ||
	        FilenameExtension.equalsIgnoreCase(".ppt")) {
	      return "application/vnd.ms-powerpoint";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".docx") ||
	        FilenameExtension.equalsIgnoreCase(".doc")) {
	      return "application/msword";
	    }
	    if (FilenameExtension.equalsIgnoreCase(".xml")) {
	      return "text/xml";
	    }
	    return "image/jpeg";
	  }
	
}



有这个工具类之后上传文件就很方便了,工具类中生成cos客户端在文件上传失败时自动重复上传5次,如果5次都失败了就会报错。
由于我的项目前端是微信小程序,微信小程序传给后台的文件类型是MultipartFile,为了使用方便在工具类中对MultipartFile做了一些操作。主要思路是:

  1. 提取文件名字+随机数(防重)
  2. getInputStream() 获取文件输入流
  3. 获取文件其他信息,metadata

如果您上传的文件是File类型而不是MultipartFile,您可以自己对上边工具类进行一些修改,或去看看其他帖子。

有了以上工具类,在上传文件时就可以这样做:

String suburl = TencentCOS.uploadfile(multfile);

具体后台代码如下:

Controller层

@Controller
@RequestMapping("/img")
public class ImgController {

	@Autowired
	private IImgService imgService;

	/**
	 * 创建队列
	 * @param leaderopenid
	 * @param leaderwxname
	 * @param quename
	 * @param state
	 * @param introduce
	 * @param file
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/upload")
	public @ResponseBody int doUpload(String leaderopenid, String leaderwxname, String quename, String state,String introduce, String location, @RequestParam(value = "file", required = false) MultipartFile file)
			throws Exception {
		return imgService.creatQue(leaderopenid, leaderwxname, quename, state, introduce, location, file);

	}

service层

@Override
	public int creatQue(String leaderopenid, String leaderwxname, String quename, String state, String introduce, String location,
			MultipartFile multfile) throws Exception {
			String url = "";
		if(multfile!=null) {
			String suburl = TencentCOS.uploadfile(multfile);
			if (suburl.isEmpty()) return 0;
			url = "https://queue-1258186610.cos.ap-beijing.myqcloud.com/" + suburl;
			System.out.println(url);
		}
	 	// 这里是一些其他逻辑...

微信小程序部分

选择图片

 /**
   * 从相册选择图片添加
   */
  ChooseImage() {
    wx.chooseImage({
      count: 1, //默认9
      sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], //从相册选择
      success: (res) => {
        console.log(res)
        if (this.data.imgList.length != 0) {
          this.setData({
            imgList: this.data.imgList.concat(res.tempFilePaths)
          })
        } else {
          this.setData({
            imgList: res.tempFilePaths
          })
        }
        var filep = res.tempFilePaths[0]
        this.setData({
          filep: filep
        })
      }
    });
  },
  /**
   * 点击图片查看
   */
  ViewImage(e) {
    wx.previewImage({
      urls: this.data.imgList,
      current: e.currentTarget.dataset.url
    });
  },
  /**
   * 删除图片
   */
  DelImg(e) {
    wx.showModal({
      title: '删除图片',
      content: '确定要删除这张图片吗?',
      cancelText: '取消',
      confirmText: '删除',
      success: res => {
        if (res.confirm) {
          this.data.imgList.splice(e.currentTarget.dataset.index, 1);
          this.setData({
            imgList: this.data.imgList
          })
        }
      }
    })
  },

上传图片

 wx.uploadFile({
      url: 'https://www.paion.xyz/queue/img/upload',
      filePath: this.data.filep,
      name: 'file',
      formData: {
        'leaderopenid': openid,
        'leaderwxname': e.detail.value.leaderwxname,
        'quename': e.detail.value.quename,
        'state': "1",
        'introduce': e.detail.value.introduce,
        'location': app.globalData.LocationInfo
      },
      success: function (res) {
        console.log(res) 
        if (res.data==0) {
          wx.showToast({
            title: '创建失败!',
            icon: 'none'
          })
        }else {
          wx.showToast({
            title: '创建成功!',
            duration: 1000
          })
          wx.navigateTo({
            url: '/pages/passUser/passUser',
          })
        }
      },
      fail: function (res) {
        wx.showToast({
          title: '创建失败!',
          icon: 'none'
        })
      }
    })

如有不足欢迎吐槽。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值