500, Internal Server Error in Retrofit 2 - java

I have 500 internal server error, every time when i try to send POST request via Retrofit. When i sending GET request, it sending correctly. I'm sure that with serverside everyting is ok. What's wrong with my code ?
Here is my request method
#POST("/listing/createListing")
Call<ResponseBody> pushData(#Body RequestBody image);
post implementation modelTask is my model class object and firebaseToken is firebase authentication token. In my model class, I am saving images as a file list.
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new
Interceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws
IOException {
Request newRequest = chain.request().newBuilder()
.addHeader("Authorization", "Bearer " +
firebaseToken)
.build();
return chain.proceed(newRequest);
}
}).build();
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl("https://something.herokuapp.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiEndPoint apiService = retrofit.create(ApiEndPoint.class);
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
builder.addFormDataPart("title", modelTask.getTitle());
builder.addFormDataPart("description", modelTask.getDescription());
builder.addFormDataPart("user_name", "Josim Uddin");
builder.addFormDataPart("user_id", "2133323");
builder.addFormDataPart("price", "30.0");
builder.addFormDataPart("category_name", "Cleaning");
builder.addFormDataPart("category_id", "123");
builder.addFormDataPart("preferred_date",
modelTask.getPreferred_date());
builder.addFormDataPart("preferred_time",
modelTask.getPreferred_time());
builder.addFormDataPart("hasPet", modelTask.getHasPet());
builder.addFormDataPart("budget",
String.valueOf(modelTask.getBudget()));
builder.addFormDataPart("address", modelTask.getAddress());
builder.addFormDataPart("longitude",
String.valueOf(modelTask.getLongitude()));
builder.addFormDataPart("latitude",
String.valueOf(modelTask.getLatitude()));
builder.addFormDataPart("equipment", modelTask.getEquipment());
for (int i = 0; i < modelTask.getImages().size(); i++) {
builder.addFormDataPart("image[]",
modelTask.getImages().get(i).getName(),
RequestBody.create(MediaType.parse("multipart/form-data"),
modelTask.getImages().get(i)));
}
MultipartBody requestBody = builder.build();
Call<ResponseBody> call = apiService.pushData(requestBody);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call,
Response<ResponseBody> response) {
Log.d(TAG, "onResponse:" + response.code()+",
"+response.message());
if (response.isSuccessful()) {
try {
Log.d(TAG, "post submitted code:" +
response.code()+"body:"+response.body().string());
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "Unable to submit post to API::
"+t.getMessage());
}
});
Postman test is successful.

Try this
#POST("listing/createListing")
Call<ResponseBody> pushData(#Body RequestBody image);
Remove "/" from the link and add it to the end of Base Url.

Related

Uploading image on imgur results OK, but no data

I'm trying to upload images from my android apk.
I use this code, seems works, but I getting no data response
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
okhttp3.RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("image", getBase64Image(bitmapImage))
.build();
okhttp3.Request request = new okhttp3.Request.Builder()
.url("https://api.imgur.com/3/image")
.method("POST", body)
.addHeader("Authorization", "Client-ID " + CLIENT_ID)
.build();
client.newCall(request).enqueue(new okhttp3.Callback() {
#Override
public void onFailure(okhttp3.Call call, IOException e) {
Log.d("ERROR",e.getMessage());
}
#Override
public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
//My code
}
});

GET Request returning 403 Forbidden but works on apitester?

I am trying to get the responce from the server but it is returinig 403 forbidden but testing api on apitester.com works.
This is the code how i am reqesting the get method :
public void getResponse(Context context) throws IOException {
OkHttpClient client = new OkHttpClient();
Hmac hmac = new Hmac();
String auth = hmac.txt;
String url = "https://api.hotstar.com/h/v1/play?contentId=1000034502";
Request request = new Request.Builder()
.url(url)
.addHeader("hotstarauth",auth)
.addHeader("referer","https://hotstar.com/movies/2-states/1000034502")
.addHeader("x-country-code","IN")
.addHeader("x-platform-code","TABLET")
.addHeader("x-region-code","undefined")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Toast.makeText(context, "Error Occured", Toast.LENGTH_SHORT).show();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
Log.d("Server Responded: ", response.toString());
}
});
}
and in response i am getting 403 FORBIDDEN
but using the same config on apitester.com it works !
here is the sharedconig on apitester https://www.apitester.com/shared/checks/dca814bb92fb40af8aecda95cdf2f39c
why i am not getting the response on android ?

Android Retrofit2 error 422 on POST request

I want to make a POST request to a server with retrofit, but I always get error 422.
I just wanna know if I do something wrong or it is the server fault.
Retrofit call:
OkHttpClient.Builder duplicateTimeSessionClient = new kHttpClient.Builder();
duplicateTimeSessionClient.addInterceptor(newInterceptor() {
#Override
public okhttp3.Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.header("Authorization", "Bearer "+sharedPreferences.getString("access_token",""))
.header("Accept", "application/vnd.web_app+json; version=1")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
});
OkHttpClient client = duplicateTimeSessionClient.build();
final Retrofit duplicateTimeSession = new Retrofit.Builder()
.baseUrl(context.getString(R.string.URL))
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
duplicateService = duplicateTimeSession.create(DuplicateTimeSessionInterface.class);
Call<String> duplicateTimeSessionCall = duplicateService.duplicate(createJSON(pos),"api/time-sessions");
duplicateTimeSessionCall.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
Log.i("time-session post",Integer.toString(response.code()));
}
#Override
public void onFailure(Call<String> call, Throwable t) {}
});
Interface:
public interface DuplicateTimeSessionInterface {
#POST
Call<String>duplicate(#Body JSONObject jsonObject, #Url String url);
}
EDIT:
The same JSON works from the browser or iPhone, and some similar calls work from Android, this one just doesn't want to go through.

when does okhttp client cache the server response?

I am using okhttp client 3.5.0 in java to cache the response and server response has below cache-control header:
Cache-Control: private, max-age=0, must-revalidate
First I am trying to make actual network call to get the server response, then in second request I want to get cached response.
Here is my java code:
HttpUrl.Builder httpUrlBuilder = HttpUrl.parse(serverUrl).newBuilder();
HttpUrl httpUrl = httpUrlBuilder.build();
Request request = new Request.Builder()
.url(httpUrl)
.cacheControl(new CacheControl.Builder().maxAge(1, TimeUnit.DAYS).build())
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
System.out.println("***************Response 1**************");
System.out.println("isSucess:"+response.isSuccessful());
Response text = response.cacheResponse();
System.out.println("Cached Response:" + text);
Response networkResponse = response.networkResponse();
System.out.println("Network Response ::" +networkResponse);
}
});
Thread.sleep(5000);
Request request2 = new Request.Builder()
.cacheControl(new CacheControl.Builder().onlyIfCached().build())
.url(httpUrlBuilder.build())
.build();
call = okHttpClient.newCall(request2);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
System.out.println("***********Response 2************");
System.out.println("isSucess:" +response.isSuccessful());
final Response text = response.cacheResponse();
System.out.println("Cached Response:" + text);
Response networkResponse = response.networkResponse();
System.out.println("Network Response:" +networkResponse);
}
});
And below is the second request output:(partial output)
***********Response 2************
isSucess:false
Cached Response:null
Network Response:null
Whether I am missing anything?
OkHttp won’t cache a response unless you read and close the response body. This is what triggers those bytes to be downloaded and saved.
try {
if (response.cacheResponse() == null) {
body.source().skip(Long.MAX_VALUE); // Exhaust response body.
}
} finally {
body.close();
}

retrofit 2.0 how to print the full json response?

I am moving from Volley to Retrofit currently version 2.0.
How to print the the full json response code ?
includes:
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
RestClient:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response;
}
});
Gson gson = new GsonBuilder()
.setDateFormat("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS'Z'")
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ROOT)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client)
.build();
REST_CLIENT = retrofit.create(APIService.class);
APIService:
#GET("my/json")
Call<Model> getFeed();
In Activity - Calling API:
Call<Model> call = RestClient.get().getFeed();
call.enqueue(new Callback<Model>() {
#Override
public void onResponse(Response<Model> response, Retrofit retrofit) {
Log.w("2.0 getFeed > response.raw() => ", response.raw().toString());//DONT WORK
Log.w("2.0 getFeed > retrofit => ", retrofit.toString());//DONT WORK
Log.w("2.0 getFeed > body => ", response.body().toString()); //DONT WORK
Log.w("2.0 getFeed > getStatus => ", response.body().getStatus());
}
#Override
public void onFailure(Throwable t) {
t.printStackTrace();
Log.e("2.0 getFeed > onFailure => ", t.toString());
}
});
To print the full response in json:
Log.w("2.0 getFeed > Full json res wrapped in gson => ",new Gson().toJson(response));
If you'd like to have pretty print feature, use:
Log.w("2.0 getFeed > Full json res wrapped in pretty printed gson => ",new GsonBuilder().setPrettyPrinting().create().toJson(response));
Note that this prints the deserialized data (not raw response as returned from server). To get the raw response, you may use one of these:
Use HttpLoggingInterceptor see: https://stackoverflow.com/a/33256827/2267723 or have your own version of interceptor
Use http debugging tools such Stetho. see: http://facebook.github.io/stetho/ or Charles Web Debugging Proxy. see: https://www.charlesproxy.com
Actually Square already create a class just for this, just add
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor).build();
And, in Retrofit
Retrofit retrofit = new Retrofit.Builder()
.client(client)
.baseUrl("https://yourapi.com/api/")
.build();
The interceptor class is in maven central
compile 'com.squareup.okhttp3:logging-interceptor:3.5.0'
You can set the logging level in HttpLoggingInterceptor class. BODY is the verbose one (it print everything to the Body). Further information is available on OkHttp github
Caution!
Don't forget to remove Interceptors (or change Logging Level to NONE) in production! Otherwise people will be able to see your request and response on Log Cat.
Plug in the following interceptor class like this
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new LoggingInterceptor());
//////Interceptor class
public static class LoggingInterceptor implements Interceptor {
#Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
Log.i("LoggingInterceptor","inside intercept callback");
Request request = chain.request();
long t1 = System.nanoTime();
String requestLog = String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers());
if(request.method().compareToIgnoreCase("post")==0){
requestLog ="\n"+requestLog+"\n"+bodyToString(request);
}
Log.d("TAG","request"+"\n"+requestLog);
com.squareup.okhttp.Response response = chain.proceed(request);
long t2 = System.nanoTime();
String responseLog = String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers());
String bodyString = response.body().string();
Log.d("TAG","response only"+"\n"+bodyString);
Log.d("TAG","response"+"\n"+responseLog+"\n"+bodyString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), bodyString))
.build();
}
public static String bodyToString(final Request request) {
try {
final Request copy = request.newBuilder().build();
final Buffer buffer = new Buffer();
copy.body().writeTo(buffer);
return buffer.readUtf8();
} catch (final IOException e) {
return "did not work";
}
}`
Courtesy: https://github.com/square/retrofit/issues/1072#
To get full response in Json in retrofit use below.
this works for me.
call.enqueue(new Callback<someList>() {
#Override
public void onResponse(Call<someList> call, Response<someList> response) {
if (response.isSuccessful())
Log.e("Success", new Gson().toJson(response.body()));
else
Log.e("unSuccess", new Gson().toJson(response.errorBody()));
}
#Override
public void onFailure(Call<someList> call, Throwable t) {
Log.e("onFailure", t.toString());
}
});
You can setLogLevel to your Retrofit adapter like below, and see the response and other data such as header, response code vs.
setLogLevel(LogLevel.FULL)
If you're using Retrofit version 2+ you have to set OkHttpLoggingInterceptor to see logs.
First add OkHttpLoggingInterceptor to your project:
com.squareup.okhttp3:logging-interceptor:${Versions.okHttpLoggingInterceptorVersion}
And than create init your interceptor:
HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY }
And finally add it to your OkHttpClient
with(OkHttpClient.Builder()) {
if (BuildConfig.DEBUG) addInterceptor(loggingInterceptor)
build()
}
Try this !!
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
/** Handles Log */
retrofit.client().interceptors().add(new LoggingInterceptor());
mRestClient = retrofit.create(RestServices.class);
class LoggingInterceptor implements Interceptor {
#Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
long t1 = System.nanoTime();
Logger.d(String.format("Sending request %s on %s%n%s",
request.url(), chain.connection(), request.headers()));
Response response = chain.proceed(request);
long t2 = System.nanoTime();
Logger.d(String.format("Received response for %s in %.1fms%n%s",
response.request().url(), (t2 - t1) / 1e6d, response.headers()));
final String responseString = new String(response.body().bytes());
Logger.d("Response: " + responseString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), responseString))
.build();
}
Check this Demo !!!
Log.e("TAG","2.0 getFeed > response.raw() => " + new Gson().toJson(response.body()));
public class HttpLoggingInterceptor {
HttpLoggingInterceptor provideHttpLoggingInterceptor(){
return new HttpLoggingInterceptor(message ->
Log.d("TAG", message)).setLevel(HttpLoggingInterceptor.Level.BODY);
}
}
public class OkHttpClient {
OkHttpClient provideOkHttpClient(#NonNull HttpLoggingInterceptor interceptor){
return new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
}
}
Try this :
Log.d("LOG","RESPONSE ==="+response.raw().toString());
Take a look on okhttp3.logging package, they already have HttpLoggingInterceptor that you can use for your needs.
And depending on them you can also specify logging level.
and you can include this interceptor to your request as mentioned - via OkHttpClient.Builder:
public OkHttpClient provideOkHttpClient() {
final OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
okHttpBuilder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
return okHttpBuilder.build();
}
To get full json response with retrofit 2.0 follow code given below
Api Interface
#GET("my/json")
Call<JsonObject> getFeed();
Retrofit Call function
Call<JsonObject> call = RestClient.get().getFeed();
call.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
Log.d("res", response.body().toString());
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
Log.d("error",t.getMessage());
}
});
Call<Model> call = RestClient.get().getFeed();call.enqueue(new Callbstrong
textack<Model>() {
#Override
public void onResponse(Response<Model> response, Retrofit retrofit) {
//try this
Call<Model> call = response.body();
// this is enough for retrieve model
}
#Override
public void onFailure(Throwable t) {
t.printStackTrace();
og.e("2.0 getFeed > onFailure => ", t.toString());
}
});

Categories