import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSDownloadStream;
import com.mongodb.client.gridfs.model.GridFSFile;
import org.apache.commons.io.IOUtils;
import org.bson.types.ObjectId;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.gridfs.GridFsResource;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
@SpringBootTest
@RunWith(SpringRunner.class)
public class GridFsTest {
@Autowired
private GridFsTemplate gridFsTemplate;
@Autowired
private GridFSBucket gridFSBucket;
//取文件
@Test
public void queryFile() throws IOException {
//根据文件id查询文件
GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is("5ec8cea13cc2be46e01a0e65")));
//打开一个下载流对象
GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
//创建GridFsResource对象,获取流
GridFsResource gridFsResource = new GridFsResource(gridFSFile,gridFSDownloadStream);
//从流中取数据
String content = IOUtils.toString(gridFsResource.getInputStream(), "utf-8");
System.out.println(content);
}
}
这里报错: GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is("5ec8cea13cc2be46e01a0e65")));
报错提示:org.bson.BsonInvalidOperationException: Value expected to be of type DOCUMENT is of unexpected type STRING
这是说你的传入类型是string,而_id不是这个类型?mongo的id是一种叫ObjectId的类型。。。
看你引入了ObjectId这个类型,那么其实应该是
GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(new ObjectId("5ec8cea13cc2be46e01a0e65"))));
你可以试试。。
@顾晓北: 刚刚试了,还是报同样的错误,很奇怪。
上面的代码很简单可以运行,但是就是报这个错误。。。
@萌闪闪: 一般的mongo查询是这样的
gridFsTemplate.findOne({
_id: ObjectId('5ec8cea13cc2be46e01a0e65'),
});
你看看类型吧,还真没见过你这种查法。
你的
Criteria.where("_id").is(new ObjectId("5ec8cea13cc2be46e01a0e65"))
返回的是什么?
@顾晓北: 直接就报错了。
http://www.manongjc.com/article/30628.html
https://blog.csdn.net/weixin_30859423/article/details/99802762
上面都有相同写法,我这跑就报错了。。
@顾晓北:
Criteria.where("_id").is(objectId),返回的是一个Criteria对象,
Query.query(Criteria.where("_id").is(objectId)),一直到这里都是好的。
进入gridFsTemplate.findOne()方法后就报错了。
我刚才又运行了下
我又查看了GridFsTemplate.java这个类的源码。
下面是其中findOne方法的源码
/*
* (non-Javadoc)
* @see org.springframework.data.mongodb.gridfs.GridFsOperations#findOne(com.mongodb.Document)
*/
public GridFSFile findOne(Query query) {
return find(query).first();
}
然后我进而查看.first()这个方法,发现源码中是这么写的 TResult first();
也就是说返回类型是一个TResult,
而源码中关于TResult类型的解释如下
/**
*The MongoIterable is the results from an operation, such as a query.
*
所以,我估计是这里的问题!!!
果然写成下面这样:
GridFSFindIterable gridFSFiles = gridFsTemplate.find(Query.query(Criteria.where("_id").is(objectId)));
GridFSFile fsFile = gridFSFiles.first();
gridFSFiles.first()的时候报错了。
真心不知道咋改。。
大侠,我终于找到问题原因了,
不是java代码问题,而实mongodb中存的数据问题
@萌闪闪: 哦?
@顾晓北: 嗯