【javaWeb】java实现IPFS文件下载和上传功能

        Kubo 是 IPFS的官方核心实现,由 Go 语言编写,是目前最成熟、应用最广泛的 IPFS 节点软件。 我们可以在此下载kubo并安装,具体教程可参见我的另一篇博客:

一、ipfs启动

         以上是安装完成后的界面,我们直接在此处打开cmd,分别运行以下命令对kubo进行启动部署。

# 初始化ipfs
ipfs init
# 启动ipfs服务
ipfs daemon

首次运行需要进行初始化,如果已经配置过会进行提示。 

如上图所示,ipfs启动成功后,我们可以访问http://127.0.0.1:5001/webui ,进入ipfs的页面。

 二、实现ipfs上传

        在实现上传下载功能前,我们要把ipfs的依赖引入到项目工程中

        <dependency>
            <groupId>com.github.ipfs</groupId>
            <artifactId>java-ipfs-http-client</artifactId>
            <version>1.3.3</version>
        </dependency>

        并且注意在项目配置文件中,对ipfs进行配置

ipfs:
  config:
    multi-addr: /ip4/127.0.0.1/tcp/5001 # ipfs的服务器地址和端口

        接下来,我们编写控制类,写出上传接口

    @Autowired
    IpfsService ipfsService;

    /**
     * 文件上传到ipfs
     *
     * @param file 待上传文件
     * @return Result
     */
    @PostMapping("/upload")
    public Result uploadIpfs(MultipartFile file) {
        String fileCID = ipfsService.uploadIpfs(file);
        Map<String, Object> map = new HashMap<>();
        map.put("msg","上传成功");
        map.put("data",fileCID);
        return Result.ok().data("info",map);
    }

        对uploadIipfs方法实现

    @Value("${server.port:8080}")
    private String port;

    @Value("${ip:localhost}")
    private String ip;

    @Value("${ipfs.config.multi-addr}")
    private String ipfsAddress;
    private static final String filePath = System.getProperty("user.dir") + "/files/";

    public String  uploadIpfs(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("上传文件为空");
        }
        String flag;
        synchronized (IpfsController.class) {
            flag = System.currentTimeMillis() + "";
            ThreadUtil.sleep(1L);
        }
        String fileName = file.getOriginalFilename();
        String fileCID;
        try {
            if (!FileUtil.isDirectory(filePath)) {
                FileUtil.mkdir(filePath);
            }
            IPFS ipfs = new IPFS(ipfsAddress);
            File uploadFile = FileUtils.MultipartFileToFile(file);
            NamedStreamable.FileWrapper saveFile = new NamedStreamable.FileWrapper(uploadFile);
            MerkleNode result = ipfs.add(saveFile).get(0);
            fileCID = result.hash.toBase58();
            System.out.println(fileCID);
            // 文件存储形式:时间戳-文件名
            FileUtil.writeBytes(file.getBytes(), filePath + flag + "-" + fileName);
            System.out.println(fileName + "--上传成功");
            FileUtils.deleteTempFile(uploadFile);
            System.out.println("文件上传地址" + filePath);
            return fileCID;
        } catch (Exception e) {
            System.err.println(fileName + "--文件上传失败");
            throw new RuntimeException("上传文件失败");
        }
    }

        现在进行测试

        提示 上传成功,并且返回了该文件的CID,我们可以复制此CID在ipfs的主页导入,检测图片是否一致。

三、实现ipfs下载

        类似上传,不过是另一种处理方式,我们接收文件的CID,这里称为hash

    /**
     * ipfs下载指定文件
     *
     * @param hash 待上传文件
     */
    @PostMapping("/download/{hash}")
    public void downloadIpfs(@PathVariable String hash, HttpServletResponse response) {
        try {
            ipfsService.downFromIpfs(response, hash);
        } catch (Exception e) {
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

        对downFromIpfs实现

    public void downFromIpfs(HttpServletResponse response, String hash) {
        IPFS ipfs = new IPFS(ipfsAddress);
        try {
            byte[] data = ipfs.cat(Multihash.fromBase58(hash));
            if (data == null || data.length == 0) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND, "文件不存在");
                return;
            }

            // 设置响应头
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(hash + ".jpg", "UTF-8") + "\"");
            response.setContentLength(data.length);

            // 直接写入响应流
            response.getOutputStream().write(data);
            response.flushBuffer();
        } catch (IOException e) {
            try {
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "文件下载失败");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

        进行测试,为了直观展示,我写了一个简单的html页面,测试下载功能在浏览器中的实际效果,如下

        我们在此输入之前的CID,可以发现接口识别后进行了下载,浏览器弹出下载窗口

        至此,java实现ipfs的上传下载功能结束,不过在下载部分,我这里仅对文件进行了统一的.jpg命名,如何实现自动识别文件类型从而添加对应的文件后缀,还请各位大佬进行指点!(抱拳) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奈何不吃鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值