我正在尝试发送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();
我做错了什么?
由于
答案 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);
}