一、配置

依赖:

  1. <!-- OSS SDK 相关依赖 -->
  2. <dependency>
  3. <groupId>com.aliyun.oss</groupId>
  4. <artifactId>aliyun-sdk-oss</artifactId>
  5. <version>2.5.0</version>
  6. </dependency>

添加配置类:

@Configuration
public class OssConfig {
    final static private String ALIYUN_OSS_ENDPOINT = "oss-cn-shenzhen.aliyuncs.com";
    final static private String ALIYUN_OSS_ACCESSKEY_ID = "your ak";
    final static private String ALIYUN_OSS_ACCESSKEY_SECRET = "your as";

    @Bean
    public OSSClient ossClient(){
        return new OSSClient(ALIYUN_OSS_ENDPOINT, ALIYUN_OSS_ACCESSKEY_ID, ALIYUN_OSS_ACCESSKEY_SECRET);
    }
}

二、上传策略及成功后的回调参数

添加OSS上传策略封装对象OssPolicyResult,前端直接上传文件时所需参数。

@Data
public class OssPolicyResult {
    private String accessKeyId;
    private String policy;
    private String signature;
    private String dir;
    private String host;
    private String callback;
}

添加OSS上传成功后的回调参数对象OssCallbackParam,当OSS上传成功后,会根据该配置参数来回调对应接口。

@Data
public class OssCallbackParam {
    private String callbackUrl; // 请求的回调地址
    private String callbackBody; // 回调是传入request中的参数
    private String callbackBodyType; // 回调时传入参数的格式,比如表单提交形式
}

OSS上传成功后的回调结果对象OssCallbackResult,回调接口中返回的数据对象,封装了上传文件的信息。

@Data
public class OssCallbackResult {
    private String filename;
    private String size;
    private String mimeType;
    private String width;
    private String height;
}

三、创建Service

public interface OssService {
    // oss上传策略生成
    OssPolicyResult policy();

    // oss上传成功回调
    OssCallbackResult callback(HttpServletRequest request);
}

服务的实现类:

import cn.hutool.json.JSONUtil;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.example.test.dto.OssCallbackParam;
import com.example.test.dto.OssCallbackResult;
import com.example.test.dto.OssPolicyResult;
import com.example.test.service.OssService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class OssServiceImpl implements OssService {
    private static final Logger LOGGER = LoggerFactory.getLogger(OssServiceImpl.class);
    final static private int ALIYUN_OSS_EXPIRE = 300;
    final static private int ALIYUN_OSS_MAX_SIZE = 10;
    final static private String ALIYUN_OSS_CALLBACK = "http://localhost:10010/aliyun/oss/callback";
    final static private String ALIYUN_OSS_ENDPOINT = "oss-cn-shenzhen.aliyuncs.com";
    final static private String ALIYUN_OSS_BUCKET_NAME = "your bucket_name";
    final static private String ALIYUN_OSS_DIR_PREFIX = "images/";

    @Autowired
    private OSSClient ossClient;

    /**
     * 签名生成
     */
    @Override
    public OssPolicyResult policy() {
        OssPolicyResult result = new OssPolicyResult();
        // 存储目录
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dir = ALIYUN_OSS_DIR_PREFIX+sdf.format(new Date());
        // 签名有效期
        long expireEndTime = System.currentTimeMillis() + ALIYUN_OSS_EXPIRE * 1000;
        Date expiration = new Date(expireEndTime);
        // 文件大小
        long maxSize = ALIYUN_OSS_MAX_SIZE * 1024 * 1024;
        // 回调
        OssCallbackParam callback = new OssCallbackParam();
        callback.setCallbackUrl(ALIYUN_OSS_CALLBACK);
        callback.setCallbackBody("filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
        callback.setCallbackBodyType("application/x-www-form-urlencoded");
        // 提交节点
        String action = "http://" + ALIYUN_OSS_BUCKET_NAME + "." + ALIYUN_OSS_ENDPOINT;
        try {
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String policy = BinaryUtil.toBase64String(binaryData);
            String signature = ossClient.calculatePostSignature(postPolicy);
            String callbackData = BinaryUtil.toBase64String(JSONUtil.parse(callback).toString().getBytes("utf-8"));
            // 返回结果
            result.setAccessKeyId(ossClient.getCredentialsProvider().getCredentials().getAccessKeyId());
            result.setPolicy(policy);
            result.setSignature(signature);
            result.setDir(dir);
            result.setCallback(callbackData);
            result.setHost(action);
        } catch (Exception e) {
            LOGGER.error("签名生成失败", e);
        }
        return result;
    }

    @Override
    public OssCallbackResult callback(HttpServletRequest request) {
        OssCallbackResult result= new OssCallbackResult();
        String filename = request.getParameter("filename");
        filename = "http://".concat(ALIYUN_OSS_BUCKET_NAME).concat(".").concat(ALIYUN_OSS_ENDPOINT).concat("/").concat(filename);
        result.setFilename(filename);
        result.setSize(request.getParameter("size"));
        result.setMimeType(request.getParameter("mimeType"));
        result.setWidth(request.getParameter("width"));
        result.setHeight(request.getParameter("height"));
        return result;
    }
}

四、在控制器中使用

@Controller
@RequestMapping("/aliyun/oss")
public class OssController {
    @Autowired
    private OssService ossService;

    @RequestMapping(value = "/policy", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult<OssPolicyResult> policy() {
        OssPolicyResult result = ossService.policy();
        return CommonResult.success(result);
    }

    @RequestMapping(value = "callback", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult<OssCallbackResult> callback(HttpServletRequest request) {
        OssCallbackResult ossCallbackResult = ossService.callback(request);
        return CommonResult.success(ossCallbackResult);
    }
}

测试:
001.png

这样就能将前端需要的上传参数返回,具体的前端上传参考阿里云的文档。

参考资料