Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit with String response

I want a POST call on an URL, and as response I just get a String "ok" or "no".. So I have here my interface like this:

public interface registerAPI
{
    @FormUrlEncoded
    @POST("addDevice.php")
    Call<String> insertUser(
            @Field("name") String devicename,
            @Field("username") String regid);
}

So I just want to give the POST method the two parameters, and I want a back a String. In a PHP script on the server, there is something like this:

<?php
if(...)
   echo "ok";
else
   echo "no";

So I call on my Android-phone:

Retrofit adapter = new Retrofit.Builder()
                        .baseUrl("http://root.url.net/")
                        .addConverterFactory(GsonConverterFactory.create()) //I dont want this..
                        .build();

                registerAPI api = adapter.create(registerAPI.class);

                Call<String> call = api.insertUser(name,regid);
                call.enqueue(new Callback<String>()
                {
                    @Override
                    public void onResponse(Response<String> response, Retrofit retrofit)
                    {
                        Log.i("Error",response.message());
                    }

                    @Override
                    public void onFailure(Throwable t)
                    {
                        Log.d("Error", " Throwable is " +t.toString());

                    }
                });

So, when I run this, in Throwable, I get the following message:

Unable to create converter for class java.lang.String

Do I have to write my own converter just for a String-response? And how do I do that? Or is there a better way to do this?

Regards

like image 538
Klatschen Avatar asked Dec 09 '15 03:12

Klatschen


People also ask

How do you handle retrofit response in HTML?

For this, we will use the ResponseBody Object provided by the Retrofit only. When a response is received in the callback, we will extract the body of the response and convert it to a string by calling the string() method. Now we will Create a document from this string by passing it to Jsoup. parse()method.

Does retrofit use reflection?

Retrofit makes use of reflections to get the work done.


2 Answers

Ok the answer is to write an own converter. Like this:

public final class ToStringConverterFactory extends Converter.Factory {

            @Override
            public Converter<ResponseBody, ?> fromResponseBody(Type type, Annotation[] annotations) {
                //noinspection EqualsBetweenInconvertibleTypes
                if (String.class.equals(type)) {
                    return new Converter<ResponseBody, Object>() {

                        @Override
                        public Object convert(ResponseBody responseBody) throws IOException {
                            return responseBody.string();
                        }
                    };
                }

                return null;
            }

            @Override
            public Converter<?, RequestBody> toRequestBody(Type type, Annotation[] annotations) {
                //noinspection EqualsBetweenInconvertibleTypes
                if (String.class.equals(type)) {
                    return new Converter<String, RequestBody>() {

                        @Override
                        public RequestBody convert(String value) throws IOException {
                            return RequestBody.create(MediaType.parse("text/plain"), value);
                        }
                    };
                }

                return null;
            }
        }

You have to call it with this:

Retrofit adapter = new Retrofit.Builder()
                        .baseUrl("http://root.url.net/")
                        .addConverterFactory(new ToStringConverterFactory())
                        .build();

                registerAPI api = adapter.create(registerAPI.class);

                Call<String> call = api.insertUser(name,regid);

You get the response in this:

call.enqueue(new Callback<String>()
                {
                    @Override
                    public void onResponse(Response<String> response, Retrofit retrofit)
                    {
                        Log.i("http","innen: " + response.message());
                        Log.i("http","innen: " + response.body()); // here is your string!!
                    }

                    @Override
                    public void onFailure(Throwable t)
                    {
                        Log.d("http", " Throwable " +t.toString());

                    }
                });
like image 85
Klatschen Avatar answered Nov 14 '22 22:11

Klatschen


@Klatschen your answer is right,in Retrofit2 the abstarct function has changed.

public final class StringConverterFactory extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
    if (String.class.equals(type)) {
        return new Converter<ResponseBody, Object>() {
            @Override
            public Object convert(ResponseBody responseBody) throws IOException {
                return responseBody.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(MediaType.parse("text/plain"), value);
            }
        };
    }
    return null;
}
}
like image 26
chinaanihchen Avatar answered Nov 14 '22 23:11

chinaanihchen