当前位置: 首页 > news >正文

七牛云上传图片

java项目中用到了七牛云上传图片,所以记录一下。是基于servlet的,相对的麻烦一点

在servlet中加入上传方法。

public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
       //图片上传
        if(!ServletFileUpload.isMultipartContent(req)){
            System.out.println("请选择文件-1");
            return;
        }
        Map<String, Object> resultMap = new HashMap<String, Object>();
        if(StringUtils.isEqual("image",dir)){
            FileUploadServiceImpl fileUploadServiceImpl = new FileUploadServiceImpl();
            //文件上传到七牛云
            Object resultObj = fileUploadServiceImpl.uploadFileToQn(req,resp,"");        
    
        }else{
            Logging.info("请选择上传图片,其他类型的文件暂不支持");

        }
        
    }

上传方法:

public Object uploadFileToQn(HttpServletRequest request,
            HttpServletResponse response, String baseUrl){
        long maxSize = 1000000;
        
        // 上传代码 
        FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setHeaderEncoding("UTF-8");
        List items;
        Object resultObj = null;
        try {
            items = upload.parseRequest(request);
            Iterator itr = items.iterator();
            while (itr.hasNext()) {
                FileItem item = (FileItem) itr.next();
                if (!item.isFormField()) {
                    byte[] data = item.get(); 
                    //检查文件大小
                    String fileUrl = uploadQnBytes(data);
                    //String fileUrl = "Fm88aB0hvslo6IGvrWCEKvJQ3FQg";
                    if(item.getSize() > maxSize){
                        System.out.println("上传文件大小超过限制。");
                        return null;
                    }
                    if (item.getSize() > 500 * 1024) { //文件大小大于200K
                        fileUrl = Constant.DOMAIN_NAME + fileUrl + "?imageslim";
                    } else {
                        fileUrl = Constant.DOMAIN_NAME + fileUrl;
                    }
                    resultObj  = fileUrl;
                }
            }
        } catch (FileUploadException e1) {
            Logging.error("2-文件上传失败");
            throw new IllegalStateException("2-文件上传失败");
        }
        
        return resultObj;
    }

开始上传:

    /**
     * 上传二进制到七牛
     * @param byteArr
     * @return
     * @throws BusException
     * @throws ErrorException
     */
    public  String uploadQnBytes(byte[] byteArr) {
        if (null == byteArr) {
            Logging.error("1-文件流不存在");
            throw new IllegalStateException("1-文件流不存在");
        }
        //构造一个带指定Zone对象的配置类
        Configuration cfg = new Configuration(Zone.zone0());
        //...其他参数参考类注释
        UploadManager uploadManager = new UploadManager(cfg);
        //...生成上传凭证,然后准备上传
        String accessKey = Constant.ACCESS_KEY;
        String secretKey = Constant.SECRET_KEY;
        String bucket = Constant.BUCKET;
        //默认不指定key的情况下,以文件内容的hash值作为文件名
        String key = null;
        Auth auth = Auth.create(accessKey, secretKey);
        String upToken = auth.uploadToken(bucket);
        try {
            Response response = uploadManager.put(byteArr, key, upToken);
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);//解析上传成功的结果
            return putRet.key;
        } catch (QiniuException ex) {
            try {
                throw new IllegalStateException("2-response" + ex.response.bodyString());
            } catch (QiniuException e) {
                throw new IllegalStateException("3-没有找到文件" + e.getMessage());
            }
        }
    }

Auth类:

package com.xyt.common.util;


import java.net.URI;
import java.security.GeneralSecurityException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import com.qiniu.util.Json;
import com.qiniu.util.StringMap;
import com.qiniu.util.StringUtils;
import com.qiniu.util.UrlSafeBase64;


public final class Auth {

    /**
     * 上传策略,参数规格详见
     * <p/>
     * http://developer.qiniu.com/docs/v6/api/reference/security/put-policy.html
     */
    private static final String[] policyFields = new String[]{
            "callbackUrl",
            "callbackBody",
            "callbackHost",
            "callbackBodyType",
            "callbackFetchKey",

            "returnUrl",
            "returnBody",

            "endUser",
            "saveKey",
            "insertOnly",

            "detectMime",
            "mimeLimit",
            "fsizeLimit",
            "fsizeMin",

            "persistentOps",
            "persistentNotifyUrl",
            "persistentPipeline",

            "deleteAfterDays",
    };
    private static final String[] deprecatedPolicyFields = new String[]{
            "asyncOps",
    };
    private final String accessKey;
    private final SecretKeySpec secretKey;

    private Auth(String accessKey, SecretKeySpec secretKeySpec) {
        this.accessKey = accessKey;
        this.secretKey = secretKeySpec;
    }

    public static Auth create(String accessKey, String secretKey) {
        if (StringUtils.isNullOrEmpty(accessKey) || StringUtils.isNullOrEmpty(secretKey)) {
            throw new IllegalArgumentException("empty key");
        }
        byte[] sk = StringUtils.utf8Bytes(secretKey);
        SecretKeySpec secretKeySpec = new SecretKeySpec(sk, "HmacSHA1");
        return new Auth(accessKey, secretKeySpec);
    }

    private static void copyPolicy(final StringMap policy, StringMap originPolicy, final boolean strict) {
        if (originPolicy == null) {
            return;
        }
        originPolicy.forEach(new StringMap.Consumer() {
            @Override
            public void accept(String key, Object value) {
                if (StringUtils.inStringArray(key, deprecatedPolicyFields)) {
                    throw new IllegalArgumentException(key + " is deprecated!");
                }
                if (!strict || StringUtils.inStringArray(key, policyFields)) {
                    policy.put(key, value);
                }
            }
        });
    }

    private Mac createMac() {
        Mac mac;
        try {
            mac = javax.crypto.Mac.getInstance("HmacSHA1");
            mac.init(secretKey);
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
            throw new IllegalArgumentException(e);
        }
        return mac;
    }

    public String sign(byte[] data) {
        Mac mac = createMac();
        String encodedSign = UrlSafeBase64.encodeToString(mac.doFinal(data));
        return this.accessKey + ":" + encodedSign;
    }

    public String sign(String data) {
        return sign(StringUtils.utf8Bytes(data));
    }

    public String signWithData(byte[] data) {
        String s = UrlSafeBase64.encodeToString(data);
        return sign(StringUtils.utf8Bytes(s)) + ":" + s;
    }

    public String signWithData(String data) {
        return signWithData(StringUtils.utf8Bytes(data));
    }

    /**
     * 生成HTTP请求签名字符串
     *
     * @param urlString
     * @param body
     * @param contentType
     * @return
     */
    public String signRequest(String urlString, byte[] body, String contentType) {
        URI uri = URI.create(urlString);
        String path = uri.getRawPath();
        String query = uri.getRawQuery();

        Mac mac = createMac();

        mac.update(StringUtils.utf8Bytes(path));

        if (query != null && query.length() != 0) {
            mac.update((byte) ('?'));
            mac.update(StringUtils.utf8Bytes(query));
        }
        mac.update((byte) '\n');
        if (body != null && body.length > 0 && !StringUtils.isNullOrEmpty(contentType)) {
            if (contentType.equals(Client.FormMime)
                    || contentType.equals(Client.JsonMime)) {
                mac.update(body);
            }
        }

        String digest = UrlSafeBase64.encodeToString(mac.doFinal());

        return this.accessKey + ":" + digest;
    }

    /**
     * 验证回调签名是否正确
     *
     * @param originAuthorization 待验证签名字符串,以 "QBox "作为起始字符
     * @param url                 回调地址
     * @param body                回调请求体。原始请求体,不要解析后再封装成新的请求体--可能导致签名不一致。
     * @param contentType         回调ContentType
     * @return
     */
    public boolean isValidCallback(String originAuthorization, String url, byte[] body, String contentType) {
        String authorization = "QBox " + signRequest(url, body, contentType);
        return authorization.equals(originAuthorization);
    }

    /**
     * 下载签名
     *
     * @param baseUrl 待签名文件url,如 http://img.domain.com/u/3.jpg 、
     *                http://img.domain.com/u/3.jpg?imageView2/1/w/120
     * @return
     */
    public String privateDownloadUrl(String baseUrl) {
        return privateDownloadUrl(baseUrl, 3600);
    }

    /**
     * 下载签名
     *
     * @param baseUrl 待签名文件url,如 http://img.domain.com/u/3.jpg 、
     *                http://img.domain.com/u/3.jpg?imageView2/1/w/120
     * @param expires 有效时长,单位秒。默认3600s
     * @return
     */
    public String privateDownloadUrl(String baseUrl, long expires) {
        long deadline = System.currentTimeMillis() / 1000 + expires;
        return privateDownloadUrlWithDeadline(baseUrl, deadline);
    }

    String privateDownloadUrlWithDeadline(String baseUrl, long deadline) {
        StringBuilder b = new StringBuilder();
        b.append(baseUrl);
        int pos = baseUrl.indexOf("?");
        if (pos > 0) {
            b.append("&e=");
        } else {
            b.append("?e=");
        }
        b.append(deadline);
        String token = sign(StringUtils.utf8Bytes(b.toString()));
        b.append("&token=");
        b.append(token);
        return b.toString();
    }

    /**
     * scope = bucket
     * 一般情况下可通过此方法获取token
     *
     * @param bucket 空间名
     * @return 生成的上传token
     */
    public String uploadToken(String bucket) {
        return uploadToken(bucket, null, 3600, null, true);
    }

    /**
     * scope = bucket:key
     * 同名文件覆盖操作、只能上传指定key的文件可以可通过此方法获取token
     *
     * @param bucket 空间名
     * @param key    key,可为 null
     * @return 生成的上传token
     */
    public String uploadToken(String bucket, String key) {
        return uploadToken(bucket, key, 3600, null, true);
    }

    /**
     * 生成上传token
     *
     * @param bucket  空间名
     * @param key     key,可为 null
     * @param expires 有效时长,单位秒
     * @param policy  上传策略的其它参数,如 new StringMap().put("endUser", "uid").putNotEmpty("returnBody", "")。
     *                scope通过 bucket、key间接设置,deadline 通过 expires 间接设置
     * @return 生成的上传token
     */
    public String uploadToken(String bucket, String key, long expires, StringMap policy) {
        return uploadToken(bucket, key, expires, policy, true);
    }

    /**
     * 生成上传token
     *
     * @param bucket  空间名
     * @param key     key,可为 null
     * @param expires 有效时长,单位秒。默认3600s
     * @param policy  上传策略的其它参数,如 new StringMap().put("endUser", "uid").putNotEmpty("returnBody", "")。
     *                scope通过 bucket、key间接设置,deadline 通过 expires 间接设置
     * @param strict  是否去除非限定的策略字段,默认true
     * @return 生成的上传token
     */
    public String uploadToken(String bucket, String key, long expires, StringMap policy, boolean strict) {
        long deadline = System.currentTimeMillis() / 1000 + expires;
        return uploadTokenWithDeadline(bucket, key, deadline, policy, strict);
    }

    public String uploadTokenWithDeadline(String bucket, String key, long deadline, StringMap policy, boolean strict) {
        String scope = bucket;
        if (key != null) {
            scope = bucket + ":" + key;
        }
        StringMap x = new StringMap();
        copyPolicy(x, policy, strict);
        x.put("scope", scope);
        x.put("deadline", deadline);

        String s = Json.encode(x);
        return signWithData(StringUtils.utf8Bytes(s));
    }

    public StringMap authorization(String url, byte[] body, String contentType) {
        String authorization = "QBox " + signRequest(url, body, contentType);
        return new StringMap().put("Authorization", authorization);
    }

    public StringMap authorization(String url) {
        return authorization(url, null, null);
    }
}

就可以完成七牛云上传了。

 

转载于:https://www.cnblogs.com/sunxun/p/9178484.html

相关文章:

  • s22day6笔记
  • BZOJ5093 [Lydsy1711月赛]图的价值 【第二类斯特林数 + NTT】
  • 【大数据Spark_SparkSQL系列_1】Spark SQL基础(五星重要)
  • bool值的底层应用场景
  • hihocoder:#1082 : 然而沼跃鱼早就看穿了一切(用string)
  • js中提示框闪退问题
  • Web站点抓取工具webhttrack
  • 在rabbitmq操作页面上添加队列、交换器及绑定示图
  • Windows10远程报错:由于CredSSP加密Oracle修正
  • dedecms四张表对应关系
  • Confluence 6 恢复一个站点问题解决
  • js寻路算法
  • C++公有继承、保护继承和私有继承
  • jmeter3.0+ant1.10+jenkins实现接口自动化并发送邮件
  • malloc(0)分配多少内存?(译文)
  • SegmentFault for Android 3.0 发布
  • Python_OOP
  • 规范化安全开发 KOA 手脚架
  • 前端_面试
  • 前端js -- this指向总结。
  • 数组大概知多少
  • 一些基于React、Vue、Node.js、MongoDB技术栈的实践项目
  • 与 ConTeXt MkIV 官方文档的接驳
  • 正则表达式
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • #### go map 底层结构 ####
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • *Django中的Ajax 纯js的书写样式1
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .net framework4与其client profile版本的区别
  • /proc/stat文件详解(翻译)
  • /var/lib/dpkg/lock 锁定问题
  • [2]十道算法题【Java实现】
  • [2544]最短路 (两种算法)(HDU)
  • [AIGC 大数据基础]hive浅谈
  • [AUTOSAR][诊断管理][ECU][$37] 请求退出传输。终止数据传输的(上传/下载)
  • [C# 网络编程系列]专题六:UDP编程
  • [daily][archlinux][game] 几个linux下还不错的游戏
  • [FUNC]判断窗口在哪一个屏幕上
  • [GDOUCTF 2023]<ez_ze> SSTI 过滤数字 大括号{等
  • [JS真好玩] 掘金创作者必备: 监控每天是谁取关了你?
  • [LeetCode]—Copy List with Random Pointer 深度复制带“任意指针”的链表
  • [OGRE]看备注学编程(02):打地鼠01-布置场地九只地鼠
  • [POI2009]WIE-Hexer
  • [pytest] 运行方式、常用参数、前后置条件
  • [python]tkinker的GUI应用执行耗时长的任务
  • [Real world Haskell] 中文翻译:前言
  • [Silverlight]通过MVVM模式实现本地化/全球化(1)
  • [Vue]中数组的操作用法
  • [webpack] devtool里的7种SourceMap[转]