2015-02-13 19 views
5

Hãy tưởng tượng theo yêu cầu sau:Serialize Query-Parameter trong Retrofit

@POST("/recipes/create") 
void createRecipe(@Query("recipe") Recipe recipe, Callback<String> callback); 

Tôi muốn có toJson (công thức) nhưng tiếc là yêu cầu của tôi chỉ đang kêu gọi toString() cho công thức của tôi mà không làm việc ở tất cả.

Tôi có thể ghi đè lên toString bên trong Công thức nhưng tôi muốn có giải pháp chung.

tôi không thể sử dụng @Body như tôi cần phải xác định, những gì tôi đang gửi (i cần phải có "công thức = json (theRecipe)".

Tôi cũng không thể thay đổi tuần tự để thêm "công thức =" như tôi không chịu trách nhiệm về các máy chủ.

tại thời điểm tôi đang sử dụng một bản đồ QueryMap nơi mà tôi đặt trong một đối tượng serialized. Mặc dù công trình này, nó không phải là một giải pháp rất tốt đẹp trong quan điểm của tôi.

Tôi có thể chặn bộ điều hợp trang bị thêm bằng cách nào đó không?

Trả lời

6

Tôi không nghĩ rằng nó hỗ trợ điều này ngay bây giờ theo một cách tốt đẹp. Kiểm tra câu trả lời này bởi một trong các tác giả: https://github.com/square/retrofit/issues/291

Phương pháp được đề xuất từ ​​câu trả lời đó là tạo kiểu tùy chỉnh ghi đè phương pháp toString(), vì Retrofit sử dụng nội bộ String.valueOf(value) để chuyển đổi tham số truy vấn hoặc đường dẫn thành chuỗi.

Vì vậy, bạn có thể có một cái gì đó như thế này:

class Recipe { 
    public int id; 
    public String title; 

    @Override 
    public String toString() { 
    // You can use a GSON serialization here if you want 
    // This is not a robust implementation 
    return Integer.toString(id) + "-" + title; 
    } 
} 
+0

Rõ ràng hỗ trợ đã được thêm từ đó. Xem [câu trả lời bên dưới] (http://stackoverflow.com/a/42459356/741217) –

0

Bạn có thể sử dụng r etrofit.RestAdapter.Builder(). setConverter (...) để chuyển một trình biến đổi json tùy chỉnh.

+1

Cảm ơn trả lời nhanh. Tôi đã đặt bộ chuyển đổi. Vấn đề là bộ chuyển đổi chỉ được sử dụng bên trong Thân máy @.Tôi cần serialization của mình trong @ Query – Frame91

3

Đây là bây giờ có thể khi đăng ký một tùy chỉnh Converter.Factory đó sẽ ghi đè các phương pháp stringConverter, được gọi là khi giải quyết các thông số. Các Github issue rằng @ William gọi 2 năm trước dường như không được cập nhật kể từ khi hỗ trợ được thêm vào.

Phương pháp Javadoc:

Trả về một chuyển đổi để chuyển đổi loại vào một String, hoặc null nếu loại không thể được xử lý bởi nhà máy này. Điều này được sử dụng để tạo trình chuyển đổi cho các loại được chỉ định bởi các giá trị @Field, @FieldMap, @Header, @HeaderMap, @Path, @Query và @QueryMap.

Ví dụ bên dưới đại biểu cho Gson, nhưng giống như bất kỳ loại chuyển đổi nào cũng có thể được áp dụng cho các tham số.

Ví dụ: GsonStringConverterFactory

class GsonStringConverterFactory 
    extends Converter.Factory { 

    private final transient Gson gson; 

    GsonStringConverterFactory(final Gson gson) { 

     this.gson = gson; 
    } 

    @Override 
    public Converter<?, String> stringConverter(final Type type, final Annotation[] annotations, final Retrofit retrofit) { 

     final TypeAdapter typeAdapter; 
     typeAdapter = gson.getAdapter(TypeToken.get(type)); 

     return new StringConverter<>(typeAdapter); 
    } 

    private static class StringConverter<T> 
      implements Converter<T, String> { 

     private final TypeAdapter<T> typeAdapter; 

     private StringConverter(final TypeAdapter<T> typeAdapter) { 

      this.typeAdapter = typeAdapter; 
     } 

     @Override 
     public String convert(final T value) 
       throws IOException { 

      /* This works in our case because parameters in this REST api are always some kind of scalar 
      * and the toJson method converts these to simple json types. */ 
      final String jsonValue; 
      jsonValue = typeAdapter.toJson(value)); 

      if (jsonValue.startsWith("\"") && jsonValue.endsWith("\"") { 
       /* Strip enclosing quotes for json String types */ 
       return jsonValue.substring(1, jsonValue.length() - 1); 
      } else { 
       return jsonValue; 
      } 
     } 
    } 
} 

Đăng ký chuyển đổi:

Để đăng ký chuyển đổi tùy chỉnh, xây dựng Retrofit của bạn có thể trông giống như thế này:

new Retrofit.Builder().baseUrl(BASE_URL) 
          .addConverterFactory(GsonConverterFactory.create(gson)) 
          .addConverterFactory(new GsonStringConverterFactory(gson)) 
          .build();