How to use Retrofit in Android POST method along with body? - java

I have one url with request parameter is in JsonFormat like
{"EmailAddress":"user#gmail.com","PassWord":"password"} it's requested parameter.
When i used in POSTMAN then its okey.but when i request with program then that time i got error response. ihave tried till like this please see this snippet.
public class LoginModel {
#SerializedName("EmailAddress")
public String userName;
#SerializedName("PassWord")
public String userPass;
}
#Override
public String toString() {
Log.e("POSTLOGIN_MODEL" , userName+"||"+userPass);
return "{" +
"EmailAddress='" + userName + '\'' +
", PassWord='" + userPass + '\'' +
'}';
}
}
After that i used Interface.
public interface ApiService {
#FormUrlEncoded
#POST("/json/syncreply/AuthenticateUserRequest?")
Call<LoginResponse> LoginService(#Field("EmailAddress") String userName, #Field("PassWord") String userPass, Callback<LoginResponse> callBack);
After that i used to call this interface method through activity.
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(input_username.getText().toString() != null && input_password.getText().toString() != null
&& !input_username.getText().toString().isEmpty() && !input_password.getText().toString().isEmpty()){
LoginModel loginCredentials = new LoginModel();
loginCredentials.userName = "test#gmail.com";
loginCredentials.userPass = "password";
String request = "{\"EmailAddress\":\"raj#gmail.com\"," +
"\"PassWord\":\"pass\"}";
sendPost(loginCredentials);
}else{
Toast.makeText(getApplicationContext() , "Please enter valid Username and Password." , Toast.LENGTH_LONG).show();
}
}
});
public void sendPost(LoginModel name) {
Log.e("TAG","||"+name.userPass+"||"+name.userName);
// mAPIService.savePost(name).enqueue(new Callback<LoginModel>() {
Call<LoginResponse> call = mAPIService.LoginService(name.userName, name.userPass, new Callback<LoginResponse>() {
#Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
Log.e("TAG" , "RESPONSE"+"||"+response.body());
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
Log.e("TAG" , "FAILURE"+"||"+t.getMessage());
}
});
}
Thanks In Advance.any answer will appriciated.my english is please avoid it.

Hey Rajan use Request body to pass Json
String request = "{\"EmailAddress\":\"raj#gmail.com\"," + "\"PassWord\":\"pass\"}";
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),request);
#Headers("Content-Type: application/json; charset=utf-8")
#POST("/json/syncreply/AuthenticateUserRequest")
Call<ResponseBody> AuthenticateUserRequest(#Body RequestBody body);
aCall.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccessful()) {
ResponseBody responseBody = response.body();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});

First on your rest client interface side change the method like below, instead of taking email and password both seperately take only one ArrayList of String there :
#FormUrlEncoded
#POST(WEBSERVICE_NAME)
Call<ModelClass> methodName(
#Field("parameters" + "[]") ArrayList<String> paramsArrayList
);
Now, convert your arraylist of model class in to JSON string using GSON library like this,
private ArrayList<String> getModelClassArrayinString(ArrayList<ModelClass> arrayList) {
ArrayList<String> arrayListString = new ArrayList<>();
for (int i = 0; i < arrayList.size(); i++) {
arrayListString.add(new Gson().toJson(arrayList.get(i)).toString());
}
return arrayListString;
}
So your final call will be like this :
Call<LoginResponse> call = mAPIService.LoginService(getModelClassArrayinString(arrayListofModelClass), new Callback<LoginResponse>() {
#Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
Log.e("TAG" , "RESPONSE"+"||"+response.body());
}
#Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
Log.e("TAG" , "FAILURE"+"||"+t.getMessage());
}
});

Related

How to retrieve a value from list in retrofit

here my module
public class SPSOnHand {
#SerializedName("ITEM_CODE")
#Expose
private String ITEM_CODE;
#SerializedName("ITEM_DESCRIPTION")
#Expose
private String ITEM_DESCRIPTION;
public String getITEM_CODE() {
return ITEM_CODE;
}
public void setITEM_CODE(String item_code) {
ITEM_CODE = item_code;
}
public String getITEM_DESCRIPTION() {
return ITEM_DESCRIPTION;
}
public void setITEM_DESCRIPTION(String item_description) {
ITEM_DESCRIPTION = item_description;
}
here my rest service class
public class RestService {
private static final String URL = "http://localhost:58364/";
private retrofit.RestAdapter restAdapter;
//private InstituteService apiService;
private SPInventoryService apiService;
public RestService()
{
restAdapter = new retrofit.RestAdapter.Builder()
.setEndpoint(URL)
.setLogLevel(retrofit.RestAdapter.LogLevel.FULL)
.build();
apiService = restAdapter.create(SPInventoryService.class);
}
public SPInventoryService getService()
{
return apiService;
}
here my service
#GET("/api/SPSOnHand/itemcode/{item_code}")
public void getItemCode(#Path("item_code") String itemcode,
Callback<ArrayList<SPSOnHand>>callback);
here my main activity class
String itemcode;
Intent intent = getIntent();
itemcode =intent.getStringExtra("itemcode");
restService.getService().getItemCode(itemcode, new Callback<ArrayList<SPSOnHand>>() {
#Override
public void success(ArrayList<SPSOnHand> spsOnHands, Response response) {
item_description.setText(String.valueOf(spsOnHands.get(0)));
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(AirJet.this, error.getMessage().toString(),
Toast.LENGTH_LONG).show();
}
});
I want that item_description to contain a word like this
"ID": 167,
"ITEM_CODE": "3020240002",
"ITEM_DESCRIPTION": "CONTROLLER LME22.331c2 (CONTROL BOX)"
thanks in advance, I'm still a newbie in retrofit
Because of String.valueOf(spsOnHands.get(0)) whole item of list converted to String so that's why you are getting wrong format of text.
Use below code for set text in textview:
int id = 0+1;
String itemCode = arrayList.get(0).getITEM_CODE();
String itemDescription = arrayList.get(0).getITEM_CODE();
item_description.setText("\"ID\":"+ id+" \n\"ITEM_CODE\":" + itemCode+" \n\"ITEM_DESCRIPTION\":"+itemDescription);
You can change format of text in textview according to your requirement.
In your case, you receive ArrayList. And if you want to get the item from List then you have to pass index and get value List, like below. It will give you ITEM_DESCRIPTION for the 0th index of your List.
restService.getService().getItemCode(itemcode, new Callback<ArrayList<SPSOnHand>>() {
#Override
public void success(ArrayList<SPSOnHand> spsOnHands, Response response) {
item_description.setText(String.valueOf(spsOnHands.get(0).ITEM_DESCRIPTION));
}
#Override
public void failure(RetrofitError error) {
Toast.makeText(AirJet.this, error.getMessage().toString(),
Toast.LENGTH_LONG).show();
}
});

Spring gets Null values from Retrofit

I am trying to send POST Request from Android to Spring via Retrofit from past 2 days. I have tried plenty of solutions regarding this, but nothing seems to be working. So, asking here finally to be able to get some help.
So, i am trying to send a simple Object from Android to Spring via retrofit. From android side i have verified the values sent by me and it gives me correct value.(I have debugged it via Android's debugging mode). But on spring side i got null values.
This is my code ->
function foo() -> from which i am sending my request.
private void foo() {
request.setName1("XYZ");
request.setName2("PQR");
Api.upload(request, new Callback<BasicResponse>() {
#Override
public void onResponse(Call<BasicResponse> call, Response<BasicResponse> response) {
Log.d(TAG, "onResponse: Success" + response.toString());
}
#Override
public void onFailure(Call<BasicResponse> call, Throwable t) {
Log.d(TAG, "onResponse: Failure");
}
});
}
}
my upload Function ->
public static void upload(Request request, Callback<BasicResponse> callback) {
uploadRequest api = retrofit.create(uploadRequest.class);
Call<BasicResponse> call = uploadRequest.uploadCall(POJO);
call.enqueue(callback);
}
This is my UploadRequest Interface ->
public interface uploadRequest{
#POST(UPLOAD_REQUEST)
Call<BasicResponse> uploadCall(#Body POJO pojo);
}
This is My POJO Class
public class POJO {
private String Name1;
private String Name2;
public String getName1() {
return Name1;
}
public void setName1(String name1) {
Name1 = name1;
}
public String getName2() {
return Name2;
}
public void setName2(String name2) {
Name2 = name2;
}
}
And this is my Spring Controller Method
#RequestMapping(value = "/UploadRequest",method = RequestMethod.POST,consumes = "application/json", produces = "application/json")
#ResponseBody
public void UploadImage(#RequestBody POJO pojo,HttpServletRequest request) {
if(pojo!=null){
System.out.println("pojo is not null");
System.out.println(pojo.getName1());
}
else{
System.out.println("null");
}
}
I am getting pojo is not null and inside the pojo.getName1(), the value prints is null.
Edit : Adding BasicResponse Class.
public class BasicResponse {
private boolean success = Boolean.TRUE;
private ErrorCode errorCode;
private String response;
private Integer totalCount;
private String callingUserId;
public BasicResponse() {
super();
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public ErrorCode getErrorCode() {
return errorCode;
}
public void setErrorCode(ErrorCode errorCode) {
this.errorCode = errorCode;
this.success = false;
}
public String getResponse() {
return response;
}
public void setResponse(String response) {
this.response = response;
}
public void setResponse(Object response) {
if (response != null) {
this.response = GsonUtils.toGson(response);
}
}
public Integer getTotalCount() {
return totalCount;
}
public void setTotalCount(Integer totalCount) {
this.totalCount = totalCount;
}
public String getCallingUserId() {
return callingUserId;
}
public void setCallingUserId(String callingUserId) {
this.callingUserId = callingUserId;
}
}
Compare the response and your POJO class. The instance variables of your POJO class must be the same as in response. In your case Name1 and Name2. If they are name1, name2 in the response (which means if they do not start with capital letters, etc.), or different, it gives you NullPointerException.
Most likely Name1 and Name2 have different names in json than in your POJO and Jackson, with is used under the hood when you annotate your parameters with #RequestBody can not figure them out, so you get null values. Check out your json.

Publisher/Subscriber in JAX-RS - List not updating

So I'm trying to implement a publisher/subscriber pattern in JAX-RS however it seems that after the subscriber subscribes the publisher cannot find the subscription.
Server Code:
#GET
#Path("{id}/subscribe")
public void subscribe(#Suspended AsyncResponse asyncResponse, #PathParam("id") Long id) {
if (responses.containsKey(id)) {
responses.get(id).add(asyncResponse);
} else {
List<AsyncResponse> newList = new ArrayList<>();
newList.add(asyncResponse);
responses.put(id, newList);
}
System.out.println(responses.size());
}
#POST
#Path("{id}/publish")
#Consumes(MediaType.TEXT_PLAIN)
public void publish(String message, #PathParam("id") Long id) {
System.out.println(responses.size());
List<AsyncResponse> responseList = responses.get(id);
if (responseList == null) {
return;
}
for (AsyncResponse response : responseList) {
response.resume(message);
}
responseList.clear();
}
Client Code:
public void subscribeToConcertNews(ConcertDTO concertDTO) {
Response response = null;
String url = CONCERT_URL + "/" + concertDTO.getId() + "/subscribe";
ClientBuilder.newClient().target(url)
.request()
.async()
.get(new InvocationCallback<String>() {
#Override
public void completed(String s) {
System.out.println(s);
_client.target(CONCERT_URL + "/" + concertDTO.getId() + "/subscribe")
.request()
.async()
.get(this);
}
#Override
public void failed(Throwable throwable) {
throw new ServiceException("");
}
});
}
public void publishToConcertNews(ConcertDTO concertDTO, String message) {
Response response = _client.target(CONCERT_URL + "/" + concertDTO.getId() + "/publish")
.request()
.post(Entity.entity("News!", MediaType.TEXT_PLAIN));
}
Testing Code:
ConcertDTO concertDTO = new ConcertDTO(1L, "123", new HashSet<>(), new HashMap<>(), new HashSet<>());
_service.subscribeToConcertNews(concertDTO);
_service.publishToConcertNews(concertDTO, "213123");
After the subscription, the size of the map is 1, however news is attempted to be published it reads that the size of the map to hold the responses is 0. So the AsyncResponse stored in the map is disappearing. Any help would be appreciated!

Android Retrofit 2 post request responses with name of response class

In my app I make post request to the server with a special code inside the body. Then I should get some information in the response. However, I always get the name of the response class.
My request code:
#POST("/accounts/login/vk-oauth2/")
Call<RegistrationProcessCodeResponse> postCode(#Body CodePostRequest code);
My ResponseClass:
public class RegistrationProcessCodeResponse {
private String message;
private String partial_token;
private String phase;
public String getMessage() {
return message;
}
public String getPartial_token() {
return partial_token;
}
public String getPhase() {
return phase;
}
public void setMessage(String message) {
this.message = message;
}
public void setPartial_token(String partial_token) {
this.partial_token = partial_token;
}
public void setPhase(String phase) {
this.phase = phase;
}
}
My request code:
HseAlumniApi hseAlumniApi = HseAlumniApi.retrofit.create(HseAlumniApi.class);
Call<RegistrationProcessCodeResponse> postComment = hseAlumniApi.postCode(codePostRequest);
postComment.enqueue(new Callback<RegistrationProcessCodeResponse>() {
#Override
public void onResponse(Call<RegistrationProcessCodeResponse> call, Response<RegistrationProcessCodeResponse> response) {
Log.d("myLogs", "String.valueOf(response.code())\n" + String.valueOf(response.code()));
Log.d("myLogs", "response.body().toString()\n" + response.body().toString());
if (response.isSuccessful()) {
Log.d("myLogs", "Request succeeded");
}
}
#Override
public void onFailure(Call<RegistrationProcessCodeResponse> call, Throwable t) {
Log.d("myLogs", "Request failed");
}
});
My logs:
D/myLogs: String.valueOf(response.code())
200
D/myLogs: response.body().toString()
com.example.vitaly.hsealumni.RegistrationProcessCodeResponse#498e7e7
D/myLogs: Request succeeded
Response Json:
{
"message": "email needed",
"partial_token": "231445d4fc5a4ed99dccb681942d5d7e",
"phase": 1
}
I really have no idea what to do, help please
public class RegistrationProcessCodeResponse {
private String message;
private String partial_token;
private String phase;
public RegistrationProcessCodeResponse() {
message = "";
partial_token = "";
phase = "";
}
// getters and setters
#Override
public String toString() {
return "RegistrationProcessCodeResponse{" +
"message='" + message + '\'' +
", partial_token='" + partial_token + '\'' +
", phase='" + phase + '\'' +
'}';
}
}

Why does the state of an object declared as final seem to be reset even when it's altered inside an anonymous function?

I use "token", instance of the ValueContainer class declared as final, in order to save data received from a JSON request. Inside the anonymous function, Response.Listener(), I set the value of token and it works.
Log.d("myTag", "token value1:" + token.getValue());
This line displays a correct value (non null). However, when I check the value of token.getValue() again (this time outside the anonymous function)
Log.d("myTag", "token value2:" + token.getValue());
I get token.getValue() = null. I don't understand why token's value seems to be reset to null. Am I missing something?
The full code:
public class MainActivity extends AppCompatActivity {
class ValueContainer<T> {
private T value;
public ValueContainer() { }
public ValueContainer(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final ValueContainer<String> token = new ValueContainer<String>();
String getTokenUrl = "http://www.someurl.com/?somekey=somevalue";
JsonObjectRequest getTokenRequest = new JsonObjectRequest(
Request.Method.GET, getTokenUrl, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
token.setValue(response.getString("token"));
Log.d("myTag", "token value1:" + token.getValue());
mainTextView.append("Response: JsonObjectRequest successful: get_token: " + token.getValue() + "\n");
} catch (JSONException e) {
mainTextView.append("Response: JSONException: getString():" + e);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mainTextView.append("Response: JsonObjectRequest failed: " + error + "\n");
}
});
Log.d("myTag", "token value2:" + token.getValue());
}
You can change the "real content" of a "final" Object, but you can't change it's address, as the example said blew.
String stringTest = "test String";
StringBuffer normalTest = new StringBuffer(stringTest);
normalTest = normalTest.append(" end");
normalTest.delete(0, 5);
System.out.println(normalTest);
final StringBuffer finalTest = new StringBuffer(stringTest);
// finalTest = finalTest.append(" end"); // can't work;
finalTest.delete(0, 5);
System.out.println(finalTest);
you can test by your code as
//token = new Token("...")// can't work
token.changeTheToken("...")// work ok

Categories