Reputation: 1365
I am doing android, looking for a way to do a super basic http GET/POST request. I keep getting an error:
java.lang.IllegalArgumentException: Unable to create converter for class java.lang.String
Webservice:
public interface WebService {
@GET("/projects")
Call<String> jquery();
}
then in my java:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://jquery.org")
// .addConverterFactory(GsonConverterFactory.create())
.build();
WebService service = retrofit.create(WebService.class);
Call<String> signin = service.jquery();
Toast.makeText(this, signin.toString(), Toast.LENGTH_LONG).show();
I'm literally just trying to query jquery.org/projects with a GET request and return the String that it responds with. What is wrong?
If I try to implement a custom Converter (I've found a few examples online) it complains that I didn't implement the abstract method convert(F), which none of the examples do.
Thanks.
Upvotes: 68
Views: 86848
Reputation: 1649
Add Retrofit2 and ScalarsConverterFactory to your Retrofit.Builder.
adapterBuilder = new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create());
To use ScalarsCoverter add following dependency to your build graddle
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0' //Adding Retrofit2
For API Call use:
Call <String> *****
Android Code :
.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
Log.i("Response", response.body().toString());
//Toast.makeText()
if (response.isSuccessful()){
if (response.body() != null){
Log.i("onSuccess", response.body().toString());
}else{
Log.i("onEmptyResponse", "Returned empty response");//Toast.makeText(getContext(),"Nothing returned",Toast.LENGTH_LONG).show();
}
}
Upvotes: 118
Reputation: 881
I change the Response type, instead of adding ScalarsConverterFactory like this
interface YourApiService {
@GET("/endpoint")
fun getResponse(): Call<ResponseBody>
}
And then you can get the string object by
val str = response.body().toString()
Upvotes: 1
Reputation: 1587
thought it might be late to answer just use response.body()?.string()
and you'll have your response as a string.
Upvotes: 1
Reputation: 4857
Just use log level BODY
in intercepror:
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()....
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
clientBuilder.addNetworkInterceptor(httpLoggingInterceptor);
And you can see body in logcat like:
D/OkHttp: {"blablabla":1,.... }
D/OkHttp: <-- END HTTP (1756-byte body)
This solution for debug only, not for get String directly in code.
Upvotes: 2
Reputation: 1564
String body = new String(((TypedByteArray) response.getBody()).getBytes());
if you found
java.lang.ClassCastException: retrofit.client.UrlConnectionClient$TypedInputStream cannot be cast to retrofit.mime.TypedByteArray
then put this in your RestAdapter
.setLogLevel(RestAdapter.LogLevel.FULL)
for Example:
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(Root_url)
.build();
Upvotes: -1
Reputation: 4644
call.enqueue(new Callback<Object>() {
@Override
public void onResponse(@NonNull Call<Object> call, @NonNull Response<Object> response) {
if (response.isSuccessful()) {
Gson gson = new Gson();
String successResponse = gson.toJson(response.body());
Log.d(LOG_TAG, "successResponse: " + successResponse);
} else {
try {
if (null != response.errorBody()) {
String errorResponse = response.errorBody().string();
Log.d(LOG_TAG, "errorResponse: " + errorResponse);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
public void onFailure(@NonNull Call<Object> call, @NonNull Throwable t) {
}
});
Upvotes: 5
Reputation: 2154
To get the response as a String, you have to write a converter and pass it when initializing Retrofit
.
Here are the steps.
Initializing retrofit.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL_BASE)
.addConverterFactory(new ToStringConverterFactory())
.build();
return retrofit.create(serviceClass);
Converter class for converting Retrofit's ResponseBody
to String
public class ToStringConverterFactory extends Converter.Factory {
private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
if (String.class.equals(type)) {
return new Converter<ResponseBody, String>() {
@Override
public String convert(ResponseBody value) throws IOException
{
return value.string();
}
};
}
return null;
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations,
Annotation[] methodAnnotations, Retrofit retrofit) {
if (String.class.equals(type)) {
return new Converter<String, RequestBody>() {
@Override
public RequestBody convert(String value) throws IOException {
return RequestBody.create(MEDIA_TYPE, value);
}
};
}
return null;
}
}
And after executing service.jquery();
, signin
will contain JSON response.
Upvotes: 16
Reputation: 24114
You can try the following:
build.gradle file:
dependencies {
...
compile 'com.squareup.retrofit2:retrofit:2.0.1'
...
}
WebAPIService:
@GET("/api/values")
Call<String> getValues();
Activity file:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_URL_BASE)
.build();
WebAPIService service = retrofit.create(WebAPIService.class);
Call<String> stringCall = service.getValues();
stringCall.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
Log.i(LOG_TAG, response.body());
}
@Override
public void onFailure(Call<String> call, Throwable t) {
Log.e(LOG_TAG, t.getMessage());
}
});
I have tested with my Web serivce (ASP.Net WebAPI):
public class ValuesController : ApiController
{
public string Get()
{
return "value1";
}
}
Android Logcat out: 04-11 15:17:05.316 23097-23097/com.example.multipartretrofit I/AsyncRetrofit2: value1
Hope it helps!
Upvotes: 6
Reputation: 3654
I take a look at Retrofit library and noticed that it parses response according to the type class inside Call<T>
. So you have two option:
1st: create a class according to the response from the server.
2nd: get the response and handle it yourself (Not recommended Retrofit already handles it. So why do you use Retrofit as it is tailored for this job). Anyway instead of Call<String>
use Call<ResponseBody>
and Call<ResponseBody> signin = service.jquery();
after this put the following
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response, Retrofit retrofit) {
// handle success
String result = response.body().string();
}
@Override
public void onFailure(Throwable t) {
// handle failure
}
});
Upvotes: 22