I want to use retrofit for fetching data from my server. My server send data as a string json.
I create a server like this:
public class ServiceGenerator {
public static final String BASE_URL = "http://192.168.100.73/ChartReport/Service1.svc/";
static OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create());
private static Retrofit retrofit = builder.build();
public static <S> S createService(Class<S> serviceClass) {
return retrofit.create(serviceClass);
}
}
And then i have created client like blow:
public interface IReportCLient {
#POST("json/GetDataReport")
Call<ResponseBody> getReporst();
}
And I have used into my activity :
IReportCLient service = ServiceGenerator.createService(IReportCLient.class);
Call<ResponseBody> reporst = service.getReporst();
reporst.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
JsonObject post = new JsonObject().get(response.body().string()).getAsJsonObject();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
When I run my app in debug mode for first time i fetch my data by this command:
response.body().string()
but immediately my result is null when i run response.body().string() again??
What is happens?
string() method can only be called once on RequestBody. So it will return empty string if you try to call it again. This is true for debugging as well. If you try to evaluate expressions response.body().string() while debugging, your actual methods will get empty string.
An HTTP response. Instances of this class are not immutable: the
response body is a one-shot value that may be consumed only once and
then closed. All other properties are immutable.
https://square.github.io/okhttp/3.x/okhttp/okhttp3/Response.html
Read this as well https://stackoverflow.com/a/32307866/6168272
This is how I get JsonObject from my response object. You can give it a try.
private JSONObject parseJsonFromResponse(Response response) {
ResponseBody responseBody = response.body();
if (responseBody != null) {
try {
return new JSONObject(responseBody.string());
} catch (JSONException | IOException e) {
e.printStackTrace();
return new JSONObject();
}
} else return new JSONObject();
}
Below are the files for retrofit.
While passing the data in the form of JSON I am getting a null response.
Could anyone guide where can be the issue occurring?
I am trying to post the data in the form of JSON using the retrofit library. Can you suggest me the right approach?
My code:
public class ApiSellarClient {
public static final String BASE_URL = "Constant.BASE_URL";// it is from constant file..
private static Retrofit retrofit = null;
public static Retrofit getClient() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
public class ApiSellarConnection {
public static Call<String> getSignInData(JSONObject json) {
return ApiSellarClient.getClient().create(ApiSellarInterface.class).getSignInData(json);
}
}
public interface ApiSellarInterface {
#Headers("Content-Type: application/json")
#POST("integration/customer/token")
Call<String> getSignInData(#Body JSONObject json);
}
// Below is the controller class.
JSONObject paramObject = new JSONObject();
try {
paramObject.put("username", etUserName.getText().toString());
paramObject.put("password", etPassword.getText().toString());
ApiSellarConnection.getSignInData(paramObject).enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
Log.d("tag", "helper" + response.body());
}
#Override
public void onFailure(Call<String> call, Throwable t) {
}
});
} catch (JSONException e) {
e.printStackTrace();
}
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.
Hi i have a json to send to the server (POST METHORD){"country":"india","devicetype":"android"} it is in form data model
like the key for this json is data ie is the server accept it like
data={"country":"india","devicetype":"android"} am using retrofit i use Multipart like this
#Multipart
#POST("initiate")
#Headers({
"Content-Type: application/json",
"Cache-Control: no-cache"
})
Call<UserInfoServerResponse> getUserInfoRequest(#Part(value="data") UserInfo mUserInfo);
here UserInfo is the json but am getting fail message from server after that i used FormUrlEncoded methord
#FormUrlEncoded
#POST("initiate")
#Headers({
"Content-Type: application/json",
"Cache-Control: no-cache"
})
Call<UserInfoServerResponse> getUserInfoRequest(#Field(value="data",encoded = false) String mUserInfo);
its out put is also same failure result from server, but the data sending to the server is in the formate
data=%7B%22country%22%3A%22india%22%2C%22devicetype%22%3A%22%22%7D
My UserInfo.class
public class UserInfo {
public String country;
public String devicetype;
public UserInfo( String country,String devicetype) {
this.country=country;
this.devicetype=devicetype;
}
}
My adaptor 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();
}
});
so how can i send the json to server using retrofit successfully i gone through the retofit document and follow couple of steps but i dont get any result. can any one help me in this
Thank you
finally i found the solution hope this will help some other
i achieve the solution by using FieldMap
of retrofit.
#POST("initiate")
#FormUrlEncoded
Call<UserInfoServerResponse> getUserInfoRequest(#FieldMap Map<String,String> params);
and in the Rest Adaptor section i changed request data from string to Hashmap form like following
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();
}
});
Basilcally what I used #FormUrlEncoded for form data and #FieldMap to put my request JSON as a key value. i got solution by following this method, hope this will help some one :)
The above solution works but is cumbersome to use , a better solution will be to use a converter for #Multipart formData
Please use the bellow code for proceeding with #Multipart FormData
This is because
"" 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;
}
}
and in your retrofit client add this line
.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;
}
This works fine for me and return a json to obtain new valid Microsoft Azure Token :
My end point :
#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);
}
My 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);
}
My Token Service :
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;
}
My GraphRepository :
#POST("/{tenant_id}/oauth2/v2.0/token")
#FormUrlEncoded
Call<RefreshToken> getRefreshToken(
#Path("tenant_id") String tenant_id,
#FieldMap Map<String, String> params
);
I hope this can help someone.
I am working on Retrofit v2 library for network calls.I am using following dependencies in build.gradle file.
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
1.User.java
public class User {
#SerializedName("email")
String email;
#SerializedName("password")
String password;
public User(String email, String password) {
this.email = email;
this.password = password;
}
}
2.MyAPI.java
public interface MyAPI {
#GET("{roomID}")
Call<List<Message>>loadMessages(#Path("roomID") String roomID);
#POST("almabay_oauth/authorize")
Call<User>login(#Body User user);
}
3.MainActivity.java
public class MainActivity extends AppCompatActivity {
String roomID = "548b737c0eadfb00eb93891bb28242e5";
MyAdapter adapter;
ListView lv;
List<Message> items;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://pms.vebific.com:81/chat/index/")
.addConverterFactory(GsonConverterFactory.create())
.build();
MyAPI myAPI = retrofit.create(MyAPI.class);
Call<List<Message>> call = myAPI.loadMessages(roomID);
call.enqueue(new Callback<List<Message>>() {
#Override
public void onResponse(Response<List<Message>> response, Retrofit retrofit) {
// Log.e("ResponseP", String.valueOf(response.body()));
List<Message> items = response.body();
Iterator iterator = items.iterator();
while (iterator.hasNext()) {
Message message = (Message) iterator.next();
String user = message.getUser();
//Log.e("User", user);
}
int statusCode = response.code();
//Log.e("StatusCode", String.valueOf(statusCode));
adapter = new MyAdapter(getApplicationContext(), items);
lv.setAdapter(adapter);
}
#Override
public void onFailure(Throwable t) {
}
});
//--------------POST-------------
Retrofit retrofit1 = new Retrofit.Builder()
.baseUrl("http://phpstack-11819-25991-62288.cloudwaysapps.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
MyAPI myPostApi = retrofit1.create(MyAPI.class);
User user = new User("j#yahoo.com", "Admin123#");
Call<User> call1 = myPostApi.login(user);
call1.enqueue(new Callback<User>() {
#Override
public void onResponse(Response<User> response, Retrofit retrofit) {
Log.e("Response code ", String.valueOf(response.code()));
User user1 = response.body();
Log.e("Response Message",response.message());
}
#Override
public void onFailure(Throwable t) {
}
});
}
}
I have succesfully handled GET request method using this library but i am not able to understand how to read the response after posting data to server using this library.Here i am sending email ID and password to server using Retrofit library.I am getting the status code as 200 here.It means everything is working fine.I know after posting data to server successfully,i am getting some response string .But here i am unable to view the response.Please help.
as you said you got response code 200 it means there is no issue with your request and response.
use OkHttpLoggingIntercepter class.
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient httpClient = new OkHttpClient();
httpClient.interceptors().add(logging);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient)
.build();
you will get detailed log of your response and all the errors if any.
one more thing Gson Converter only parse json data which has json object at root. not JsonArray.
so check your response string as well in log by writing above code.
try to send this POST request via Postman plugin for Chrome, maybe your User class is wrong