Trang bị thêm và NHẬN sử dụng các thông số


92

Tôi đang cố gắng gửi yêu cầu tới API Google GeoCode bằng Retrofit. Giao diện dịch vụ trông như thế này:

public interface FooService {    
    @GET("/maps/api/geocode/json?address={zipcode}&sensor=false")
    void getPositionByZip(@Path("zipcode") int zipcode, Callback<String> cb);
}

Khi tôi gọi dịch vụ:

OkHttpClient okHttpClient = new OkHttpClient();

RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(Constants.GOOGLE_GEOCODE_URL).setClient(new OkClient(okHttpClient)).build();

FooService service = restAdapter.create(FooService.class);

service.getPositionByZip(zipCode, new Callback<String>() {
    @Override public void success(String jsonResponse, Response response) {
       ...
    }
@Override public void failure(RetrofitError retrofitError) {
    }
});

Tôi nhận được stacktrace sau:

06-07 13:18:55.337: E/AndroidRuntime(3756): FATAL EXCEPTION: Retrofit-Idle
06-07 13:18:55.337: E/AndroidRuntime(3756): Process: com.marketplacehomes, PID: 3756
06-07 13:18:55.337: E/AndroidRuntime(3756): java.lang.IllegalArgumentException: FooService.getPositionByZip: URL query string "address={zipcode}&sensor=false" must not have replace block.
06-07 13:18:55.337: E/AndroidRuntime(3756):     at retrofit.RestMethodInfo.methodError(RestMethodInfo.java:120)
06-07 13:18:55.337: E/AndroidRuntime(3756):     at retrofit.RestMethodInfo.parsePath(RestMethodInfo.java:216)
06-07 13:18:55.337: E/AndroidRuntime(3756):     at retrofit.RestMethodInfo.parseMethodAnnotations(RestMethodInfo.java:162)
06-07 13:18:55.337: E/AndroidRuntime(3756):     at 

Tôi đã xem qua câu hỏi StackOverflow: Trang bị thêm: nhiều tham số truy vấn trong lệnh @GET? nhưng nó dường như không áp dụng được.

Tôi đã lấy nguyên văn mã từ đây: http://square.github.io/retrofit/ vì vậy tôi hơi mất hứng để hiểu vấn đề.

Suy nghĩ?

Câu trả lời:


154

AFAIK, {...}chỉ có thể được sử dụng làm đường dẫn, không phải bên trong tham số truy vấn. Hãy thử cái này thay thế:

public interface FooService {    

    @GET("/maps/api/geocode/json?sensor=false")
    void getPositionByZip(@Query("address") String address, Callback<String> cb);
}

Nếu bạn có một số lượng tham số không xác định để truyền, bạn có thể sử dụng làm như sau:

public interface FooService {    

    @GET("/maps/api/geocode/json")
    @FormUrlEncoded
    void getPositionByZip(@FieldMap Map<String, String> params, Callback<String> cb);
}

Làm cách nào để thêm nhiều tham số Truy vấn
Gilberto Ibarra

2
@GilbertoIbarra lỗi, bằng cách thêm vào:void getPositionByZip(@Query("address") String address, @Query("number") String number, Callback<String> cb);
Bart Kiers

9
FormUrlEncoded chỉ có thể được chỉ định trên các phương thức HTTP có nội dung yêu cầu (ví dụ: @POST)
jiashie

8
Câu trả lời sai ở đây, @FormUrlEncoded không thể sử dụng với GET
mr.icetea

1
@FormUrlEncodedkhông hoạt động với @GETchú thích
Black_Zerg

40

@QueryMap đã làm việc cho tôi thay vì FieldMap

Nếu bạn có nhiều tham số GET, một cách khác để chuyển chúng vào url của bạn là a HashMap.

class YourActivity extends Activity {

private static final String BASEPATH = "http://www.example.com";

private interface API {
    @GET("/thing")
    void getMyThing(@QueryMap Map<String, String> params, new Callback<String> callback);
}

public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.your_layout);

   RestAdapter rest = new RestAdapter.Builder().setEndpoint(BASEPATH).build();
   API service = rest.create(API.class);

   Map<String, String> params = new HashMap<String, String>();
   params.put("key1", "val1");
   params.put("key2", "val2");
   // ... as much as you need.

   service.getMyThing(params, new Callback<String>() {
       // ... do some stuff here.
   });
}
}

URL được gọi sẽ là http://www.example.com/thing/?key1=val1&key2=val2


4

Tôi cũng muốn làm rõ rằng nếu bạn có các tham số url phức tạp để xây dựng, bạn sẽ cần phải xây dựng chúng theo cách thủ công. tức là nếu truy vấn của bạn example.com/?latlng=-37,147, thay vì cung cấp các giá trị lat và lng riêng lẻ, bạn sẽ cần phải xây dựng chuỗi latlng bên ngoài, sau đó cung cấp nó dưới dạng một tham số, tức là:

public interface LocationService {    
    @GET("/example/")
    void getLocation(@Query(value="latlng", encoded=true) String latlng);
}

Lưu ý encoded=truelà cần thiết, nếu không việc trang bị thêm sẽ mã hóa dấu phẩy trong tham số chuỗi. Sử dụng:

String latlng = location.getLatitude() + "," + location.getLongitude();
service.getLocation(latlng);

1

Hoàn thành ví dụ làm việc trong Kotlin , tôi đã thay thế các khóa API của mình bằng 1111 ...

        val apiService = API.getInstance().retrofit.create(MyApiEndpointInterface::class.java)
        val params = HashMap<String, String>()
        params["q"] =  "munich,de"
        params["APPID"] = "11111111111111111"

        val call = apiService.getWeather(params)

        call.enqueue(object : Callback<WeatherResponse> {
            override fun onFailure(call: Call<WeatherResponse>?, t: Throwable?) {
                Log.e("Error:::","Error "+t!!.message)
            }

            override fun onResponse(call: Call<WeatherResponse>?, response: Response<WeatherResponse>?) {
                if (response != null && response.isSuccessful && response.body() != null) {
                    Log.e("SUCCESS:::","Response "+ response.body()!!.main.temp)

                    temperature.setText(""+ response.body()!!.main.temp)

                }
            }

        })

1
Bạn có thể đặt định nghĩa phương thức getWeather (params) cho rõ ràng hơn không?
supro_96 Ngày
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.