2017-03-23 23 views
2

我使用改造爲REST客戶端,並得到如下回應:定製改裝轉換器

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{"Response":{"Status":"success","Response........... </string> 

我怎樣才能讓改造開始解析對象xml標籤如果可能的話後,如果沒有,是否有其他解?

回答

1

您必須編寫自定義Converter

事情是這樣的:

new Retrofit.Builder() 
    .baseUrl(...) 
    .addCallAdapterFactory(...) 
    .addConverterFactory(new Converter.Factory() { 
     @Override 
     public Converter<ResponseBody, YourModel> responseBodyConverter(final Type type, 
                     final Annotation[] annotations, final Retrofit retrofit) { 
      return new Converter<ResponseBody, YourModel>() { 
       @Override 
       public YourModel convert(final ResponseBody value) throws IOException { 
        String responseString = value.string(); 
        int startIndex = responseString.indexOf(">"); 
        ++startIndex; 
        int endIndex = responseString.indexOf("<", 1); 
        String jsonResponse = responseString.substring(startIndex, endIndex); 
        YourModel yourModel = new Gson().fromJson(jsonResponse, YourModel.class); 
        return yourModel; 
       } 
      }; 
     } 
    }) 
    .build() 
    .create(...); 

注意,這只是一個草圖,它可能無法正常工作,我沒有測試它。讓我知道我是否應該編輯它。

+0

這是尋找偉大我的需要但我需要這是通用的... –

+1

@Jesus Dimrix,現在你明白了。您可以自行實施的解析邏輯。 – azizbekian

2

這很簡單。據我所知,改造不提供轉換器鏈,但你仍然可以換多個轉換器:

final class XmlWrappedConverterFactory 
     extends Converter.Factory { 

    // This is the converter factory the deserialization will be delegated to 
    private final Converter.Factory backingConverterFactory; 

    private XmlWrappedConverterFactory(final Converter.Factory backingConverterFactory) { 
     this.backingConverterFactory = backingConverterFactory; 
    } 

    static Converter.Factory create(final Converter.Factory backingConverterFactory) { 
     return new XmlWrappedConverterFactory(backingConverterFactory); 
    } 

    @Override 
    public Converter<ResponseBody, ?> responseBodyConverter(final Type type, final Annotation[] annotations, final Retrofit retrofit) { 
     final Converter<ResponseBody, ?> responseBodyConverter = backingConverterFactory.responseBodyConverter(type, annotations, retrofit); 
     return new XmlWrappedResponseBodyConverter(responseBodyConverter); 
    } 

    private static final class XmlWrappedResponseBodyConverter 
      implements Converter<ResponseBody, Object> { 

     private final Converter<ResponseBody, ?> responseBodyConverter; 

     private XmlWrappedResponseBodyConverter(final Converter<ResponseBody, ?> responseBodyConverter) { 
      this.responseBodyConverter = responseBodyConverter; 
     } 

     @Override 
     public Object convert(final ResponseBody responseBody) 
       throws IOException { 
      // Note the response is not converted to string in order to save memory and work in streaming fashion 
      // So just fast-forward until '>' is found -- let's pretend it's an XML pretty much then 
      fastForward(responseBody.charStream(), '>'); 
      // GsonConverterFactory uses charStream() as well, at this step the stream will be "fast-forwarded" 
      return responseBodyConverter.convert(responseBody); 
      // However, the GsonConverterFactory closes the charStream() so wer're unable to read it until the end -- not that bad in fact 
     } 

     private static void fastForward(final Reader reader, final char ch) 
       throws IOException { 
      // Just read until the given character is found or EOF 
      int read; 
      while ((read = reader.read()) != ch && read != -1) { 
      } 
     } 

    } 

} 

然後建立一個Retrofit實例很簡單:

final Retrofit retrofit = new Builder() 
     ... 
     .addConverterFactory(XmlWrappedConverterFactory.create(GsonConverterFactory.create())) 
     .build();