通过Java操作IPFS实现上传与下载
2022-12-29 本文已影响0人
攻城老狮
本文介绍IPFS的环境搭建,并通过Java作为客户端完成对文件上传和下载功能。
环境信息如下:
系统:Mac M1
IPFS版本:go-ipfs_v0.10.0_darwin-arm64.tar.gz
构建:采用SpringBoot构建项目
1 IPFS环境搭建
- 下载IPFS
# go-ipfs
IPFS官网:https://dist.ipfs.io/
- 解压并启动IPFS服务
# 1.解压IPFS服务
tar -zxvf go-ipfs_v0.10.0_darwin-arm64.tar.gz
cd go-ipfs
# 2.设置ipfs命令到全局路径PATH中(可选)
# 3.初始化IPFS服务
ipfs init
# 4.解决跨域问题
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"]'
# 5.启动ipfs服务
ipfs daemon
# 6.访问IPFS的web网址,看到网站内容说明IPFS服务搭建成功,可以在设置中对IPFS默认配置做进一步修改
http://127.0.0.1:5001/webui
image-20221229150423457.png
# 6.若与本地服务端口发生冲突,可以在IPFS的配置中对端口进行重新指定
image-20221229150550523.png
构建Java操作环境
- 引入IPFS所需依赖
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<!--ps:此处一定要下载最新版本的client:v1.3.3,旧版本client采用GET的方式发送HTTP请求,会导致在新的IPFS服务连接出现405报错-->
<dependencies>
<dependency>
<groupId>com.github.ipfs</groupId>
<artifactId>java-ipfs-http-client</artifactId>
<version>v1.3.3</version>
</dependency>
</dependencies>
- 在 yaml 文件中给出连接的ip和port,与具体应用解耦,当然简单使用也可以直接硬编码到程序中
ipfs:
config:
multi-addr: /ip4/127.0.0.1/tcp/5001 # ipfs的服务器地址和端口
- 给出操作IPFS服务的接口
import java.io.IOException;
public interface IpfsService {
/**
* 指定path+文件名称,上传至ipfs
*
* @param filePath
* @return
* @throws IOException
*/
String uploadToIpfs(String filePath) throws IOException;
/**
* 将byte格式的数据,上传至ipfs
*
* @param data
* @return
* @throws IOException
*/
String uploadToIpfs(byte[] data) throws IOException;
/**
* 根据Hash值,从ipfs下载内容,返回byte数据格式
*
* @param hash
* @return
*/
byte[] downFromIpfs(String hash);
/**
* 根据Hash值,从ipfs下载内容,并写入指定文件destFilePath
*
* @param hash
* @param destFilePath
*/
void downFromIpfs(String hash, String destFilePath);
}
- 给出对IPFS操作的具体实现类
@Service
public class IpfsServiceImpl implements IpfsService {
// ipfs 的服务器地址和端口,与yaml文件中的配置对应
@Value("${ipfs.config.multi-addr}")
private String multiAddr;
private IPFS ipfs;
@PostConstruct
public void setMultiAddr() {
ipfs = new IPFS(multiAddr);
}
@Override
public String uploadToIpfs(String filePath) throws IOException {
NamedStreamable.FileWrapper file = new NamedStreamable.FileWrapper(new File(filePath));
MerkleNode addResult = ipfs.add(file).get(0);
return addResult.hash.toString();
}
@Override
public String uploadToIpfs(byte[] data) throws IOException {
NamedStreamable.ByteArrayWrapper file = new NamedStreamable.ByteArrayWrapper(data);
MerkleNode addResult = ipfs.add(file).get(0);
return addResult.hash.toString();
}
@Override
public byte[] downFromIpfs(String hash) {
byte[] data = null;
try {
data = ipfs.cat(Multihash.fromBase58(hash));
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
@Override
public void downFromIpfs(String hash, String destFile) {
byte[] data = null;
try {
data = ipfs.cat(Multihash.fromBase58(hash));
} catch (IOException e) {
e.printStackTrace();
}
if (data != null && data.length > 0) {
File file = new File(destFile);
if (file.exists()) {
file.delete();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write(data);
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 编写一个测试用例
@RunWith(SpringRunner.class)
@SpringBootTest
public class IpfsServiceTest {
@Autowired
private IpfsService ipfsService;
// 上传
@Test
public void uploadIpfs() throws IOException {
byte[] data = "hello world".getBytes();
String hash = ipfsService.uploadToIpfs(data);
// Qmf412jQZiuVUtdgnB36FXFX7xg5V6KEbSJ4dpQuhkLyfD
System.out.println(hash);
}
// 下载
@Test
public void downloadIpfs() {
String hash = "Qmf412jQZiuVUtdgnB36FXFX7xg5V6KEbSJ4dpQuhkLyfD";
byte[] data = ipfsService.downFromIpfs(hash);
System.out.println(new String(data));
}
}