D. Ace D. Ace - 5 months ago 63
Android Question

Retrofit 2.0 is returning an incorrect URL

I'm trying to build my URL using Retrofit 2.0. The problem is it's returning this URL:

http://query.yahooapis.com/v1/public/yql?&q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22YHOO%22)&format=json%26diagnostics%3Dtrue%26env%3Dstore%253A%252F%252Fdatatables.org%252Falltableswithkeys%26callback%3D


I want it to return this URL instead:

https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22YHOO%22)&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=


Can anyone please advise how do I fix this?

Here is the code that returns the URL:

Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();

mQuoteAdapter = new QuoteAdapter(items);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.question_list);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(mQuoteAdapter);

StockApiServiceInterface stockApiServiceInterface = retrofit.create(StockApiServiceInterface.class);

stockApiServiceInterface.listQuotes(
"select * from yahoo.finance.quotes where symbol in (\"YHOO\")",
"json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=")
.enqueue(new Callback<ResultWrapper>() {
@Override
public void onResponse(Response<ResultWrapper> response) {
response.body().getQuery().getResults().getQuote().getAsk();
}

@Override
public void onFailure(Throwable t) {
Log.e("listQuotes threw: ", t.getMessage());
}
});


Here is my StockApiService:

public final class StockApiService {

public interface StockApiServiceInterface {

@GET("v1/public/yql?")
Call<ResultWrapper> listQuotes(
@Query("q") String query,
@Query("format") String env
);
}
}

Answer

Slight change from Ian that simplifies it a little:

public final class StockApiService {
  public interface StockApiServiceInterface {
    @GET("v1/public/yql?format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys")
    Call<ResultWrapper> listQuotes(
        @Query("q") String query,
        @Query("diagnostics") boolean diagostics
    );
  }
}

Unchanging query strings parameters can be included in the method annotation and retrofit should merge them together. Also, I removed the callback parameter because that is a thing for websites called JSONP and isn't relevant to an Android app.

The actual problem you have is that you are giving Retrofit a precomposed partial query string and asking it to encode it for you. Retrofit doesn't know that it's a precomposed query string, so it does what it's supposed to: treats it as the value of a query string parameter and URL encodes it. @Ian is absolutely right that you need to split them up.