[英]Retrofit 2 in Android results in Java.io.EOFException when querying items from MongoDB database by Node.js
I have been having trouble trying to query multiple MongoDB documents in form of an JSONArray from mLab at once using Retrofit 2 in an Android project. 我在尝试使用Android项目中的Retrofit 2一次从mLab以JSONArray形式查询多个MongoDB文档时遇到了麻烦。 The documents I'm trying to query have the have the same value in one of their fields, so I used the db.collection.find() method in my Node.js API.
我尝试查询的文档在它们的一个字段中具有相同的值,因此我在Node.js API中使用了db.collection.find()方法。 Here is the android app code.
这是android应用程序代码。
productSubscription.add(ProductNetworkUtil
.getProductRetrofit(myToken).getProductByCategory("Hardware")
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(this::handleProductListResponse,this::handleProductError));
private void handleProductResponse(Product product)
{
String itemName = product.getItemName();
Snackbar.make(findViewById(R.id.content_home_screen), itemName, Snackbar.LENGTH_LONG).show();
int stop = 0;
}
private void handleProductListResponse(JSONArray productList)
{
Snackbar.make(findViewById(R.id.content_home_screen),"Hardware list received",Snackbar.LENGTH_SHORT).show();
int stop = 0;
}
private void handleProductError(Throwable error)
{
if(error instanceof HttpException)
{
Gson gson = new GsonBuilder().create();
try
{
String errorBody = ((HttpException)error).response().errorBody().string();
Response response = gson.fromJson(errorBody,Response.class);
Snackbar.make(findViewById(R.id.content_home_screen),response.getMessage(),Snackbar.LENGTH_SHORT).show();
}
catch (IOException e)
{
e.printStackTrace();
}
}
else
{
Snackbar.make(findViewById(R.id.content_home_screen),"Network Error!",Snackbar.LENGTH_SHORT).show();
}
}
Here is the ProductNetworkUtil class used in the previous snippet, 这是上一片段中使用的ProductNetworkUtil类,
public class ProductNetworkUtil {
public static Retrofit2ProductInterface getProductRetrofit(String token) {
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(chain -> {
Request original = chain.request();
Request.Builder builder = original.newBuilder()
.addHeader("x-access-token", token)
.method(original.method(),original.body());
return chain.proceed(builder.build());
});
RxJavaCallAdapterFactory rxAdapter = RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io());
return new Retrofit.Builder()
.baseUrl(NewLoginConstants.PRODUCT_FETCHER_URL)
.client(httpClient.build())
.addCallAdapterFactory(rxAdapter)
.addConverterFactory(GsonConverterFactory.create())
.build().create(Retrofit2ProductInterface.class);
}}
Here is the Interface class I have been using: 这是我一直在使用的Interface类:
enter cpublic interface Retrofit2ProductInterface {
@GET("products/{itemName}")
Observable<Product> getProduct(@Path("itemName") String itemName);
@GET("products/{category}")
Observable<JSONArray> getProductByCategory(@Header("category") String category);}
If I were to use the query method using the itemName field as the parameter, I can query successfully since inside the database the itemName for each document is unique. 如果要使用使用itemName字段作为参数的查询方法,我可以成功查询,因为在数据库内部,每个文档的itemName是唯一的。 However, the getProductByCategory method results in Java.io.EOFException: End of input at line 1 column 1 path $ in the debugger.
但是,getProductByCategory方法导致Java.io.EOFException:调试器中第1行第1列路径$的输入结束。 I have searched for some answers and some say this is due to the app receiving empty data.
我已经搜索了一些答案,有人说这是由于该应用接收到空数据。 So I tried to change the node.js code as well.
因此,我也尝试更改node.js代码。
exports.getProductByCategory = category =>
new Promise ((resolve,reject) => {
var productList = product.find({ category: category }, {
_id: 1,
QRCode: 1,
owner: 1,
itemName: 1,
salePrice: 1,
price: 1,
sku: 1,
webCode: 1,
summary: 1,
description: 1,
inTheBox: 1,
warranty: 1,
category: 1,
mainImg: 1,
otherImgs: 1
}).toArray();
product.resolve({productList, message: 'Got your list!'})
.catch(err => reject({ status: 500, message: 'Internal Server Error !' }))
});
Here is the related code from the routes.js of the node.js API 这是来自node.js API的routes.js的相关代码
'use strict';
const detail = require('./functions/detail'); const detail = require('./ functions / detail'); const config = require('./config/config.json');
const config = require('./ config / config.json');
module.exports = router => { module.exports =路由器=> {
router.get('/', (req, res) => res.end('This is the product node!'));
router.get('/products/:id', (req,res) => {
detail.getProduct(req.params.id)
.then(result => res.json(result))
.catch(err => res.status(err.status).json({ message: err.message }));
});
router.get('/products/:category', (req,res) => {
detail.getProductByCategory(req.params.category)
.then(result => res.json(result))
.catch(err => res.status(err.status).json({message: err.message}));
});
} }
I am not sure if the node.js API has some fundamental coding error, or it is the android query method that is the issue. 我不确定node.js API是否存在一些基本的编码错误,或者是问题所在的android查询方法。
I cannot say anything because I would need more info and check it by myself (your response data). 我什么也不能说,因为我需要更多信息并亲自检查(您的响应数据)。
Did you try to debug / log and check what is the response content? 您是否尝试调试/记录并检查响应内容是什么? It looks that it's wrong.
看来这是错误的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.