Spring Boot项目OSS整合

摘要: 主要是PC项目前端上传需要从服务端拿到OSS认证才能上传、后端直接调用OSSClient上传就行。

Ali OSS前端获取签名上传文件

文件上传流程比较复杂的服务器设置回调功能。整个流程图是这样的
Spring Boot项目OSS整合_第1张图片
可以参考阿里api文档介绍的工作流程说明:https://help.aliyun.com/document_detail/31927.html?spm=5176.doc31988.6.633.OTY557
废话不多说可以参考代码:

# OSS \u914D\u7F6E
oss.endpoint = oss-cn-shanghai.aliyuncs.com //上传节点
oss.accessKeyId = LTAIETtq2nU2PNbA//唯一标识
oss.accessKeySecret = 0FwnHo8Hj9ti9C5p7Sg9hYnqn553BO//密钥
oss.bucketName = ## //文件存储目录名
oss.expireTime = 3600 //

OssClient单例工厂

/**
 * ClassName: OssClientFactory 
* Function: OssClient单例工厂
* date: 2017/11/9 11:14
* * @author lijc * @version 1.0.0 * @since JDK 1.8 */
@Component public class OssClientFactory { private volatile static OSSClient client; private static String endpoint; private static String accessKeyId; private static String accessKeySecret; public static OSSClient getOSSClient(){ if (client == null) { synchronized (OssClientFactory.class){ if (client == null) { client = new OSSClient(endpoint, accessKeyId, accessKeySecret); } } } return client; } @Value("${oss.endpoint}") public void setEndpoint(String endpoint) { this.endpoint = endpoint; } @Value("${oss.accessKeyId}") public void setAccessKeyId(String accessKeyId) { this.accessKeyId = accessKeyId; } @Value("${oss.accessKeySecret}") public void setAccessKeySecret(String accessKeySecret) { this.accessKeySecret = accessKeySecret; } }

与前端进行交互接口功能主要有、OSS签名授权、删除图片、创建oss bucket
接口:

ublic class OssController {

    @Resource
    private OssService ossService;

    /**
     * OSS签名授权
     */
    @ApiOperation(value = "OSS签名授权", notes = "OSS签名授权", produces = "application/json")
    @RequestMapping(value = "/authorize", method = RequestMethod.POST)
    public ReturnData authorize(@Valid OssAuthorizeParam ossAuthorizeParam, BindingResult result) {
        return ossService.authorize(ossAuthorizeParam.getDir());
    }


    /**
     * 删除图片
     */
    @ApiOperation(value = "删除OSS图片", notes = "删除OSS图片", produces = "application/json")
    @RequestMapping(value = "/remove", method = RequestMethod.POST)
    public ReturnData remove(@Valid OssRemoveParam ossRemoveParam, BindingResult result) {
        return ossService.remove(ossRemoveParam.getKey());
    }

    /**
     * 创建oss bucket
     */
    @ApiOperation(value = "创建oss bucket", notes = "创建oss bucket", produces = "application/json")
    @RequestMapping(value = "/createBucketName", method = RequestMethod.POST)
    public ReturnData createBucketName(@Valid OssBucketNameParam ossBucketNameParam, BindingResult result) {
        return ossService.createBucketName(ossBucketNameParam.getBucketName());
    }


}

参数:

/**
*授权接口参数
*/
@Getter
@Setter
@ToString
public class OssAuthorizeParam implements Param {

    @ApiModelProperty(value = "目录", required = true)
    @NotEmpty(message = "目录不能为空")
    private String dir;

}
/**
*授权接口返回值
*/
@Getter
@Setter
public class OssAuthorizeData implements Serializable{

    private static final long serialVersionUID = -6646242394834700700L;

    private String accessId;

    private String policy;

    private String signature;

    private String dir;

    private String host;

    private String expire;

}
/**
*删除文件参数
*/
@Getter
@Setter
@ToString
public class OssRemoveParam implements Param {

    @ApiModelProperty(value = "key", required = true)
    @NotEmpty(message = "key不能为空")
    private String key;

}
/**
*相关接口
*/

public interface OssService {

    ReturnData authorize(String dir);

    ReturnData remove(String objectName);

    ReturnData createBucketName(String bucketName);
}
/**
*接口实现
*/
@Slf4j
@Service
public class OssServiceImpl implements OssService {

    @Value("${oss.endpoint}")
    private String endpoint;

    @Value("${oss.accessKeyId}")
    private String accessKeyId;

    @Value("${oss.accessKeySecret}")
    private String accessKeySecret;

    @Value("${oss.bucketName}")
    private String bucketName;

    @Value("${oss.expireTime}")
    private Long expireTime;

    @Override
    public ReturnData authorize(String dir) {
        try {
            String host = "http://" + bucketName + "." + endpoint;
            OSSClient client = OssClientFactory.getOSSClient();

            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            String postPolicy = client.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = client.calculatePostSignature(postPolicy);

            OssAuthorizeData ossAuthorizeData = new OssAuthorizeData();
            ossAuthorizeData.setAccessId(accessKeyId);
            ossAuthorizeData.setDir(dir);
            ossAuthorizeData.setExpire(String.valueOf(expireEndTime / 1000));
            ossAuthorizeData.setHost(host);
            ossAuthorizeData.setPolicy(encodedPolicy);
            ossAuthorizeData.setSignature(postSignature);
            return XgReturnUtil.success(ossAuthorizeData);
        }catch(Exception e){
            log.warn("OSS authorize error",e);
            return XgReturnUtil.fail(ReturnCode.SERVER_EXCEPTION);
        }
    }

    @Override
    public ReturnData remove(String objectName) {
        try {
            OSSClient client = OssClientFactory.getOSSClient();
            client.deleteObject(bucketName,objectName);
            return XgReturnUtil.success();
        }catch(Exception e){
            log.warn("OSS authorize error",e);
            return XgReturnUtil.fail(ReturnCode.SERVER_EXCEPTION);
        }
    }

    @Override
    public ReturnData createBucketName(String bucketName) {
        try {
            OSSClient client = OssClientFactory.getOSSClient();
            boolean ifExist = client.doesBucketExist(bucketName);
            if(!ifExist)
                client.createBucket(bucketName);
            return XgReturnUtil.success();
        }catch(Exception e){
            log.warn("OSS createBucketName error",e);
            return XgReturnUtil.fail(ReturnCode.SERVER_EXCEPTION);
        }
    }

}

例子:完成图片上传(单个批量)、批量删除、图片搜素功能。


"1.0" encoding="UTF-8"?>
"-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
"com.xinguang.ftcs.common.mapper.OssImageMapper">

    "add" parameterType="OssImage">
        INSERT INTO t_oss_image
        "(" suffix =")" suffixOverrides=",">
            <if test="reference_id != null">referenceId,if>
            <if test="imageType != null">image_type,if>
            <if test="purpose != null">purpose,if>
            <if test="objectName != null">object_name,if>
            <if test="createTime != null">create_time,if>
        
        "VALUES (" suffix=")" suffixOverrides=",">
            <if test="referenceId != null">#{referenceId},if>
            <if test="imageType != null">#{imageType},if>
            <if test="purpose != null">#{purpose},if>
            <if test="objectName != null">#{objectName},if>
            <if test="createTime != null">#{createTime},if>
        
    

    
    "batchAdd" parameterType="java.util.List">
        insert into t_oss_image
        (
            reference_id,
            image_type,
            purpose,
            object_name,
            create_time
        )
        values
        "list" item="item" index="index" separator="," >
            (#{item.referenceId},#{item.imageType},#{item.purpose},#{item.objectName},#{item.createTime})
        
    

    "batchDelete" parameterType="java.util.List">
        update
            t_oss_image
        set
            del_flag = '1'
        where
            id in
            "list" item="id" open="(" separator="," close=")">
                #{id}
            
    

    

    


//对应Mapper文件
@Mapper
public interface OssImageMapper {

    /** 新增OSS图片 */
    void add(OssImage ossImage);

    /** 新增OSS图片列表 */
    void batchAdd(List ossImageList);

    /** 删除OSS图片列表 */
    void batchDelete(List ids);

    /** 查询OSS图片 */
    List searchOssImageList(OssImageSearchParam param);

    /** 通过主键Ids获取集合 */
    List getByIds(List ids);

    /** 删除OSS图片 (真删) */
    @Delete("DELETE FROM t_oss_image WHERE id=#{id}")
    void delete(@Param("id") String id);

}
/**
*OSSImageService实现
*/
@Slf4j
@Service
public class OssImageService {

    @Resource
    private OssImageMapper ossImageMapper;

    @Value("${oss.bucketName}")
    private String bucketName;

    @Value("${oss.expireTime}")
    private Long expireTime;

    /**
     * 新增单个图片
     * @param param
     * @param referenceId
     * @param imageType
     */
    public void add(OssImageAddParam param,String referenceId,String imageType){
        OssImage ossImage = new OssImage();
        ossImage.setImageType(imageType);
        ossImage.setObjectName(param.getObjectName());
        ossImage.setPurpose(param.getPurpose());
        ossImage.setReferenceId(referenceId);
        ossImage.setCreateTime(new Date());
        ossImageMapper.add(ossImage);
    }

    /**
     * 批量新增图片
     * @param list
     * @param referenceId
     * @param imageType
     */
    public void batchAdd(List list,String referenceId,String imageType){
        if(CollectionUtils.isEmpty(list))
            return;
        Date now = new Date();
        List ossImageList = new ArrayList<>();
        for(OssImageAddParam addParam:list){
            OssImage ossImage = new OssImage();
            ossImage.setImageType(imageType);
            ossImage.setObjectName(addParam.getObjectName());
            ossImage.setPurpose(addParam.getPurpose());
            ossImage.setReferenceId(referenceId);
            ossImage.setCreateTime(now);
            ossImageList.add(ossImage);
        }
        ossImageMapper.batchAdd(ossImageList);
    }

    /**
     * 批量删除图片
     * @param ids
     */
    @Transactional
    public void batchDelete(List ids){
        if(CollectionUtils.isEmpty(ids))
            return;
        List ossImages = ossImageMapper.getByIds(ids);
        OSSClient client = OssClientFactory.getOSSClient();
        for(OssImage ossImage:ossImages){
            client.deleteObject(bucketName,ossImage.getObjectName());
        }
        ossImageMapper.batchDelete(ids);
    }

    /**
     * 查询图片
     * @param param
     */
    public List searchOssImageList(OssImageSearchParam param){
        List ossImages = ossImageMapper.searchOssImageList(param);
        if(CollectionUtils.isEmpty(ossImages))
            return null;

        List ossImageDataList = new ArrayList<>();
        OSSClient ossClient = OssClientFactory.getOSSClient();
        long time = new Date().getTime();
        Date expireDate = new Date(time+expireTime * 60 * 60 * 1000);
        for(OssImage ossImage:ossImages) {
            OssImageData data = new OssImageData();
            data.setId(ossImage.getId());
            data.setReferenceId(ossImage.getReferenceId());
            data.setObjectName(ossImage.getObjectName());
            data.setPurpose(ossImage.getPurpose());
            boolean objectExist = ossClient.doesObjectExist(bucketName, ossImage.getObjectName());
            if(objectExist) {
                URL url = ossClient.generatePresignedUrl(bucketName, ossImage.getObjectName(), expireDate);
                data.setImgUrl(url.toString());
            }
            ossImageDataList.add(data);
        }
        return  ossImageDataList;
    }

}
/**
*对应OSS参数
*/
/**
*图片新增参数
*/
@Getter
@Setter
@ToString
public class OssImageAddParam implements Param{

    @ApiModelProperty(value = "图片用途")
    @NotEmpty(message = "图片用途不能为空")
    private String purpose; // 图片用途,自定义枚举

    @ApiModelProperty(value = "OSS objectname")
    @NotEmpty(message = "图片url不能为空")
    private String objectName; // OSS objectname
}
/**
*图片搜素参数
*/
@Getter
@Setter
@ToString
public class OssImageSearchParam implements Serializable{

    private String referenceId; //关联ID

    private List referenceIds;//关联ID集合

    private String imageType; //图片类型,1-商品,2-卖家,3-VAT订单

    private String purpose; //图片用途
}

后端直接上传文件:
一、创建相应的表
二、将文件转化成输入流
三、调用OssClient把生成url放到数据库中

      //文件上传到Oss服务器并还回URL
                String url = ossFileService.uploadFile(ossClient, bucketName, expireTime, key, inputStream).toString();

四、返回给前端相应的图片访问连接(注意:从数据库取出url 加上 String host = “http://” + bucketName + “.” + endpoint;)
注意点:
以上需求可能不满足你的业务需求:我的业务是没有进行回调如果需要回调请注意callback的设置。

定义callback 时,阿里支持两种方式,一个是callbackBody字符串直接拼接 用&符连接。
这里我使用的是第二种方式,callbackBody 采用json字符串。但是这跟以往的字符串不一样,中间有阿里自带的字符bucket,object,size等以及自定义的字符,ali oss 需要解析自定义字符,这里可以理解成变量的一个占位符,那么json串是如何拼接一个占位符变量呢?可以参照官网的一篇错误排查文章:https://yq.aliyun.com/articles/68863/callbackBody                                         
定义的原来是一个字符串的jsonobject,一直以为需要定义一个占位符类型的jsonobject对象,例如:callbackBody应该拼成这样 "{\'bucket\':${bucket},\'object\':${object},\'size\':${size},\'mimeType\':${mimeType},\'uid\':${x:uid},\'biz_type\':${x:biz_type}}"

你可能感兴趣的:(JAVA)