I have a problem in using retrofit. I have a API https://raakar.ir/addProject and want to send some information. API works fine in postman. I want to make post request. I think, I do every think correctly. But when I run the app, It crash.
I used these libraries:
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
and these are my interface of retrofit :
public interface APIInterface {
#Multipart
#POST("addProject")
Call<AddProjectResponse> post(
#Header("token") String token,
#Field("name") String name,
#Field("amount") String amount,
#Field("description") String description,
#Field("category") String category,
#Field("deadline") String deadline,
#Field("projectFile")Bitmap bitmap
);
}
------------------------------------------------------------------------------------------------------------------------------------
Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl("https://raakar.ir/")
.addConverterFactory(GsonConverterFactory.create());
Retrofit retrofit = builder.build();
APIinterface retroInterface = retrofit.create(APIinterface.class);
Call<AddProjectResponse> call = retroInterface.post(token,
"طراحی راکار",
"50000000",
"خالی است",
"برنامه نویسی",
"5",
null);
call.enqueue(new Callback<AddProjectResponse>() {
#Override
public void onResponse(Call<AddProjectResponse> call, Response<AddProjectResponse> response) {
Log.d("Resposne:", response.toString());
}
#Override
public void onFailure(Call<AddProjectResponse> call, Throwable t) {
Log.d("Respone:", "Error");
}
});
PLEASE HELP me!
i thing if you are not post any image and other file like video etc then you can not used #Multipart and also pass in post method paremater make one pojo class for that and only pass your object like below that...sample code
MyEventRequestModel myEventListRequestModel = new MyEventRequestModel(); // define your pojo class object
myEventListRequestModel.setDate(mDate);
Call<MyEventResponseModel> call = apiInterface.getAllEvent(myEventListRequestModel);
and header will be set on retrofit intialized..
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.readTimeout(60, TimeUnit.SECONDS);
client.writeTimeout(60, TimeUnit.SECONDS);
client.connectTimeout(60, TimeUnit.SECONDS);
client.addInterceptor(interceptor);
client.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
if (context == null) {
request = request
.newBuilder()
.build();
} else {
request = request
.newBuilder()
.addHeader("Authorization", "Bearer " + AppSetting.getStringSharedPref(context, Constants.USER_KEY_TOKEN, "")) // hear define your header.
.build();
}
return chain.proceed(request);
}
});
If You use #Multipart than use #Part not #Field
public interface APIInterface {
#Multipart
#POST("addProject")
Call<AddProjectResponse> post(
#Part ("token") String token,
#Part ("name") String name,
#Part ("amount") String amount,
#Part ("description") String description,
#Part ("category") String category,
#Part ("deadline") String deadline,
#Part MultipartBody.Part img
);
}
Related
I am plugging Retrofit into my android app.
Here is how I build retrofit, notice the interceptor for the logging and headers.
public void buildRetrofit(String token){
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addNetworkInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.header("Authorization", "Bearer " + token)
.header("Content-Type", "application/json")
.header("api-version", "1")
.method(chain.request().method(), chain.request().body())
.build();
return chain.proceed(newRequest);
}
});
httpClient.addInterceptor(logging);
Retrofit.Builder buidler = new Retrofit.Builder()
.baseUrl("XXX_HIDDEN_FORSTACKOVERFLOW")
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build());
retroFit = buidler.build();
}
I make the call like so
OrderApi orderApi = mainActivity.retroFit.create(OrderApi.class);
Call<Order> call = orderApi.getOpenOrder();
call.enqueue(new Callback<Order>() {
#Override
public void onResponse(Call<Order> call, Response<Order> response) {
Order a = response.body();
int b = 1;
}
#Override
public void onFailure(Call<Order> call, Throwable t) {
}
});
And here is how the actual request tag
public interface OrderApi {
#POST("/HIDDEN")
Call<Order> getOpenOrder();
}
Lastly, here is the order class
public class Order {
private String orderId;
private OrderStatus orderStatus;
public String getOrderId(){
return orderId;
}
public OrderStatus getOrderStatus() {
return orderStatus;
}
}
I get a response of 400. I have no idea why, and It works in postman etc. Something to note is that the response contains a lot more properties than just the ones in the class. I just want a proof on concept, but that shouldn't break things right?
.................
Managed to fix it. Had to send an empty body request as it was a post but I wasn't posting anything. API is dumb.
See here to send empty request Send empty body in POST request in Retrofit
Here I need to pass Authorization Bearer to get response from server in case of uploading file to server I am using retrofit.
I tried in two ways
1)
This is how I initialized in retrofit interface class
#POST("document/kycDocument/user/3")
Call<UploadKycpojo> uploadkycdoc(#Header("Authorization")String token, #Body UploadKycRequest uploadKycRequest);
This is how I called it from interface class
Call<UploadKycpojo> request = RestClient.getInstance(UploadIdActivtiy.this).get().uploadkycdoc("Bearer "+auth,uploadKycRequest);
2)
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer " + token)
.build();
return chain.proceed(newRequest);
}
}).build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl(/** your url **/)
.addConverterFactory(GsonConverterFactory.create())
.build();
Any help will be appreciated.
Thanks in Advance!
You just need to add space before Bearer it's work for me try it:
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", " Bearer " + token)
.build();
return chain.proceed(newRequest);
}
}).build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl(/** your url **/)
.addConverterFactory(GsonConverterFactory.create())
.build();
Your retrofit interface method should be like this:-
#Multipart
#POST("document/kycDocument/user/3")
Call<UploadKycpojo> uploadkycdoc(#Header("Authorization")String token, #Part
MultipartBody.Part file);
And your calling statement would be like this:-
File file = new File(yourStringPath);
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), getRealPathFromURI(data.getData()));
MultipartBody.Part multipartBody =MultipartBody.Part.createFormData("file",file.getName(),requestFile);
Call<UploadKycpojo> request = RestClient.getInstance(UploadIdActivtiy.this).get()
.uploadkycdoc("Bearer "+auth,multipartBody );
I did try and it's working for me please refer below code:
#Multipart
#POST("document/kycDocument/user/3")
Call<UploadKycpojo> uploadkycdoc(#Header("Authorization")String token, #Part
MultipartBody.Part file, #PartMap() Map<String,
RequestBody> partMap);
And for API call use below method:
private void uploadkycdoc() {
MultipartBody.Part filePart;
HashMap<String, RequestBody> requestBodyMap = new HashMap<>();
requestBodyMap.put("imageSlide", RequestBody.create(MediaType.parse("multipart/form-data"), "front"));
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<UploadKycpojo> uploadkycdocCall = null;
File file = new File(getRealPathFromURI(fileUri, context));
RequestBody requestFile = RequestBody.create(MediaType.parse("*/*"), file);
filePart= MultipartBody.Part.createFormData("file", file.getName(),
requestFile);
uploadkycdocCall = apiInterface.uploadkycdoc("Bearer " + token, filePart, requestBodyMap);
uploadkycdocCall.enqueue(new Callback<UploadKycpojo>() {
#Override
public void onResponse(Call<UploadKycpojo> call, Response<UploadKycpojo> response) {
cancelProgressDialog();
try {
if (response.isSuccessful()) {
} else {
}
} catch (Exception e) {
}
}
#Override
public void onFailure(Call<UploadKycpojo> call, Throwable t) {
}
});
}
Kotlin Ex:
retrofit Get request with AUTH HEADER
#GET("api-shipping/Apps")
fun getApp(#Header("Authorization") auth: String) : retrofit2.Call<JsonObject>
call enqueue don't forget to add Bearer with a space in tokken
val tokken = "Bearer TOKKEN_Key"
call.enqueue(object : Callback<JsonObject> {
override fun onResponse(call: Call<JsonObject>, response: Response<JsonObject>) {
}
override fun onFailure(call: Call<JsonObject>, t: Throwable) {
}
})
}
I tried send json-rpc via retrofit2.
This is my interface:
public interface ApiInterfaceJson {
#POST
#Headers( "Content-Type: application/json" )
Call<String> getDataJson(
#Url String url,
#Body RequestBody body);
}
Create retrofit:
retrofitJson = new Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.baseUrl("http://localhost:8800")
.client(client)
.build();
apiInterfaceJson = retrofitJson.create(ApiInterfaceJson.class);
Call:
JSONObject paramObject = new JSONObject();
try {
paramObject.put("id", "0");
paramObject.put("name", "user");
paramObject.put("command", "finish");
}catch(Exception e){
}
RequestBody requestBody= RequestBody.create(MediaType.parse("application/json"), paramObject.toString());
MinersMonitorApplication.getApiJson().getDataJson("http://10.10.10.230:10000", requestBody).enqueue(new Callback<String>() {
#Override
public void onResponse(#NonNull Call<String> call, #NonNull Response<String> response) {}
#Override
public void onFailure(Call<String> call, Throwable t) {
}
});
The result is SocketTimeoutException.
You need RPC wrapped retrofit - https://github.com/segmentio/retrofit-jsonrpc
Also let service see that it should use json RPC by annotating:
interface MultiplicationService {
#JsonRPC("Arith.Multiply") #POST("/rpc")
Call<Integer> multiply(#Body MultiplicationArgs args);
}
Note that Retrofit is only REST Based library.
I want my android users to be able to upload a profile image to the django rest api. I use retrofit to handle the upload:
UserService
#Multipart
#POST("users/upload-profile-image/")
Call<ResponseBody> uploadProfileImage(#Part MultipartBody.Part image,
#Part("name") RequestBody name);
UserRepository
RequestBody reqFile = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("upload", file.getName(), reqFile);
RequestBody name = RequestBody.create(MediaType.parse("text/plain"), "upload");
Call<ResponseBody> req = userServiceApi.uploadProfileImage(body, name);
req.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(#NonNull Call<ResponseBody> call,
#NonNull Response<ResponseBody> response) {
// Do Something
if (response.isSuccessful()) {
Log.d(TAG, "Successfully uploaded image");
} else {
eventBus.post(new FailUploadProfileImageEvent());
}
}
#Override
public void onFailure(#NonNull Call<ResponseBody> call, #NonNull Throwable t) {
t.printStackTrace();
}
});
To instantiate the userServiceAPI
userServiceApi = ServiceGenerator.createService(UserService.class, token);
ServiceGenerator
// Actual digits replaced with X
private static final String BASE_API_URL = "http://XXX.XXX.X.XXX:8000/";
private static OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
private static Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BASE_API_URL)
.addConverterFactory(GsonConverterFactory.create());
public static <S> S createService(Class<S> serviceClass, String token) {
if (token != null)
okHttpBuilder.authenticator(new TokenAuthenticator(token));
OkHttpClient client = okHttpBuilder.build();
builder.client(client);
Retrofit retrofit = builder.build();
return retrofit.create(serviceClass);
}
users/urls.py
url(r'^upload-profile-image/$', views.UserProfileUploadImageView.as_view(), name="upload_profile_image"),
When I run the android app, no request is made to the server, why?
This is my interface:
public interface ApiInterface {
#GET("solicitation/all")
Call<SolicitationResponse> getAllNews(#Query("X-Authorization") String apiKey);
#POST("solicitation/create ")
Call<Solicitation> createSolicitation(#Body Solicitation solicitation);
}
And this is the MainActivity code to create a new solicitation:
Solicitation solicitation = new Solicitation("xx", "list", "31", "32", "description goes here", "file goes here", "userid goes here", "203120312");
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<Solicitation> call = apiService.createSolicitation(solicitation);
call.enqueue(new Callback<Solicitation>() {
#Override
public void onResponse(Call<Solicitation> call, Response<Solicitation> response) {
Log.d("Response::", "Success!");
}
#Override
public void onFailure(Call<Solicitation> call, Throwable t) {
Log.e("Response::", "Fail!!");
}
});
The problem is, as you've seen above on the query I use an api key. #Query("X-Authorization").
It seems I can't do the same to the #Body.
Is there a way to insert the api key there like in the query?
just add the Query separate by comma
Call<Solicitation> createSolicitation(#Query("X-Authorization") String apiKey, #Body Solicitation solicitation);
or in header
Call<Solicitation> createSolicitation(#Header("X-Authorization") String apiKey, #Body Solicitation solicitation);
or you need an interceptor to insert the header
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.header("X-Authorization", "YOUR AUTH KEY"); // <-- this is the important line
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
OkHttpClient client = httpClient.build();
usage
Call<Solicitation> call = apiService.createSolicitation("YOUR API KEY",solicitation);