IPFS节点部署及连接java服务接口

文章目录

    • 引言
    • 前言:IPFS网络部署
        • 1.下载安装文件
        • 2.安装及初始化
        • 3.测试上传文件
    • 引入IPFS 依赖包
    • 初始化IPFS
    • 创建接口类以及实现类
    • 创建前端访问的控制类
    • 前端设计及验证

引言

该篇文章是记录使用IPFS存储文件与java的Springboot项目连接的过程,前端简单地用了一个vue的文件传输组件,将本地的文件上传到IPFS中存储,并返回哈希值。

前言:IPFS网络部署

1.下载安装文件

ipfs官网地址:https://dist.ipfs.tech/
下载kubo(go-ipfs),安装列表中适配的操作系统进行下载对应的安装文件。

2.安装及初始化
#1.解压安装包
$tar -zxvf kubo_v0.21.0_linux-amd64.tar.gz
#2.进入解压后的目录
$cd kubo
#3.执行install.sh脚本
$./install.sh
#4.执行初始化
$ipfs init
#5.解决跨域问题
$ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST", "OPTIONS"]'
$ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
$ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]'
$ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '["Authorization"]'
$ipfs config --json API.HTTPHeaders.Access-Control-Expose-Headers '["Location"]'
#6.启动ipfs
$ipfs daemon
#7.若启动时与本地服务端口发生冲突,可以在IPFS的配置中对端口进行重新指定
3.测试上传文件

在改目录下创建一个blockchain.txt文件,

在这里插入图片描述

ipfs 使用add 命令来添加内容到节点中, 在命令行输入:

$ipfs add blockchain.txt

在这里插入图片描述

当它文件添加到节点时,会为文件生成唯一的hash,可以使用ipfs cat 查看文件的内容:

$ipfs cat QmaXomPM2Kh1pNmhpvY1M5jFvThoZBHp2NckDJTbBnb6Xa

在这里插入图片描述

引入IPFS 依赖包

首先在创建的Springboot项目中的pom.xml文件中添加ipfs依赖,

<repositories>
		<repository>
			<id>jitpack.io</id>
			<url>https://jitpack.io</url>
		</repository>
</repositories>
<dependency>
		<groupId>com.github.ipfs</groupId>
		<artifactId>java-ipfs-http-client</artifactId>
		<version>v1.4.4</version>
</dependency>

在这里插入图片描述

初始化IPFS

初始化IPFS的过程主要是编写配置类,用于与本地你开启的IPFS节点进行连接,本篇文章只启动了一个IPFS节点,后续会进行多节点的连接。

首先配置IPFS系统的属性配置类IpfsProperties,需要注意的是multiAddr的设置,multiAddr的值用于指定IPFS节点的网络地址和端口,这样客户端就可以通过这个地址连接到IPFS节点。

当我们用ipfs daemon启动节点之后,就可以在控制台看到,

在这里插入图片描述

package com.example.eduction.utils;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "ipfs.config")
public class IpfsProperties {
    private String multiAddr="/ip4/127.0.0.1/tcp/5001";
}

在这里插入图片描述

然后初始化相关类BeanConfig,

package com.example.eduction.utils;
import io.ipfs.api.IPFS;
import lombok.extern.log4j.Log4j2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
import java.io.IOException;
/**
 * 初始化相关类
 */
@Log4j2
@Configuration
public class BeanConfig {
    @Resource
    private IpfsProperties ipfsProperties;
    @Bean
    public IPFS ipfs() throws IOException {
        IPFS ipfs = new IPFS(ipfsProperties.getMultiAddr());
        ipfs.refs.local();
        return ipfs;
    }
}

在这里插入图片描述

以上的两个类的代码我感觉可以用IPFS ipfs = new IPFS("/ip4/127.0.0.1/tcp/5001"),这一行代码搞定,但还没有验证,后续可以试试。

创建接口类以及实现类

首先创建接口类IpfsService,

package com.example.eduction.controller;
import com.example.eduction.utils.BeanConfig;
import org.springframework.stereotype.Service;
import java.io.IOException;
@Service
public interface IpfsService {

    String uploadToIpfs(String filePath) throws IOException;

    String uploadToIpfs(byte[] fileData) throws IOException;

    byte[] downFromIpfs(String hash);

    void downFromIpfs(String hash, String destFilePath);
}

在这里插入图片描述

然后创建实现类IpfsServiceImpl,

package com.example.eduction.controller;
import cn.hutool.core.io.FileUtil;
import io.ipfs.api.IPFS;
import io.ipfs.api.MerkleNode;
import io.ipfs.api.NamedStreamable;
import io.ipfs.multihash.Multihash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;


/**
 * 连接ipfs星际文件系统的文件上传和下载服务类
 */
@Service
public class IpfsServiceImpl implements IpfsService {

    @Autowired
    private IPFS ipfs;

    @Autowired
    public IpfsServiceImpl(IPFS ipfs){
        this.ipfs=ipfs;
    }
    /**
     * 指定文件路径上传文件到ipfs
     *
     * @param filePath 文件路径
     * @return 存储文件的寻址哈希
     * @throws IOException
     */
    @Override
    public String uploadToIpfs(String filePath) throws IOException {
        NamedStreamable.FileWrapper file = new NamedStreamable.FileWrapper(new File(filePath));
        MerkleNode addResult = ipfs.add(file).get(0);
        String hash = addResult.hash.toString();
        return hash;
    }
    /**
     * 将byte格式的数据,上传至ipfs
     *
     * @param fileData
     * @return 存储文件的寻址哈希
     * @throws IOException
     */
    @Override
    public String uploadToIpfs(byte[] fileData) throws IOException {
        NamedStreamable.ByteArrayWrapper file = new NamedStreamable.ByteArrayWrapper(fileData);
        MerkleNode addResult = ipfs.add(file).get(0);
        return addResult.hash.toString();
    }
    /**
     * 根据Hash值,从ipfs下载内容,返回byte数据格式
     * @param hash 文件寻址哈希
     * @return
     */
    @Override
    public byte[] downFromIpfs(String hash) {
        byte[] data = null;
        try {
            data = ipfs.cat(Multihash.fromBase58(hash));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 根据Hash值,从ipfs下载内容,并写入指定文件destFilePath
     *
     * @param hash         文件寻址哈希
     * @param destFilePath 目标文件路径
     */
    @Override
    public void downFromIpfs(String hash, String destFilePath) {
        byte[] data = null;
        try {
            data = ipfs.cat(Multihash.fromBase58(hash));
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (data != null && data.length > 0) {
            FileUtil.del(destFilePath);
            FileUtil.writeBytes(data, destFilePath);
        }
    }
}

在这里插入图片描述

创建前端访问的控制类

创建FileUploadController,我设置的调用路径为http://127.0.0.1:8423/upload , 这里文件上传接口编写需要注意的是文件的路径和名称,从前端上传的文件是以MultipartFile的形式传到后端的,然后我们利用getOriginalFilename()方法获取真实的文件名称,但这只是获取了文件的名称,而没有获取文件路径。这个文件路径是系统的绝对路径,因此我们要再加上dir前缀。

package com.example.eduction.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController
@CrossOrigin//支持跨域
public class FileUploadController {

    @Autowired
    IpfsServiceImpl ipfsService;
    @PostMapping("/upload")
    public String upload(MultipartFile file) throws Exception {
        System.out.println(file.getOriginalFilename());
        String originalfilename = file.getOriginalFilename();
        String dir="/fisco/Eduction/src/main/java/com/example/eduction/assets/";
        ipfsService.uploadToIpfs(dir+originalfilename);
        System.out.println(ipfsService.uploadToIpfs(dir+originalfilename));
        return ipfsService.uploadToIpfs(dir+originalfilename);
    }
}

在这里插入图片描述

前端设计及验证

前端采用vue+elementui,随便写了一个接口。

<template>
  <el-card class="box-card">
    <div slot="header" class="clearfix">
      <span>学历存证</span>
<!--      <el-button style="float: right; padding: 3px 0" type="text">操作按钮</el-button>-->
    </div>
    <div class="text item">
      {{'下载学历数据填写表'}}<el-button type="primary" style="margin-left: 100px;text-align: left" @click="downloadTable">点击下载</el-button>
    </div>
    <div class="text item">
      {{'上传填写好的学历数据填写表'}}

      <el-upload
        class="upload-demo"
        action="http://localhost:8463/upload"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :on-success="uploadsuccess"
        :before-remove="beforeRemove"
        multiple
        :limit="3"
        :on-exceed="handleExceed"
        :file-list="fileList">
        <el-button type="primary" >点击上传</el-button>
        <div slot="tip" class="el-upload__tip">只能上传txt文件,且不超过500kb</div>
      </el-upload>
    </div>
    <el-button type="success" @click="confirmSubmit">确认提交</el-button>
  </el-card>
</template>

在这里插入图片描述

然后点击点击上传按钮,选择我自己的系统路径"/fisco/Eduction/src/main/java/com/example/eduction/assets/"下的文件,

成功上传之后就会显示出来,

在这里插入图片描述

并且,我在后端控制台设置了文件存储在IPFS后打印hash值,因此我们可以再后端看到hash值打印出来,说明我们上传成功。

在这里插入图片描述

最后我们验证一下,使用改hash索引是否能够在ipfs返回我们所存的文件内容,

在这里插入图片描述

结果返回我们存在filetest.txt文件里面的内容8623。

参考文章

IPFS 使用入门 | 登链社区 | 区块链技术社区 (learnblockchain.cn)

区块链 - 集成IPFS星际文件系统,并基于WeBASE-Front发送交易接口实现文件类上链存证的方案 - 个人文章 - SegmentFault 思否

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/679825.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于websocket与node搭建简易聊天室

一、前言 上一篇文章介绍了websocket的详细用法与工具类的封装&#xff0c;本篇就基于websocket搭建一个简易实时的聊天室。 在本篇开始之前也可以去回顾一下websocket详细用法&#xff1a;WebSocket详解与封装工具类 二、基于node搭建后台websocket服务 首先确认本机电脑中…

YOLOv8改进 | Conv篇 | 利用YOLOv10提出的C2fUIB魔改YOLOv8(附代码 + 完整修改教程)

一、本文介绍 本文给大家带来的改进机制是利用YOLOv10提出的C2fUIB模块助力YOLOv8进行有效涨点&#xff0c;其中C2fUIB模块所用到的CIB模块是一种紧凑的倒置块结构&#xff0c;它采用廉价的深度卷积进行空间混合&#xff0c;并采用成本效益高的点卷积进行通道混合。本文针对该…

Window10磁盘的分盘和合并

注意&#xff1a; 当我们c盘不够大需要扩大磁盘空间时&#xff0c;当c盘后面没有未划分的磁盘时候&#xff0c;我们是无法进行扩充c盘的&#xff0c;此时&#xff0c;我们可以先删除后面一个磁盘&#xff0c;再进行扩大。 如下&#xff1a;c盘后没有未分配的空间&#xff0c;…

Flink端到端的精确一次(Exactly-Once)

目录 状态一致性 端到端的状态一致性 端到端精确一次&#xff08;End-To-End Exactly-Once&#xff09; Flink内部的Exactly-Once 输入端保证 输出端保证 幂等写入 事务写入 Flink和Kafka连接时的精确一次保证 整体介绍 需要的配置 案例 状态一致性 流式计算本身就…

UI 自动化分布式测试 -Docker Selenium Grid

分布式测试Selenium Grid 对于大型项目或者有大量测试用例的项目,单机的测试环境往往无法快速完成所有测试用例的执行,此时自动化测试执行效率将会成为最大的瓶颈,Selenium Grid 可以通过多机的分布式架构允许测试用例并行运行,大大缩短了测试时间。 Selenium Grid 提供了多…

命令模式(行为型)

目录 一、前言 二、命令模式 三、总结 一、前言 命令模式&#xff08;Command Pattern&#xff09;是一种行为型设计模式&#xff0c;命令模式将一个请求封装为一个对象&#xff0c;从而可以用不同的请求对客户进行参数化&#xff1b;对请求排队或记录请求日志&#xff0c;以…

此表单不安全,因此系统已关闭自动填充功能

问题截图&#xff1a; 截图就不放了&#xff0c;公司的系统不方便&#xff0c;就是form表单会有个提示“此表单不安全&#xff0c;因此系统已关闭自动填充功能” 解决思路&#xff1a; 1、问题原因 使用https访问&#xff0c;但表单提交地址是http的 2、查看表单配置 表单…

行业分析---造车新势力之理想汽车

1 前言 在之前的博客中&#xff0c;笔者撰写了多篇行业类分析的文章&#xff08;科技新能源&#xff09;&#xff1a; 《行业分析---我眼中的Apple Inc.》 《行业分析---马斯克的Tesla》 《行业分析---造车新势力之蔚来汽车》 《行业分析---造车新势力之小鹏汽车》 此类文章的受…

IIC信号质量测试、时序测试详解

IIC 时序图 信号质量测试 1、vIL: 低输入电平。 2、vIH: 高输入电平。 3、vhys: 施密特触发器输入的滞后。 4、vOL1: VDD>2V时&#xff0c;低电平输出电压&#xff08;漏极开路或集电极开路&#xff09;。 5、vOL3: VDD<2V时&#xff0c;低电平输出电压&#xff08;漏极开…

js 数字精确度

事情的起源&#xff1a; 项目中 填写的赔付金额是小数 传给后端需要 *100 9.87 *100 传给后端后是986.9999999999999 后端直接取整 就变成了9.86了 0.1 0.2 ! 0.3 console.log(0.1 0.2) //0.30000000000000004 console.log(0.1 0.2 0.3) //false1. 数字的存储 浮点数是用…

【因果推断python】14_控制混淆因素3

目录 不良控制 - 选择偏差 糟糕的 COP 关键思想 不良控制 - 选择偏差 让我们回到债务催收电子邮件的案例。 请记住&#xff0c;电子邮件是随机分配给客户的。 我们已经解释了什么是 信用额度 和 风险分 。 现在&#xff0c;让我们看看剩下的变量。 打开 是客户是否打开电子邮…

工厂模式——工厂方法模式+注册表

工厂方法模式的瑕疵 在前一篇笔记中我们介绍了工厂方法模式&#xff0c;示例的类图如下&#xff1a; 考虑一种情况&#xff1a;现在要在程序运行时&#xff0c;根据外部资源&#xff0c;动态的实例化对象。也就是说在编译期我们无法知道要实例化的对象的类型。因此在实例化的过…

el-input实现后缀图标和clearable的兼容,调整el-input clearable与自定义图标展示位置问题

背景&#xff1a;常见的输入框存在两个图标的展示效果都是清空在前搜索或其他图标在后 常见以及最终实现效果&#xff08;清空图标在前&#xff0c;搜索图标在后&#xff09; BUG以及el-input默认效果 问题排查 通过控制台审查元素能够发现&#xff0c;默认的效果是自定义图标…

数据结构_手撕七大排序(快排,归并,堆排,希尔,选择,插入,冒泡)

✨✨所属专栏&#xff1a;数据结构✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a;假定在待排序的记录序…

使用wheelnav.js构建酷炫的动态导航菜单

目录 前言 一、WheelNav是什么 1、项目地址 2、关于开源协议 3、相关目录介绍 二、如何使用wheelnav.js 1、新建html页面 2、设置style样式 3、创建展示元素实现动态导航 三、参数即方法介绍 1、参数列表 2、运行方法 3、实际成果 四、总结 前言 用户体验永远是一…

『 Linux 』目录与软硬链接 (万字详解)

文章目录 如何理解目录目录项 目录中的权限问题根目录Dentry缓存文件的增删改查与文件系统关系软硬链接软链接硬链接 如何理解目录 目录是一个文件存在其对应独立的Inode; $ stat dirFile: ‘dir’Size: 4096 Blocks: 8 IO Block: 4096 directory Device: f…

栈的最小值

题目链接 栈的最小值 题目描述 注意点 执行push、pop和min操作的时间复杂度必须为O(1) 解答思路 使用两个栈&#xff0c;一个栈deque存储栈中对应的元素值&#xff0c;另一个栈minDeque存储当前栈中所有元素的最小值&#xff0c;当执行push(int x)操作&#xff0c;deque直…

【乐吾乐3D可视化组态编辑器】数据接入

数据接入 本文为您介绍3D数据接入功能&#xff0c;数据接入功能分为三个步骤&#xff1a;数据订阅、数据集管理、数据绑定 编辑器地址&#xff1a;3D可视化组态 - 乐吾乐Le5le 数据订阅 乐吾乐3D组态数据管理功能由次顶部工具栏中按钮数据管理打开。 在新弹窗中选择数据订阅…

白银票据~

一. 白银票据的原理 白银票据就伪造ST票据&#xff0c; kerberoasting是破解ST票据中的服务用户hash值&#xff0c;有以下区别&#xff1a; 白银票据&#xff1a;伪造的ST使用的是机器用户的Hash值 Kerberoasting:破解的是ST的域用户的hash值二. 白银票据的利用条件 1.域名 …

基于线性回归根据饮食习惯和身体状况估计肥胖水平

目录 1. 作者介绍2&#xff0e;饮食习惯与身体状况数据集介绍3&#xff0e;实验步骤3.1 数据分析3.2 可视化处理数据3.3 导入线性回归模型进行训练3.4 预测结果3.5 完整代码3.5.1 数据分析3.5.2 模型评估 参考文献 1. 作者介绍 刘欢&#xff0c;女&#xff0c;西安工程大学电子…