I am using spring android framework for retrieving json data via Http GET. I am getting following exception for the same :
- Could not read JSON: Can not deserialize instance of com.springandroidjsondemo.beans.LoginBean[] out of START_OBJECT token
The bean (LoginBean) is Following
package com.springandroidjsondemo.beans;
public class LoginBean {
private String status;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
The android code is following :
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Collections.singletonList(new MediaType("application", "json")));
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
// Create a new RestTemplate instance
RestTemplate restTemplate = new RestTemplate();
// Add the Jackson message converters
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
// Make the HTTP GET request, marshaling the response from JSON to an array of Events
ResponseEntity<LoginBean[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity,LoginBean[].class); // getting exception here
LoginBean[] loginBean = responseEntity.getBody();
String status = loginBean[0].getStatus();
The json response from the server is following :
{"emp-data":[{"status":"true"}]}
I am not sure if any annotations are required for Jackson Marshalling
Please suggest the solution
Thanks!
this is a Jackson deserialization issue. if you compare the JSON response with your LoginBean, the array of statuses is contained within the element "emp-data". However, your RestTemplate request is expecting JSON which looks like the following.
[{"status":"true"},{"status":"false"}]
You have a couple options. You can create a wrapper object around LoginBean. Or you can try annotating the LoginBean like the following:
#JsonRootName(value = "emp-data")
public class LoginBean {
...
}
In order for this to work, you probably need to configure the Jackson ObjactMapper.
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
MappingJackson2HttpMessageConverter jackson = new MappingJackson2HttpMessageConverter();
jackson.setObjectMapper(objectMapper);
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(jackson);
Related
im using RestTemplate to call the authenticate web service and POST username and password,i need in return to get the token from response body but i can't find a clear way to do it..Here is my code
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Content-Type","application/json");
requestHeaders.add("Accept", "application/json");
requestHeaders.add("Authorization", auth_token);
final String url = "http://192.168.1.3:18080/api/authenticate";
RestTemplate restTemplate=new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("password",password);
map.add("username",username);
HttpEntity<MultiValueMap<String, String>> entity= new HttpEntity<MultiValueMap<String, String>>(map, requestHeaders);
String response = restTemplate.postForObject(url,entity,String.class);
return response;
and this is the response body that i need to get the token from it:web service response body
You're pretty much there, at the moment your code gets the whole JSON response as a string:
return restTemplate.postForObject(url,entity,String.class);
// {"id_token": "blahblahblah"}
Instead you can either transform to a Map and take the correct value:
Map<String, Object> response3 = restTemplate.postForObject(url, entity, Map.class);
return response3.get("id_token")
// blahblahblah
or create a class:
public class AuthResponse {
#JsonProperty( "id_token" )
private String idToken;
public String getIdToken() {
return idToken;
}
public void setIdToken(String idToken) {
this.idToken = idToken;
}
}
and transform that:
AuthResponse response4 = restTemplate.postForObject(url, entity, AuthResponse.class);
return response4.getIdToken();
// blahblahblah
I'm pretty new to both android and RESTful resources (been learning Rails and RoboSpice). I have a rails api setup correctly and for starters I'd like to pass a user name and password to the api and get a user model object back. I've been looking at the docs and examples and it's been pretty confusing. I was hoping someone could give me a quick example or point me at a good tutorial. Just for a test case, could someone walk me through this snippet and how could I adjust it to query?:
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAcceptEncoding(ContentCodingType.IDENTITY);
HttpEntity<?> requestEntity = new HttpEntity<Object>(requestHeaders);
// Create a new RestTemplate instance
RestTemplate restTemplate = new RestTemplate();
// Add the String message converter
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
// Make the HTTP GET request, marshaling the response to a String
ResponseEntity<User> response = restTemplate.exchange(url, HttpMethod.GET, requestEntity, User.class);
Also, specifically what do the headers do? and how do I set up a class to recieve the response? i.e. User.class to receive a User model. That part confuses me the most >.< It seems disorganized..
thanks for any help!
This is a very simple example:
private static final String TAG = "HTTP CLIENT: ";
public String login(String User,String Pass){
Log.d(TAG, "Login Attempt!!!");
String result = "Empty!!!";
String url = "http://somehost.somedomain.com:8080/login?email="+User+"&password="+Pass;
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
try {
result = restTemplate.getForObject(url, String.class, "");
}catch (Exception e){
result = e.getMessage();
Log.d(TAG, "Exception Message: "+e.getMessage()+" "+e.getCause());
}
Log.d(TAG, "Token: "+result);
return result;
}
in regards to the Headers they are use to set the type of content that you will handle, for example JSON or XML data.
we have a rest web service with Oracle 11g and Apex on the server side. On the client side we are developing for android, and using Spring 1.0.1 and Jackson 2.2.3 libraries to manage the requests of the rest webservices and convert the json data back into a pojo.
It works very well when the webservice is a "query". The resultset-Json data is converted in
an array of Pojos without problem. But when we try to do the same with a oracle procedure, it fails with an exception.
The Json data returned by the procedure is the following:
{"item":"{\r\n \"user\" : \"{john}\",\r\n \"profile\" : \"nothing\"\r\n}"}
I tried an online Json validator, and the Json data appears to be valid. In the header you can also see that the type is "application/json".
The pojo object is as follows:
public class User {
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
private String user;
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
private String profile;
}
The code that calls the webservice and tries to convert json to pojo is the following (copied from the spring examples):
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
User users = restTemplate.getForObject(url, User.class);
And at last, the exception when it tries to do "getForObject":
org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [com.xxx.xxx] and content type [text/plain;charset=iso-8859-1]
I tried to do the same with the Gson library instead the Jackson library, and the same exception is trown. Now I'm blocked since a couple of days...
Any ideas? What I'm doing wrong?
Thanks in advance,
The problem is with the JSON you are returning and the class you have declared. Your JSON structure is {"item":"{\r\n \"user\" : \"{john}\",\r\n \"profile\" : \"nothing\"\r\n}"} which doesn't map to the User class. The Json Structure that maps to the user class is
{\r\n \"user\" : \"{john}\",\r\n \"profile\" : \"nothing\"\r\n}
So you will have to either change the JSON response in the Rest Service.
Or add a new class structure like this
public class UserItem {
User user;
//the usual setter getter
}
Then the Rest Call will be like this :
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
UserItem item = restTemplate.getForObject(url, UserItem .class);
User user = item.getUser();
I am new to work with RestTemplates.In my application i am trying to send request by using post method as follows
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(new MediaType("application","json",Charset.forName("UTF-8")));
requestHeaders.add("username", "sai3");
requestHeaders.add("password", "x");
requestHeaders.add("device_id", device_id);
HttpEntity<String> requestEntity = new HttpEntity<String>(requestHeaders);
// Create a new RestTemplate instance
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
` restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
ResponseEntity<GetResponseBean> responseEntity1 = restTemplate.exchange(url, HttpMethod.POST, requestEntity, GetResponseBean.class);
obj = responseEntity1.getBody();
Log.v("GetDataResponse", "result message : "+obj);
For the above code i have used "spring-android-core-1.0.1.RELEASE.jar","spring-android-rest-template-1.0.1.RELEASE.jar" and "jackson-all-1.9.8.jar"
If I use ResponseEntity type is String then it is returning fine response but If I change ResponseEntity type GetResponseBean type then i am getting error as follow :
Caused by: org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [com.example.springsxmlposting.GetResponseBean] and content type [text/html]
GetResponseBean class as follows:
public class GetResponseBean {
String result = null;
String message = null;
public void setmResult(String result) {
this.result = result;
}
public String getmResult() {
return result;
}
public void setmMessage(String message) {
this.message = message;
}
public String getmMessage() {
return message;
}
}
How can i get the data into my bean class (GetResponseBean) please any body help me
I think the problem relies in your server. You're sending content-type: application/json but as you can see in your error, it states that the response you get is text/html and not application/json.
My guess is that the response you're getting back is an error html page that states that you don't have a request that returns application/json. You can try and use an external tool for sending the request to the server. Do a POST request with the same headers and I bet you'll get an HTML error page.
Jax-rs service return HTTP Status 405 - Method Not Allowed.
Service:
#GET
#Consumes(MediaType.TEXT_HTML)
#Produces(MediaType.APPLICATION_JSON)
#Path("login")
public User Login(#QueryParam("u") String username, #QueryParam("p") String password) {
return UserDAO.getInstance().getLogin(username,password)
}
Android:
public static Boolean Login(User user) {
String url = "http://myserver.com/AndroidServis/rest/login?u={u}&p={p}";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HashMap<String, String> params = new HashMap<String, String > ();
params.put("u", user.getUsername().toString());
params.put("p", user.getPassword().toString());
HttpEntity entity = new HttpEntity(headers);
restTemplate.getMessageConverters().add(new GsonHttpMessageConverter());
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
HttpEntity < Korisnici > response = restTemplate.exchange(url, HttpMethod.GET, entity,User.class, params);
}
It doesn't make sense for the server to have a #Consumes annotation on the #GET method, as this is typically only used for PUT or POST requests where the client is sending some content to the server.
Can you remove this?
Then also remove this from the client code.
headers.setContentType(MediaType.APPLICATION_JSON);
and you may need to uncomment the line you have commented out:
headers.set("Accept", "application/json");
This tells the server what content type is expected in the response so must match what the #Produces of the service.