Retrofit - POST request with #Path and without parameters - android

The request to API as follows:
POST /verify/phone/{userid}/
Mandatory parameters: userid (integer)
Return: nothing
I receive Bad Request error all the time if I want to verify user with id 1 (for example):
Response{protocol=http/1.1, code=400, message=Bad Request, url=http://dummyapi.com/verify/phone/1/}
Posting the same request using Postman works well.
Code:
#POST("/verify/phone/{userid}/")
Call<String> postVerifyPhone(#Path("userid") int userId);
public void postVerifyPhone(int userID){
showProgressBar();
RestClient.GitApiInterface service = RestClient.getClient();
Call<String> call = service.postVerifyPhone(userID);
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Response<String> response) {
hideProgressBar();
if (response.isSuccess()) {
String result = response.body();
} else {
Log.d("Fail: ", response.body()); //everytime here with Bad Request
}
}
#Override
public void onFailure(Throwable t) {
hideProgressBar();
}
});
}
I'm using String as the return type since there's message returned when there're no user with requested ID in db.
What could be a cause?

I am calling below code for reading response data.
public void postVerifyPhone(int userID){
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Constants.URL).build();
RetrofitApi retrofitApi = restAdapter.create(RetrofitApi.class);
retrofitApi.postVerifyPhone(userID, new Callback<Response>() {
#Override
public void success(Response response, Response response2) {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(response.getBody().in()));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
String result = sb.toString();
// System.out.println("res:" + result.toString());
}
#Override
public void failure(RetrofitError error) {
hidePDialog();
}
});
}
below is postVerifyPhone() code
#FormUrlEncoded
#POST("/verify/phone/")
public void postVerifyPhone(#Field("userID") String userID, Callback<Response> resonse);
It is working fine for me.please check it once.

I think the right annotation is #PathParam, not #Path

Related

Access sent parameter in onResponse of retrofit 2

I create a request with retrofit2 and send parameter to server, how can access sent parameter in onResponse?
retrofit = new Retrofit.Builder()
.baseUrl("baseAddress")
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiBase serviceSetParam = retrofit.create(ApiBase.class);
Call<String> myCall = serviceSetParam.setParam("data1","data2");
Callback<String> myCallback = new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
//i need access data1 & data2 Here !
if (response.isSuccessful()) {
String mResponse= response.body();
} else {
Utils.Log("unSuccessful");
}
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Utils.Log("onFailure");
}
};
myCall.enqueue(myCallback);
here the send param method:
#FormUrlEncoded
#POST("set")
Call<String> setParam(#Field("param1") String param1, #Field("param2") String param2);
in onResponse method of your request, test this code:
try {
BufferedSink bf = new Buffer();
call.request().body().writeTo(bf);
Log.i("params are",bf.buffer().readUtf8().toString());
} catch (IOException e) {
e.printStackTrace();
}
You need to get the original Request from OkHttp.
List<String> pathSegments = original(response.raw()).url().pathSegments();
given:
static Request original(Response response) {
while (true) {
Response prior = response.priorResponse();
if (prior == null) {
break;
}
response = prior;
}
return response.request();
}

How to post oauth API for login using Retrofit 1.9.0 in Android

I have done successfully registration using below API but I'm not able to login
got error message from server Retrofit:
{"code":401,"message":"Authentication failed","error":{"reason":"authError"}
This is my interface:
public static final String BASE_URL= "http://ashwinku.fwd.wf/ssng-project/api";
public static final String REGISTER_OPERATION = "/registerUser";
public static final String LOGIN_OPERATION = "/loginUser";
This is my User(Bean) Class for login:
public User(String firstName, String password) {
this.firstName=firstName;
this.password = password;
}
This is my Login fragment:
private void loginuser(String firstName, String password) {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(Constants.BASE_URL)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
//Creating object for our interface
RequestInterface api = restAdapter.create(RequestInterface.class);
user = new User(firstName,password);
user.setFirstName(firstName);
user.setPassword(password);
//Defining the method insertuser of our interface
api.loginuser(user, new Callback<User>() {
#Override
public void success(User result, Response response) {
BufferedReader reader = null;
//An string to store output from the server
String output = "";
try {
//Initializing buffered reader
reader = new BufferedReader(new InputStreamReader(response.getBody().in()));
//Reading the output in the string
output = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
//Displaying the output as a toast
Toast.makeText(getActivity(), output, Toast.LENGTH_LONG).show();
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
}
});
}
I using 1.9.0 retrofit but not able to login. Please help. It gives me error.
Try this out
api.loginuser(user, new Callback<User>() {
#Override
public void success(User result, Response response) {
//Try to get response body
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
String result = sb.toString();
Toast.makeText(getActivity(), result, Toast.LENGTH_LONG).show();
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(getActivity(), error.toString(), Toast.LENGTH_LONG).show();
}
});
Also i just noticed that you are getting 401 error code, which means - Unauthorized: Access is denied due to invalid credentials
So that could be the problem too, you need to fix that on your side.
hope it helps

Logical error in getting a text from URL with okHttp

Im trying to write an app to read a text file from an url like this "http://chemvaaj.xzn.ir/test/words.txt"
it seems right but it doesn't return what it should :\
here's my code :
public String DL (){
OkHttpHandler handler = new OkHttpHandler();
String text ="";
try {
text = handler.execute().get();
if (text!= null && text.length()> 0){
System.out.println("not empty");
return text;
}
} catch (Exception e) {
text= "empty !!";
}
return text;
}
and here is OkHttpHandler class :
public class OkHttpHandler extends AsyncTask<Void, Void, String> {
private final String DB_URL = "http://chemvaaj.xzn.ir/test/words.txt";
OkHttpClient httpClient = new OkHttpClient();
#Override
protected String doInBackground(Void... params) {
Request.Builder builder = new Request.Builder();
builder.url(DB_URL);
Request request = builder.build();
try {
Response response = httpClient.newCall(request).execute();
return response.body().toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.e("ANSWER", "" + s);
}
}
and here's my logcat after call DL() function :
10-28 00:23:25.167 17288-17288/erfan.bagheri.chemvaaj E/ANSWER﹕ com.squareup.okhttp.internal.http.RealResponseBody#423bc6b8
You should replace return response.body().toString(); by return response.body().string();
Please refer to my following working sample code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.textView);
new GetFileRequest().execute();
}
...
private class GetFileRequest extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... voids) {
try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://chemvaaj.xzn.ir/test/words.txt")
.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (IOException e) {
e.printStackTrace();
return e.toString();
}
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (mTextView != null && result != null) {
mTextView.setText(result);
}
}
}
Here is the screenshot
Hope this helps!
First of all, please check how an AsyncTask works. Here's the official, easy to understand how-to-use.
Then you'll find that the method execute() returns the task itself, not the resulting String object.
It seems that OkHttpClient's returned Response object can be transformed to string in the following way:
response.body().toString();
Just one more hint: please avoid returning null in any method, it's considered very bad practice.
OkHttpClient is used in the wrong way(Suppose you want to use async). OkHttp is a full featured Http client library and has Asynchronous requests implemented in itself.
So there is no need to Android AsyncTask.
Here is the right way:
private final OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://chemvaaj.xzn.ir/test/words.txt")
.build();
client.newCall(request).enqueue(new Callback() {
#Override public void onResponse(Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
}
#Override public void onFailure(Request request, Throwable throwable) {
throwable.printStackTrace();
}
});
I am not familiar with OkHttpClient but from the log I am guessing that the body response is a complex object that does not have a toString() that will show you a human readable response. You will probably have to print a specific member of that object to get your readable response.
try this
OkHttpClient and callback:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
// Headers responseHeaders = response.headers();
// for (int i = 0; i < responseHeaders.size(); i++) {
// System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
// }
// System.out.println(response.body().string());
InputStream in = response.body().byteStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String result, line = reader.readLine();
result = line;
while((line = reader.readLine()) != null) {
result += line;
}
System.out.println(result);
}
});

Retrofit: Sending POST request to server in android

I am using Retrofit to call APIs. I am sending a post request to API but in the callback I am getting empty JSON like this {}.
Below is the code for RetrofitService
#POST("/com/searchusers.php")
void getUser(#Body JSONObject searchstring, Callback<JSONObject> callBack);
where searchstring JSON is like this {"search":"nitesh"}. In response I am supposed to get the detail of user "nitesh".
Below is the code for sending POST request
RetrofitService mRetrofitService = app.getRetrofitService();
mRetrofitService.getUser(user, new Callback<JSONObject>() {
#Override
public void success(JSONObject result, Response arg1) {
System.out.println("success, result: " + result);
}
#Override
public void failure(RetrofitError error) {
System.out.println("failure, error: " + error);
}
});
I am getting this output
success, result: {}
Expected output is
success, result: {"name":"nitesh",....rest of the details}
Edit:
I tried using Response instead of JSONObject like this CallBack<Response> and then I converted the raw response into String and I got the expected result. But the problem is its in String, I want the response in JSONObject.
How can I get the exact result using CallBack<JSONObject> ...?
After waiting for the best response I thought of answering my own question. This is how I resolved my problem.
I changed the converter of RestAdapter of RetrofitService and created my own Converter. Below is my StringConverter
static class StringConverter implements Converter {
#Override
public Object fromBody(TypedInput typedInput, Type type) throws ConversionException {
String text = null;
try {
text = fromStream(typedInput.in());
} catch (IOException ignored) {/*NOP*/ }
return text;
}
#Override
public TypedOutput toBody(Object o) {
return null;
}
public static String fromStream(InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String newLine = System.getProperty("line.separator");
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append(newLine);
}
return out.toString();
}
}
Then I set this converter to the RestAdapter in the Application class.
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(BASE_URL)
.setConverter(new StringConverter())
.build();
mRetrofitService = restAdapter.create(RetrofitService.class);
Now whenever I use Retrofit, I get the response in String. Then I converted that String JSONObject.
RetrofitService mRetrofitService = app.getRetrofitService();
mRetrofitService.getUser(user, new Callback<String>() {
#Override
public void success(String result, Response arg1) {
System.out.println("success, result: " + result);
JSONObject jsonObject = new JSONObject(result);
}
#Override
public void failure(RetrofitError error) {
System.out.println("failure, error: " + error);
}
});
Hence, I got the result in JSON form. Then I parsed this JSON as required.
it may help you
JSONObject responseJsonObj = new JSONObject(responseString);

Retrofit callback get response body

I am testing Retrofit to compare it with Volley and I am struggling to get the response from my requests. For example, I do something like this:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://localhost:8080")
.build();
MyService service = restAdapter.create(MyService.class);
service.getToto("toto", new Callback<Toto>() {
#Override
public void success(Toto toto, Response response) {
// Try to get response body
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(
new InputStreamReader(response.getBody().in()));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
String result = sb.toString();
}
#Override
public void failure(RetrofitError error) {}
});
It works, the object toto is set, but for testing purposes, I also want to display the JSON response returned by the server.
So I am trying to read the InputStream from response.getBody() which is a TypedInputStream.
Unfortunately, I always get an IOException : Stream is closed.
I tried to use the Utils class from Retrofit but I get the same IOException error.
Inside callback's angle brackets write "Response" and then extract the stream from this response.
service.getToto("toto", new Callback<Response>() {
#Override
public void success(Response result, Response response) {
//Try to get response body
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
String result = sb.toString();
}
#Override
public void failure(RetrofitError error) {
}
});
Before Retrofit 2.0
String bodyString = new String(((TypedByteArray) response.getBody()).getBytes());
Retrofit 2.0
String bodyString = new String(response.body().bytes());
If you set .setLogLevel(RestAdapter.LogLevel.FULL) on the RestAdapter that you use to create the service you should get the raw JSON response output in the debug console.
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("http://my_lovely_api.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
mService = restAdapter.create(MyService.class);
If you want to do something different with this raw response you can still use the code you have in your success block to create a JSON string assuming that you keep the LogLevel.FULL in the setLogLevel method, if not then it won't parse the InputStream from response.getBody().in() as it's already been read and closed.
I recently encountered a similar problem. I wanted to look at some json in the response body but didn't want to deal with the TypedByteArray from Retrofit. I found the quickest way to get around it was to make a Pojo(Plain Old Java Object) with a single String field. More Generally you would make a Pojo with one field corresponding to whatever data you wanted to look at.
For example, say I was making a request in which the response from the server was a single string in the response's body called "access_token"
My Pojo would look like this:
public class AccessToken{
String accessToken;
public AccessToken() {}
public String getAccessToken() {
return accessToken;
}
}
and then my callback would look like this
Callback<AccessToken> callback = new Callback<AccessToken>() {
#Override
public void success(AccessToken accessToken, Response response) {
Log.d(TAG,"access token: "+ accessToken.getAccessToken());
}
#Override
public void failure(RetrofitError error) {
Log.E(TAG,"error: "+ error.toString());
}
};
This will enable you to look at what you received in the response.
Please, don't use streams and straemReaders for this.
Use smart solutions like square does:
private Response logAndReplaceResponse(String url, Response response, long elapsedTime)
http://www.programcreek.com/java-api-examples/index.php?source_dir=retrofit-jaxrs-master/retrofit/src/main/java/retrofit/RestAdapter.java
example:
private String getResponseBody(Response response) {
String result = "";
//Try to get response body
if (response.getBody() instanceof TypedByteArray) {
TypedByteArray b = (TypedByteArray) response.getBody();
result = new String(b.getBytes());
}
return result;
}
Another solution would be to do something like the following:
private static String bodyAsString(RequestBody body) {
try {
Buffer buffer = new Buffer();
body.writeTo(buffer);
return buffer.readString(body.contentType().charset());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Taken from https://github.com/square/okhttp/blob/master/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java#L93-L101
With version 2.1.0, you can get the content as
public void onResponse(Call<T> call, Response<T> response) {
String errorString = response.errorBody().string();
}
Just do it like this:
ModelClass modelclass=response.response.body()
System.out.println("****************-----retro rsp----1-------"+modelclass.getMessage());
in your model of response press cmd+n and override "toString" method and only call as response.toString();
#Override
public String toString() {
return "{" +
"key_one='" + var_keyone + '\'' +
", key_two='" + var_keytwo + '\'' +
'}';
}

Categories

Resources