Java百度网盘上传图片(文件)

Java百度网盘上传图片(文件)


前言

项目中有一个服务器调用百度网盘的接口实现服务器定时上传图片。
Ps:是百度网盘!不是百度云!
不知道会有人看吗,能看明白我写的吗。

一、准备工作

1.成为百度网盘的开发者

百度网盘开发者平台.
获取参数

2.获取token

1.配置回调地址,获取code,
百度开发者中心.这里是用来配置回调地址的。
在这里插入图片描述点击工程名,安全设置。就可以配置回调地址了。回调地址应该是一个服务器域名。得到code,用code换token。不过,我的回调地址是后台的,就无法访问。所以我是手动获取的。

3.手动获取token

因为我的回调地址域名是后台服务器。就无法直接访问。所以我手动获取token。(我猜是这样子的,其实为啥访问不了我的回调地址我也不知道。)
手动获取token上面的步骤都需要做的。唯一改变的就是回调地址换成百度网盘默认的oob就可以了。

链接: 获取token的说明.
获取token的方式我们用第一种方式就可以了。
在这里插入图片描述在浏览器中输入如上参数,只需要将最后的回调URL改成oob即可。如果有错要注意一下你的参数,url是否正确。
在这里插入图片描述用得到的code和你的注册时的参数。用浏览器访问这个地址就可以了。注意文档中说的API KEY其实就是你的APPKEY.这样你就会得到你需要的access_token和refresh_token了。
我是拿到后就放到ruoyi的参数配置中直接用了。ruoyi是存在redis和数据库中了。

4.定时任务进行刷新refreshtoken换取得到新的token


  //通过refreshToken获得新的token
    public void getNewToken(){
        System.out.println("执行获取token的方法");
        //百度网盘token
        String refreshToken = configService.selectConfigByKey("baidu.upload.wpRefreshToken");
        String apiKey = configService.selectConfigByKey("baidu.upload.apiKey");
        String secretKey = configService.selectConfigByKey("baidu.upload.secretKey");

        String url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=refresh_token"+"&refresh_token="+refreshToken+"&client_id="+apiKey+"&client_secret="+secretKey;
        String newToken = HttpUtil.get(url);
        JSONObject jsonObject = JSON.parseObject(newToken);
        String access_token = jsonObject.getString("access_token");
        String refresh_token = jsonObject.getString("refresh_token");
        System.out.println(access_token);
        System.out.println(refresh_token);

        //修改数据库和redis中token,refreshtoken的值
        SysConfig sysConfig = new SysConfig();
        sysConfig.setConfigId(103L);
        sysConfig.setConfigKey("baidu.upload.wpToken");
        sysConfig.setConfigValue(access_token);
        configService.updateConfig(sysConfig);
        sysConfig.setConfigId(104L);
        sysConfig.setConfigKey("baidu.upload.wpRefreshToken");
        sysConfig.setConfigValue(refresh_token);
        configService.updateConfig(sysConfig);
        return;
    }

5.需要准备的工具类

pom中引入hutoo工具类

<!--		工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.5.9</version>
        </dependency>

转md5json串

例子: //转MD5的json
//files是文件地址
    String md5One = getMD5One(files);
    JSONArray jsonArray = new JSONArray();
    jsonArray.add(md5One);
    readyUpload.setBlock_list(jsonArray.toJSONString());
            




    private final static String[] strHex = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};


    public static String getMD5One(String path) {
        StringBuffer sb = new StringBuffer();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] b = md.digest(FileUtils.readFileToByteArray(new File(path)));
            for (int i = 0; i < b.length; i++) {
                int d = b[i];
                if (d < 0) {
                    d += 256;
                }
                int d1 = d / 16;
                int d2 = d % 16;
                sb.append(strHex[d1] + strHex[d2]);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

根据地址计算图片大小

 /**
     * @param @param  imgPath
     * @param @return 根据图片地址返回图片大小kb或者 Mb
     * @return String
     * @throws
     * @Title: pathSize
     * @add (default no)
     */
    public static String pathSize(String imgPath) {
        File file = new File(imgPath);
        FileInputStream fis;
        int fileLen = 0;
        try {
            fis = new FileInputStream(file);
            fileLen = fis.available();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return String.valueOf(fileLen);
    }

第一个接口所需要的的实体类


import lombok.Data;

@Data
public class ReadyUpload {
    // 	上传后使用的文件绝对路径,需要urlencode(必选)
    private String path;
    //文件或目录的大小,单位B,目录的话大小为0(必选)
    private String size;
    //是否目录,0 文件、1 目录(必选)
    private String isdir;
    // 	固定值1(不必选)
    private  int autoinit;
    //文件命名策略,默认0
    //0 为不重命名,返回冲突
    //1 为只要path冲突即重命名
    //2 为path冲突且block_list不同才重命名
    //3 为覆盖
    //(不必须按)
    private  int rtype;
    //上传id
    private String uploadid;
    //文件各分片MD5数组的json串
    private String block_list;
    private String content_md5;
    private String slice_md5;
    private String local_ctime;
    private String local_mtime;

}

第三个接口需要的实体类

import lombok.Data;

@Data
public class FolderMerge {
    //上传后使用的文件绝对路径(必填)
    private String path;
    //文件或目录的大小,必须要和文件真实大小保持一致(必填)
    private String size;
    //是否目录,0 文件、1 目录(必填)
    private String isdir;

    private String blockList;



}

二、上传

链接: 上传说明文档.

看着说明文档就可以了。比较坑的一点就是上传的第二步骤,我用的官方文档的地址没有成功,会报没有用户不存在的错误。在网上找了好久,接口中换了下参数。
链接: 参考一下这个.
或者直接看我代码第二步中的接口就可以了。那就直接上代码了。

1.上传的三个接口

代码如下(示例):

 /**
     * 预上传
     * @param readyUpload 预上传参数
     * @return 响应参数
     */
    public String readyUpload(ReadyUpload readyUpload) {
        // 请求url
        //百度网盘token
        String accessToken = configService.selectConfigByKey("baidu.upload.wpToken");
        String url = "http://pan.baidu.com/rest/2.0/xpan/file?method=precreate"+"&access_token="+accessToken;
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("path",readyUpload.getPath());
            map.put("size",readyUpload.getSize());
            map.put("isdir",readyUpload.getIsdir());
            map.put("autoinit",readyUpload.getAutoinit());
            map.put("block_list",readyUpload.getBlock_list());
            map.put("rtype",3);
            //String param = GsonUtils.toJson(map);
            //发送请求
            //String result = HttpUtil.post(url, accessToken,"application/json", param);
            String result = cn.hutool.http.HttpUtil.post(url, map);
            System.out.println(result);
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return  null;
    }

注意分片上传的接口参数和官网有出入。

   /**
     * 分片上传
     * @param file 上传的文件内容
     * @param path 上传后使用的文件绝对路径,需要urlencode
     *
     *
     * @param uploadid precreate接口下发的uploadid
     * @param partseq 文件分片的位置序号,从0开始,参考precreate接口返回的block_list
     * @return
     */
    public String slicingUpload(String file, String path, String uploadid, int partseq) throws Exception {
        //百度网盘token
        String accessToken = configService.selectConfigByKey("baidu.upload.wpToken");
        //百度网盘appId
        String appId = configService.selectConfigByKey("baidu.upload.appId");
        //token
        // 请求url
        String url = "https://d.pcs.baidu.com/rest/2.0/pcs/superfile2?"+"&app_id="+appId+"&access_token="+accessToken+"&method=upload&type=tmpfile"+"&path="+path+"&uploadid="+uploadid+"&partseq="+partseq;
        Map<String, Object> map = new HashMap<>();
        map.put("file",new File(file));
        try {

           String result = HttpUtil.post(url, map);
            System.out.println(result);
            return result;

        }catch (Exception e){
            e.printStackTrace();
        }
        return  null;
    }

第三步,创建文件

     /**
     * 创建文件 用于将多个分片合并成一个文件,完成文件的上传。
     * 备注:可以使用该接口创建文件夹。
     * @param folderMerge 创建文件参数
     * @return
     */
    public String folderMerge(FolderMerge folderMerge) {
        //百度网盘token
        String accessToken = configService.selectConfigByKey("baidu.upload.wpToken");
        // 请求url
         String url = "https://pan.baidu.com/rest/2.0/xpan/file?method=create"+"&access_token=" + accessToken;

        try {
            Map<String, Object> map = new HashMap<>();
            //todo
            map.put("path",folderMerge.getPath());
            map.put("size",folderMerge.getSize());
            map.put("isdir",folderMerge.getIsdir());
            map.put("block_list",folderMerge.getBlockList());
            String result = HttpUtil.post(url,map);
            System.out.println(result);
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return  null;
    }

post请求好像都可以用huttool的工具类发送(和代码无关,给我自己看的)

/**
	 * 发送post请求
	 *
	 * @param urlString 网址
	 * @param paramMap  post表单数据
	 * @return 返回数据
	 */
	public static String post(String urlString, Map<String, Object> paramMap) {
		return post(urlString, paramMap, HttpGlobalConfig.timeout);
	}

2.调用接口

代码如下(示例):




@RestController
@Slf4j
@Component("wpUploadController")
public class WpUploadController {
 
    @Value("${ruoyi.profile}")
    private String profile;

    /**
     * 上传接口测试
     *
     * @return
     * @throws Exception
     */
    @PostMapping("/gototest")
    public void Test() throws Exception {
        try {
                //文件地址
        String files = "D:\\zz.jpg";
                readyUpload.setIsdir("0");
                readyUpload.setAutoinit(1);
                readyUpload.setSize(pathSize(files));
                System.out.println(pathSize(files));
                //转MD5的json
                String md5One = getMD5One(files);
                JSONArray jsonArray = new JSONArray();
                jsonArray.add(md5One);
                readyUpload.setBlock_list(jsonArray.toJSONString());

                String result = uploadServce.readyUpload(readyUpload);

                JSONObject jsonObject = JSON.parseObject(result);
                String uploadid = jsonObject.getString("uploadid");
                String block_list = jsonObject.getString("block_list");
                String path = jsonObject.getString("path");
                System.out.println(path);


                //分片上传
                String slicingUploadresult = uploadServce.slicingUpload(files, path, uploadid, 0);
                JSONObject slicingUploadObject = JSON.parseObject(slicingUploadresult);
                String md5 = slicingUploadObject.getString("md5");


//        //创建文件直接上传
                FolderMerge folderMerge = new FolderMerge();
                folderMerge.setPath(path);
//        folderMerge.setSize("702");
                folderMerge.setSize(pathSize(files));
                folderMerge.setIsdir("0");
                JSONArray jsonArray2 = new JSONArray();
                jsonArray2.add(md5);
                folderMerge.setBlockList(jsonArray2.toJSONString());
                String folderMergeResult = uploadServce.folderMerge(folderMerge);
            }
        } catch (Exception e) {
            System.out.println("网盘上传图片失败!");
            e.printStackTrace();
        }
    }




    private final static String[] strHex = {"0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    public static String getMD5One(String path) {
        StringBuffer sb = new StringBuffer();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] b = md.digest(FileUtils.readFileToByteArray(new File(path)));
            for (int i = 0; i < b.length; i++) {
                int d = b[i];
                if (d < 0) {
                    d += 256;
                }
                int d1 = d / 16;
                int d2 = d % 16;
                sb.append(strHex[d1] + strHex[d2]);
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    /**
     * @param @param  imgPath
     * @param @return 根据图片地址返回图片大小kb或者 Mb
     * @return String
     * @throws
     * @Title: pathSize
     * @add (default no)
     */
    public static String pathSize(String imgPath) {
        File file = new File(imgPath);
        FileInputStream fis;
        int fileLen = 0;
        try {
            fis = new FileInputStream(file);
            fileLen = fis.available();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return String.valueOf(fileLen);
    }

}

该处使用的url网络请求的数据。


总结

post请求好像都可以用huttool的工具类发送,
顺便给大家分享一下stream流的文章。
链接: java8Stream流常用操作.

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值