如何在 retrofit2 中发送表单数据 android
How to send Form data in retrofit2 android
嗨,我有一个 json 要发送到服务器(POST 方法){"country":"india","devicetype":"android"}
它是表单数据模型
就像这个 json 的关键是 data 即服务器是否像
一样接受它
data={"country":"india","devicetype":"android"}
我正在使用改造 我使用 Multipart 是这样的
@Multipart
@POST("initiate")
@Headers({
"Content-Type: application/json",
"Cache-Control: no-cache"
})
Call<UserInfoServerResponse> getUserInfoRequest(@Part(value="data") UserInfo mUserInfo);
此处 UserInfo 是 json 但在我使用 FormUrlEncoded 方法后从服务器收到失败消息
@FormUrlEncoded
@POST("initiate")
@Headers({
"Content-Type: application/json",
"Cache-Control: no-cache"
})
Call<UserInfoServerResponse> getUserInfoRequest(@Field(value="data",encoded = false) String mUserInfo);
它的输出也是来自服务器的相同失败结果,但是发送到服务器的数据是格式
data=%7B%22country%22%3A%22india%22%2C%22devicetype%22%3A%22%22%7D
我的UserInfo.class
public class UserInfo {
public String country;
public String devicetype;
public UserInfo( String country,String devicetype) {
this.country=country;
this.devicetype=devicetype;
}
}
我的适配器class
RemoteRetrofitInterfaces mService;
Retrofit mRetrofit;
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS).addInterceptor(interceptor)
.build();
mRetrofit = new Retrofit.Builder()
.baseUrl(AppConstant.HOST).addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
mService = mRetrofit.create(RemoteRetrofitInterfaces.class);
Call<UserInfoServerResponse> api = mService.getUserInfoRequest(new Gson().toJson(mUserInfo));
api.enqueue(new Callback<UserInfoServerResponse>() {
@Override
public void onResponse(Call<UserInfoServerResponse> responseCall, Response<UserInfoServerResponse> response) {
if (response.body().status != null) {
if (response.body().status.equals("success")) {
Log.d(TAG, "success---");
}
} else {
Log.d(TAG, "Failed---");
}
}
@Override
public void onFailure(Call<UserInfoServerResponse> responseCall, Throwable t) {
t.printStackTrace();
}
});
那么我如何才能成功地使用改装将 json 发送到服务器?我完成了 retofit document 并执行了几个步骤,但我没有得到任何结果。任何人都可以帮助我吗
谢谢
我终于找到了解决方案希望这对其他人有所帮助
我通过使用 FieldMap
实现了解决方案
改造。
@POST("initiate")
@FormUrlEncoded
Call<UserInfoServerResponse> getUserInfoRequest(@FieldMap Map<String,String> params);
并且在 Rest Adapter 部分,我将请求数据从字符串更改为 Hashmap 形式,如下所示
Log.d(TAG, "sendUserInfo called");
UserInfo mInfo = new UserInfo("countyname","android");
String request = new Gson().toJson(mUserInfo);
// Here the json data is add to a hash map with key data
Map<String,String> params = new HashMap<String, String>();
params.put("data", request);
Call<UserInfoServerResponse> api = mService.getUserInfoRequest(params);
api.enqueue(new Callback<UserInfoServerResponse>() {
@Override
public void onResponse(Call<UserInfoServerResponse> responseCall, Response<UserInfoServerResponse> response) {
if (response.body().status != null) {
if (response.body().status.equals("success")) {
Log.d(TAG, "success---" + response.body());
}
} else {
Log.d(TAG, "Failed---");
}
}
@Override
public void onFailure(Call<UserInfoServerResponse> responseCall, Throwable t) {
t.printStackTrace();
}
});
基本上我使用 @FormUrlEncoded 作为表单数据,@FieldMap 将我的请求 JSON 作为键值.我按照这个方法得到了解决方案,希望这会对某些人有所帮助:)
上述解决方案有效但使用起来很麻烦,更好的解决方案是使用@Multipart formData 的转换器
请使用下面的代码来处理@Multipart FormData
这是因为
"" is added to your posting strings
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
/**
* Created by kural on 10/27/17.
*/
public class StringConverterFactory extends Converter.Factory {
private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");
public static StringConverterFactory create() {
return new StringConverterFactory();
}
@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;
}
}
并在您的改装客户端中添加此行
.addConverterFactory(StringConverterFactory.create())
public class RetroFitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
/*retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();*/
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(StringConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
这对我和 return 一个 json 获得新的有效 Microsoft Azure 令牌很有效:
我的终点:
@PostMapping(value = "/get-new-token", consumes = {"application/JSON"}, produces = {"application/JSON"})
@Timed
public ResponseEntity<String> getNewToken(@RequestBody String refreshToken) throws IOException {
JSONObject json = tokenService.getNewTokenByRefreshToken(refreshToken);
return new ResponseEntity<>(json.toString(), HttpStatus.OK);
}
我的 getGraphRepository :
public GraphRepository getGraphRepository() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor).build();
// Create and configure the Retrofit object
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(" https://login.microsoftonline.com")
.client(client)
.addConverterFactory(JacksonConverterFactory.create())
.build();
// Generate the graph repo
return retrofit.create(GraphRepository.class);
}
我的令牌服务:
public JSONObject getNewTokenByRefreshToken(String refreshToken) throws IOException {
GraphRepository graphRepository = getGraphRepository();
// My list of -> Key : Value
Map<String,String> params = new HashMap<String, String>();
params.put("grant_type", "refresh_token");
params.put("client_id", this.client_id);
params.put("client_secret", client_secret);
params.put("refresh_token", refreshToken);
RefreshToken data = graphRepository.getRefreshToken(tenantId, params).execute().body();
JSONObject json = new JSONObject(data);
return json;
}
我的图表库:
@POST("/{tenant_id}/oauth2/v2.0/token")
@FormUrlEncoded
Call<RefreshToken> getRefreshToken(
@Path("tenant_id") String tenant_id,
@FieldMap Map<String, String> params
);
希望对大家有所帮助。
嗨,我有一个 json 要发送到服务器(POST 方法){"country":"india","devicetype":"android"}
它是表单数据模型
就像这个 json 的关键是 data 即服务器是否像
data={"country":"india","devicetype":"android"}
我正在使用改造 我使用 Multipart 是这样的
@Multipart
@POST("initiate")
@Headers({
"Content-Type: application/json",
"Cache-Control: no-cache"
})
Call<UserInfoServerResponse> getUserInfoRequest(@Part(value="data") UserInfo mUserInfo);
此处 UserInfo 是 json 但在我使用 FormUrlEncoded 方法后从服务器收到失败消息
@FormUrlEncoded
@POST("initiate")
@Headers({
"Content-Type: application/json",
"Cache-Control: no-cache"
})
Call<UserInfoServerResponse> getUserInfoRequest(@Field(value="data",encoded = false) String mUserInfo);
它的输出也是来自服务器的相同失败结果,但是发送到服务器的数据是格式
data=%7B%22country%22%3A%22india%22%2C%22devicetype%22%3A%22%22%7D
我的UserInfo.class
public class UserInfo {
public String country;
public String devicetype;
public UserInfo( String country,String devicetype) {
this.country=country;
this.devicetype=devicetype;
}
}
我的适配器class
RemoteRetrofitInterfaces mService;
Retrofit mRetrofit;
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS).addInterceptor(interceptor)
.build();
mRetrofit = new Retrofit.Builder()
.baseUrl(AppConstant.HOST).addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
mService = mRetrofit.create(RemoteRetrofitInterfaces.class);
Call<UserInfoServerResponse> api = mService.getUserInfoRequest(new Gson().toJson(mUserInfo));
api.enqueue(new Callback<UserInfoServerResponse>() {
@Override
public void onResponse(Call<UserInfoServerResponse> responseCall, Response<UserInfoServerResponse> response) {
if (response.body().status != null) {
if (response.body().status.equals("success")) {
Log.d(TAG, "success---");
}
} else {
Log.d(TAG, "Failed---");
}
}
@Override
public void onFailure(Call<UserInfoServerResponse> responseCall, Throwable t) {
t.printStackTrace();
}
});
那么我如何才能成功地使用改装将 json 发送到服务器?我完成了 retofit document 并执行了几个步骤,但我没有得到任何结果。任何人都可以帮助我吗
谢谢
我终于找到了解决方案希望这对其他人有所帮助
我通过使用 FieldMap
实现了解决方案改造。
@POST("initiate")
@FormUrlEncoded
Call<UserInfoServerResponse> getUserInfoRequest(@FieldMap Map<String,String> params);
并且在 Rest Adapter 部分,我将请求数据从字符串更改为 Hashmap 形式,如下所示
Log.d(TAG, "sendUserInfo called");
UserInfo mInfo = new UserInfo("countyname","android");
String request = new Gson().toJson(mUserInfo);
// Here the json data is add to a hash map with key data
Map<String,String> params = new HashMap<String, String>();
params.put("data", request);
Call<UserInfoServerResponse> api = mService.getUserInfoRequest(params);
api.enqueue(new Callback<UserInfoServerResponse>() {
@Override
public void onResponse(Call<UserInfoServerResponse> responseCall, Response<UserInfoServerResponse> response) {
if (response.body().status != null) {
if (response.body().status.equals("success")) {
Log.d(TAG, "success---" + response.body());
}
} else {
Log.d(TAG, "Failed---");
}
}
@Override
public void onFailure(Call<UserInfoServerResponse> responseCall, Throwable t) {
t.printStackTrace();
}
});
基本上我使用 @FormUrlEncoded 作为表单数据,@FieldMap 将我的请求 JSON 作为键值.我按照这个方法得到了解决方案,希望这会对某些人有所帮助:)
上述解决方案有效但使用起来很麻烦,更好的解决方案是使用@Multipart formData 的转换器
请使用下面的代码来处理@Multipart FormData 这是因为
"" is added to your posting strings
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
/**
* Created by kural on 10/27/17.
*/
public class StringConverterFactory extends Converter.Factory {
private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");
public static StringConverterFactory create() {
return new StringConverterFactory();
}
@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;
}
}
并在您的改装客户端中添加此行
.addConverterFactory(StringConverterFactory.create())
public class RetroFitClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
if (retrofit==null) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
/*retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();*/
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.client(client)
.addConverterFactory(StringConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
这对我和 return 一个 json 获得新的有效 Microsoft Azure 令牌很有效:
我的终点:
@PostMapping(value = "/get-new-token", consumes = {"application/JSON"}, produces = {"application/JSON"})
@Timed
public ResponseEntity<String> getNewToken(@RequestBody String refreshToken) throws IOException {
JSONObject json = tokenService.getNewTokenByRefreshToken(refreshToken);
return new ResponseEntity<>(json.toString(), HttpStatus.OK);
}
我的 getGraphRepository :
public GraphRepository getGraphRepository() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor).build();
// Create and configure the Retrofit object
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(" https://login.microsoftonline.com")
.client(client)
.addConverterFactory(JacksonConverterFactory.create())
.build();
// Generate the graph repo
return retrofit.create(GraphRepository.class);
}
我的令牌服务:
public JSONObject getNewTokenByRefreshToken(String refreshToken) throws IOException {
GraphRepository graphRepository = getGraphRepository();
// My list of -> Key : Value
Map<String,String> params = new HashMap<String, String>();
params.put("grant_type", "refresh_token");
params.put("client_id", this.client_id);
params.put("client_secret", client_secret);
params.put("refresh_token", refreshToken);
RefreshToken data = graphRepository.getRefreshToken(tenantId, params).execute().body();
JSONObject json = new JSONObject(data);
return json;
}
我的图表库:
@POST("/{tenant_id}/oauth2/v2.0/token")
@FormUrlEncoded
Call<RefreshToken> getRefreshToken(
@Path("tenant_id") String tenant_id,
@FieldMap Map<String, String> params
);
希望对大家有所帮助。