首页 新闻 会员 周边

使用GridFsTemplate,根据文件_id读取文件,报类型错误,找不到原因

0
悬赏园豆:5 [待解决问题]

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

萌闪闪的主页 萌闪闪 | 初学一级 | 园豆:197
提问于:2020-05-24 12:34
< >
分享
所有回答(1)
0

这是说你的传入类型是string,而_id不是这个类型?mongo的id是一种叫ObjectId的类型。。。

顾晓北 | 园豆:10844 (专家六级) | 2020-05-24 14:34

看你引入了ObjectId这个类型,那么其实应该是

GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(new ObjectId("5ec8cea13cc2be46e01a0e65"))));

你可以试试。。

支持(0) 反对(0) 顾晓北 | 园豆:10844 (专家六级) | 2020-05-24 14:36

@顾晓北: 刚刚试了,还是报同样的错误,很奇怪。
上面的代码很简单可以运行,但是就是报这个错误。。。

支持(0) 反对(0) 萌闪闪 | 园豆:197 (初学一级) | 2020-05-24 16:44

@萌闪闪: 一般的mongo查询是这样的

gridFsTemplate.findOne({
  _id: ObjectId('5ec8cea13cc2be46e01a0e65'),
});

你看看类型吧,还真没见过你这种查法。
你的

Criteria.where("_id").is(new ObjectId("5ec8cea13cc2be46e01a0e65"))

返回的是什么?

支持(0) 反对(0) 顾晓北 | 园豆:10844 (专家六级) | 2020-05-24 16:53

@顾晓北: 直接就报错了。
http://www.manongjc.com/article/30628.html
https://blog.csdn.net/weixin_30859423/article/details/99802762
上面都有相同写法,我这跑就报错了。。

支持(0) 反对(0) 萌闪闪 | 园豆:197 (初学一级) | 2020-05-24 16:55

@顾晓北:
Criteria.where("_id").is(objectId),返回的是一个Criteria对象,
Query.query(Criteria.where("_id").is(objectId)),一直到这里都是好的。
进入gridFsTemplate.findOne()方法后就报错了。
我刚才又运行了下

支持(0) 反对(0) 萌闪闪 | 园豆:197 (初学一级) | 2020-05-24 17:08

我又查看了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.
*

  • @param <TResult> The type that this iterable will decode documents to.
  • @since 3.0
    */

所以,我估计是这里的问题!!!

支持(0) 反对(0) 萌闪闪 | 园豆:197 (初学一级) | 2020-05-24 17:14

果然写成下面这样:
GridFSFindIterable gridFSFiles = gridFsTemplate.find(Query.query(Criteria.where("_id").is(objectId)));
GridFSFile fsFile = gridFSFiles.first();

gridFSFiles.first()的时候报错了。
真心不知道咋改。。

支持(0) 反对(0) 萌闪闪 | 园豆:197 (初学一级) | 2020-05-24 17:19

大侠,我终于找到问题原因了,
不是java代码问题,而实mongodb中存的数据问题

支持(0) 反对(0) 萌闪闪 | 园豆:197 (初学一级) | 2020-05-24 17:29

@萌闪闪: 哦?

支持(0) 反对(0) 顾晓北 | 园豆:10844 (专家六级) | 2020-05-24 19:55

@顾晓北: 嗯

支持(0) 反对(0) 萌闪闪 | 园豆:197 (初学一级) | 2020-05-24 20:21
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册