使用字符串响应进行改造

时间:2015-12-09 03:50:23

标签: android response retrofit

我希望在URL上进行POST调用,作为响应,我只需要一个String" ok"或"不" .. 所以我在这里有这样的界面:

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

所以我只想给POST方法两个参数,我想要一个String。在服务器上的PHP脚本中,有如下内容:

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

所以我打电话给我的Android手机:

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());

                    }
                });

所以,当我在Throwable中运行它时,我收到以下消息:

Unable to create converter for class java.lang.String

我是否必须为String-response编写自己的转换器?我该怎么做?或者有更好的方法吗?

此致

3 个答案:

答案 0 :(得分:4)

好的答案是编写自己的转换器。像这样:

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;
            }
        }

你必须用它来称呼它:

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);

你得到的回应是:

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());

                    }
                });

答案 1 :(得分:3)

@Klatschen你的答案是对的,在Retrofit2中,abstarct功能已经改变。

public final class StringConverterFactory extends Converter.Factory {
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
    //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> 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;
}

}

答案 2 :(得分:-1)

这里有@chinaanihchen的Retrofit2 Converter.Factory的Kotlin版本

class StringConverterFactory : Converter.Factory() {

    override fun responseBodyConverter(
        type: Type,
        annotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<ResponseBody, *>? = if (String::class.java == type) {
        Converter<ResponseBody, Any> {
            return@Converter it.string()
        }
    } else null

    override fun requestBodyConverter(
        type: Type,
        parameterAnnotations: Array<Annotation>,
        methodAnnotations: Array<Annotation>,
        retrofit: Retrofit
    ): Converter<*, RequestBody>? = if (String::class.java == type) {
        Converter<String, RequestBody> { 
            return@Converter RequestBody.create(MediaType.parse("text/plain"), it) 
        }
    } else null
}