![](/img/trans.png)
[英]How to parse regular (not newline delimited) json with Apache Beam and Jackson?
[英]How to parse newline delimited Json response in Android?
NdJson
數據樣本:
{"type":"data","id":"xyz"}
{"type":"value","id":"xcf"}
....
....
這是我的Retrofit
和RxJava
代碼,適用於以limit=1
即{"type":"data","id":"xyz"}
來獲取數據。
adapter.create(API.class).getData()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<APIData>() {
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {}
@Override
public void onNext(APIData apidata) {}
});
模型類只有兩個參數:
public class APIData(){
private String type;
private String id;
..// Getter and setter for above two fields
}
public interface WarehouseAPI {
@GET("/search?limit=1")
public Observable<APIData> getdata ();
}
而更換我正的錯誤@GET("/search?limit=1")
與@GET("/search")
是Malformed JSON: Syntax error
。
如何正確解析NdJson
?
有什么方法可以將響應存儲在List<APIData>
現在,我試圖在觀察者中接受通用Response
:
adapter.create(APIData.class).getdata()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Response>() {
@Override
public void onCompleted() {}
@Override
public void onNext(Response response) {}
});
但是no suitable method found for subscribe(<anonymous Observer<Response>>)
但是,我犯了一些愚蠢的錯誤,並且在“ Edit-1”部分中得到的錯誤現在已修復。 現在我得到
Error:retrofit.RetrofitError: com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 2 column 2 path $
我假設服務器響應具有以下格式
{"type":"data","id":"xyz"}\n{"type":"data","id":"xyz"}
基本思想是從服務器接收響應作為字符串。 將其拆分為類似於response.split("\\n")
數組。 遍歷數組,為每個數組元素創建一個新的json對象。
我確實意識到,正如您在評論中所描述的那樣,這非常耗時。 您也可以嘗試使用String replaceAll
方法將每一行轉換成一個數組元素並解析整個字符串。 喜歡
String myResponse = "[" + response.replaceAll("/\n/", ",") + "]";
Gson gson = new Gson();
MyEntity[] arr = gson.fromJson(myResponse, MyEntity[].class);
如果進行改裝。 您將必須使用自定義響應轉換器。 因為您已經找到了使用自定義Converter來完成該問題的方法,所以我不會寫出完整的解決方案。
為了使工作正常,我必須通過Retrofit.Converter
添加Custom converter
工具:
public class CustomConverter implements Converter {
@Override
public Object fromBody(TypedInput body, Type type) throws ConversionException {
String text = null;
try {
text = fromStream(body.in());
} catch (IOException e) {
e.printStackTrace();
}
return text;
}
@Override
public TypedOutput toBody(Object object) {
return null;
}
// Custom method to convert stream from request to string
public static String fromStream(InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String newLine = System.getProperty("\n");
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append(newLine);
}
return out.toString();
}
}
而且效果很好!
對於初學者,您的json並不是Gson可以理解的json,因此您不能直接在Retrofit中使用Gson轉換器。 所以
public Observable<APIData> getdata ();
一定是
public Observable<Response> getdata ();
那你有
adapter.create(WarehouseAPI.class).getdata()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.map((Response res) -> new BufferedStreamReader(res.body.body().bytesStream()))
.flatMap(stream -> {
return Observable.create(subscriber -> {
String line;
while((line = stream.readLine() != null) {
subscriber.onNext(gson.fromJson(line, APIData.class));
}
subscriber.onCompleted();
});
});
您可以訂閱它,並接收json列表中的每個項目。
這未經測試,錯誤情況也未得到處理(為簡短起見,未測試訂閱的有效性)。
不過,它基本上應該朝着正確的方向發展。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.