Spring Boot项目OSS整合

摘要: 主要是PC项目前端上传需要从服务端拿到OSS认证才能上传、后端直接调用OSSClient上传就行。
##Ali OSS前端获取签名上传文件
文件上传流程比较复杂的服务器设置回调功能。整个流程图是这样的
这里写图片描述
可以参考阿里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 = //唯一标识
oss.accessKeySecret = //密钥
oss.bucketName = ## //文件存储目录名
oss.expireTime = 3600 //

OssClient单例工厂

/**
 * ClassName: OssClientFactory <br/>
 * Function: OssClient单例工厂 <br/>
 * date: 2017/11/9 11:14 <br/>
 *
 * @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<OssAuthorizeData> 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<Void> 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<Void> 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<OssAuthorizeData> authorize(String dir);

    ReturnData<Void> remove(String objectName);

    ReturnData<Void> 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<OssAuthorizeData> 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<Void> 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<Void> 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);
        }
    }

}

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

<!--mybatis文件-->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xinguang.ftcs.common.mapper.OssImageMapper">

    <insert id="add" parameterType="OssImage">
        INSERT INTO t_oss_image
        <trim prefix="(" 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>
        </trim>
        <trim prefix="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>
        </trim>
    </insert>

    <!-- 批量新增图片 -->
    <insert id="batchAdd" parameterType="java.util.List">
        insert into t_oss_image
        (
            reference_id,
            image_type,
            purpose,
            object_name,
            create_time
        )
        values
        <foreach collection="list" item="item" index="index" separator="," >
            (#{item.referenceId},#{item.imageType},#{item.purpose},#{item.objectName},#{item.createTime})
        </foreach>
    </insert>

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

    <select id="searchOssImageList" parameterType="com.xinguang.ftcs.common.param.OssImageSearchParam"
            resultType="OssImage">
        SELECT
            id,reference_id,image_type,purpose,object_name,create_time
        FROM
            t_oss_image
        WHERE
            del_flag = '0'
        <if test="referenceId != null and  referenceId != ''">
            and reference_id = #{referenceId}
        </if>
        <if test="imageType != null and  imageType != ''">
            and image_type = #{imageType}
        </if>
        <if test="purpose != null and  purpose != ''">
            and purpose = #{purpose}
        </if>
        <if test="referenceIds != null">
            and reference_id in
            <foreach collection="referenceIds" item="referenceId" open="(" separator="," close=")">
                #{referenceId}
            </foreach>
        </if>
    </select>

    <select id="getByIds" parameterType="java.util.List" resultType="OssImage">
        SELECT
            id,reference_id,image_type,purpose,object_name,create_time
        FROM
            t_oss_image
        WHERE
            id in
            <foreach collection="list" item="id" open="(" separator="," close=")">
                #{id}
            </foreach>
    </select>

</mapper>
//对应Mapper文件
@Mapper
public interface OssImageMapper {

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

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

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

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

    /** 通过主键Ids获取集合 */
    List<OssImage> getByIds(List<Long> 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<OssImageAddParam> list,String referenceId,String imageType){
        if(CollectionUtils.isEmpty(list))
            return;
        Date now = new Date();
        List<OssImage> 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<Long> ids){
        if(CollectionUtils.isEmpty(ids))
            return;
        List<OssImage> ossImages = ossImageMapper.getByIds(ids);
        OSSClient client = OssClientFactory.getOSSClient();
        for(OssImage ossImage:ossImages){
            client.deleteObject(bucketName,ossImage.getObjectName());
        }
        ossImageMapper.batchDelete(ids);
    }

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

        List<OssImageData> 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<String> 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}}"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值