簡體   English   中英

如何在Android中解析以換行符分隔的Json響應?

[英]How to parse newline delimited Json response in Android?

NdJson數據樣本:

{"type":"data","id":"xyz"}
{"type":"value","id":"xcf"}
....
....

這是我的RetrofitRxJava代碼,適用於以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
}

api類

public interface WarehouseAPI {
  @GET("/search?limit=1")
  public Observable<APIData> getdata ();
}

而更換我正的錯誤@GET("/search?limit=1")@GET("/search")Malformed JSON: Syntax error

如何正確解析NdJson

有什么方法可以將響應存儲在List<APIData>

編輯-1

現在,我試圖在觀察者中接受通用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>>)

編輯-2

但是,我犯了一些愚蠢的錯誤,並且在“ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM