这个改装电话怎么了?

时间:2016-09-07 15:26:52

标签: android post retrofit spotify

我正在尝试发送POST并使用Android进行改造来构建响应。

我设法发送GET没有任何问题,但现在我需要发送带有一些body元素的POST。

public static <S> S createAccessService(Class<S> serviceClass, String code, String redirectUri,
                                  String clientId, String clientSecret) {
    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    String basicCredentials = clientId+":"+clientSecret;
    byte[] encodeBytes = Base64.encode(basicCredentials.getBytes(), Base64.NO_WRAP);
    httpClient.addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();
            RequestBody body = new FormBody.Builder()
                    .add("grant_type", "authorization_code")
                    .add("code", code)
                    .add("redirect_uri", redirectUri).build();
            Request request = original.newBuilder()
                    .addHeader("Authorization", "Basic "+new String(encodeBytes))
                    .method(original.method(), original.body())
                    .put(body)
                    .build();
            return chain.proceed(request);
        }
    });

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

    return retrofit.create(serviceClass);

我正在尝试构建的POST看起来像这样:

POST /api/token HTTP/1.1
Host: accounts.spotify.com
Authorization: Basic ***********************************
Cache-Control: no-cache
Postman-Token: 99177da6-1606-3145-689d-bc4b09b3f212
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A8888%2Fcallback&code*********************************************************************************************************************************************************

显然,为了安全起见,密钥是隐藏的。

这是我用来存储回复的POJO。

public class Session {

private String scope;

private String expires_in;

private String token_type;

private String refresh_token;

private String access_token;
private String error;

public String getError_description() {
    return error_description;
}

public void setError_description(String error_description) {
    this.error_description = error_description;
}

public String getError() {
    return error;
}

public void setError(String error) {
    this.error = error;
}

private String error_description;

public String getScope ()
{
    return scope;
}

public void setScope (String scope)
{
    this.scope = scope;
}

public String getExpires_in ()
{
    return expires_in;
}

public void setExpires_in (String expires_in)
{
    this.expires_in = expires_in;
}

public String getToken_type ()
{
    return token_type;
}

public void setToken_type (String token_type)
{
    this.token_type = token_type;
}

public String getRefresh_token ()
{
    return refresh_token;
}

public void setRefresh_token (String refresh_token)
{
    this.refresh_token = refresh_token;
}

public String getAccess_token ()
{
    return access_token;
}

public void setAccess_token (String access_token)
{
    this.access_token = access_token;
}




}

我已经改变了很多东西,但无论如何,响应都无法实现新的Session对象,总是返回null。

添加了:

这是我使用的界面:

   @FormUrlEncoded
   @POST("/api/token")
   Call<Session> getSession();

我做错了什么?

由于

1 个答案:

答案 0 :(得分:0)

好吧,如果您尝试使用POST发送retrofit2请求,请尝试以下操作:

首先,创建一个接口,在此界面中声明POST request的正文内容:

public interface ISesion {

    @FormUrlEncoded
    @POST("/users/login")
    Call<Sesion> inSesion(@Field("username") String usuario, @Field("password") String password);
}

参数@Field是您在POST request

中使用的正文内容

现在,您可以在MainActivity

中进行此操作
public class MainActivity extends AppCompatActivity {
    private Retrofit retrofit; //your Retrofit Object
    private ISesion iSesion; //your interface

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    retrofit = new Retrofit.Builder()
            .baseUrl(getString(R.string.url_base)) //your base URL ("http://www.myexample.com")
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    iSesion = retrofit.create(ISesion.class);
    Call<Sesion> call = iSesion.inSesion(usuario, contrasena); //you get this fields from editText, for example, and you pass it to the method in your interface
        call.enqueue(new Callback<Sesion>() {
            @Override
            public void onResponse(Call<Sesion> call, Response<Sesion> response) {
                code = response.code();
                switch (code) {
                    case 200:
                        Intent intent = new Intent(getActivity(), MainActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        startActivity(intent);

                        break;
                    case 401:
                        error = response.body().isError();
                        mensaje = response.body().getMensaje();
                        if (error) {
                            Snackbar.make(view, mensaje, Snackbar.LENGTH_LONG).show();
                        }
                        break;
                }
            }

            @Override
            public void onFailure(Call<Sesion> call, Throwable t) {
                t.printStackTrace();
                Snackbar.make(view, getString(R.string.error_general), Snackbar.LENGTH_LONG).show();
            }
        });
    }
}

方法Call<Sesion>中使用的模型是下一个:

public class Sesion {

    @SerializedName("error")
    private boolean error;

    @SerializedName("message")
    private String mensaje;

    public boolean isError() {
        return error;
    }

    public String getMensaje() {
        return mensaje;
    }
}  

修改

如果您想在身体内容中发送令牌,请执行以下操作:

Call<Sesion> call = iSesion.inSesion("Basic " + generatedToken); // here is the authentication token
        call.enqueue(new Callback<Sesion>() {
            @Override
            public void onResponse(Call<Sesion> call, Response<Sesion> response) {
                code = response.code();
                switch (code) {
                    case 200:
                        Intent intent = new Intent(getActivity(), MainActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                        startActivity(intent);

                        break;
                    case 401:
                        error = response.body().isError();
                        mensaje = response.body().getMensaje();
                        if (error) {
                            Snackbar.make(view, mensaje, Snackbar.LENGTH_LONG).show();
                        }
                        break;
                }
            }

            @Override
            public void onFailure(Call<Sesion> call, Throwable t) {
                t.printStackTrace();
                Snackbar.make(view, getString(R.string.error_general), Snackbar.LENGTH_LONG).show();
            }
        });
    }

这是界面:

public interface ISesion {

    @FormUrlEncoded
    @POST("/users/login")
    Call<Sesion> inSesion(@Field("token") String generatedToken);
}