I am facing an issue with Deserializing a POJO object.
Following is the structure of the POJO objects on the Service side.
Class Ball{
int field1;
int field2;
}
Class BaseBall extends Ball
{
int field3;
int field4;
}
Class BallList{
List<Ball> balls;
}
Even on the Android Client side, i have a similar structure for the POJO objects.
Code for Android Client:
RestTemplate restTemplate = new RestTemplate();
List<MediaType> acceptableMediaTypes = new ArrayList<MediaType>();
acceptableMediaTypes.add(new MediaType("application","json"));
HttpHeaders headers = new HttpHeaders();
headers.setAccept(acceptableMediaTypes);
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<BallList> response = restTemplate.exchange(
url, HttpMethod.GET, entity, BallList.class);
if(response.getStatusCode() == HttpStatus.OK)
{
result += "OK";
}
04-13 18:17:46.127: ERROR/AndroidRuntime(4359): Caused by: org.springframework.web.client.ResourceAccessExcep tion: I/O error: Unrecognized field "filed3" (Class com.xx.yy.model.Ball), not marked as ignorable
On the service side, i am providing the baseball list as a response. Can anyone point me to a solution please.
This is not really Android problem. The system looks at your stuff from Ball level and hence you get Unrecognized field "field3" exception. Also I would declare acceptibleMediaType as ArrayList since List is not serializable.
I would try to create and send ArrayList<BaseBall> just to see if it works and then go from there
Spring Recently released (3.2.0.RELEASE) and they added MappingJackson2HttpMessageConverter which solved a similar problem I had. MappingJackson2HttpMessageConverter uses Jackson 2 for deserialization while MappingJacksonHttpMessageConverter uses pre-2.0 Jackson. Try adding following converter to your RestTemplate and give it a shot.
MappingJackson2HttpMessageConverter map = new MappingJackson2HttpMessageConverter();
messageConverters.add(map);
restTemplate.setMessageConverters(messageConverters);
Related
Is there any way to Log Gson parsing filed by Field? Log should print name of filed and corresponding value received in response.
Example: Model class looks something like this
public class Item{
#SerializedName("ItemCode")
#Expose
private String ItemCode;
#SerializedName("ItemSN")
#Expose
private String ItemSN;
#SerializedName("ItemDesc")
#Expose
private String ItemDesc;
--getter setter methods--
}
And if response looks as follows:
{
"ItemCode":"A12"
"ItemSN":"123455672"
"ItemDesc":"Google Pixel"
}
At the time of Gson parsing following log should be generated
ItemCode is A12
ItemSN is 123455672
ItemDesc is Google Pixel
I want this to solve following problem. If any other solution works for this kind of problem please suggest.
One API (say init API) for my application returns JSON response which I am parsing using Retrofit-Gson-RxJava, We have two environment setup Test and Prod for prod environment response is getting parsed successfully but for test environment I am getting NumberFormatException which obviously tell us some Numeric filed is having non Numeric value in response.
As the size of response is huge with so many objects nested inside one another hence its getting difficult to find out exact field for which parsing is getting failed.
Add HttpLoggingInterceptor: compile "com.squareup.okhttp3:logging-interceptor:3.3.1"
public static Retrofit getInstance() {
if (instance == null) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(logging); // <-- this is the important line!
instance = new Retrofit.Builder().baseUrl(Constant.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
}
return instance;
}
I am working in an Android app that gets the data from the Server through REST services.
Now I have to make a POST on the REST service with a Body. But i am having problem doing that. I am using SPRINGFRAMEWORK to communicate with the REST service. But I am having this error:
org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error
Here is my code for posting:
org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error
final String url = "http://mywebsite.com/login";
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Credentials> entity = new HttpEntity<>(credentials ,requestHeaders);
//the object "CREDENTIALS" has the valus that should be sent as BODY in the REST Service
For posting i used two ways, but none of them worked:
ResponseEntity<AllData> response = restTemplate.exchange(url, HttpMethod.POST, entity, AllData.class);
or
ResponseEntity<AllData> response = restTemplate.postForEntity(url, entity, AllData.class );
Any idea why I am having this problem??
P.s. I checked many of the questions that were like me but in none of them I could find a answer. I am trying since some days but can't figure out what the problem is :#
I was exactly the same problem, and I managed to solve it. Bringing to your example I needed to change the Credentials entity type to the same ResponseEntity type. Would be like this :
final String url = "http://mywebsite.com/login";
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setContentType(MediaType.APPLICATION_JSON);
AllData allData = new AllData();
HttpEntity<AllData> entity = new HttpEntity<>(allData, requestHeaders);
ResponseEntity<AllData> response = restTemplate.exchange(url, HttpMethod.POST, entity, AllData.class);
Since you say it's working from postman and other I'm guessing it's an encoding or headers issue.
I guess the easiest way to find the problem will be to use a proxy like fiddler and check the compare the headers and data sent from the Android device to those sent by postman or another tool
I'm trying to parse server message which is sent when something went wrong. Message is sent in JSON:
{
"Message" : "readable reason",
"Id" : 0, // reason code
}
Model class for error:
public class RetrofitError
{
private String message;
private int id;
}
Retrofit is created with this code:
RestAdapter.Builder builder = new RestAdapter.Builder();
builder.setLog(new AndroidLog(LOG_TAG));
builder.setLogLevel(LogLevel.FULL);
builder.setEndpoint(Constants.getUrl());
builder.setRequestInterceptor(requestInterceptor);
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
gsonBuilder.setPrettyPrinting();
Gson gson = gsonBuilder.create();
builder.setConverter(new GsonConverter(gson));
RestAdapter restAdapter = builder.build();
And the error retrieving:
RetrofitError error = (RetrofitError)retrofitError.getBodyAs(RetrofitError.class)
It works without exceptions, so it seems that I'm doing something like correct. But it constantly fails to parse both fields in the response. Retrofit is created only once, and it successfully retrieves and parses all server responses with except of an error one.
I'm using latest available Retrofit jar - 1.4.1
What am I doing wrong?
Try doing this if you are still facing this issue. I know this is a very old question but it might help others.
if (restError != null)
failure(restError);
else
{
failure(new RestError(error.getMessage()));
}
Simple Solution with getBodyAs to get a JSON Object.
JsonObject responseAsJson = (JsonObject) retrofitError.getBodyAs(JsonElement.class);
String message = responseAsJson.get("Message").getAsString(); //=> "readable reason"
Integer id = responseAsJson.get("Id").getAsInt(); //=> 0
Confirmed working in Retrofit 1.x. Not sure what changes are required for Retrofit 2.x.
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've been looking online for how to pass parameters to RESTlet webservice but it seem there are not much tutorial concerning RESTlet.
I would like to send some parameters gathered from a form on my android application (it would be great if i could do this using JSON).
well i solved this
as for the server side
#Post
public JSONArray serverSideFunction(Representation entity)
throws JSONException {
try {
JSONObject req = (new JsonRepresentation(entity)).getJsonObject();
System.out.println(req.getString(/* filed name */));
System.out.println(req.getString(/* filed name */));
/*
* you can retrieve all the fields here
* and make all necessary actions
*/
} catch (IOException e) {
e.printStackTrace();
}
}
as for the Android Side
HttpClient client = new DefaultHttpClient();
String responseBody;
JSONObject jsonObject = new JSONObject();
try{
HttpPost post = new HttpPost(WebService_URL);
jsonObject.put("field1", ".........");
jsonObject.put("field2", ".........");
StringEntity se = new StringEntity(jsonObject.toString());
post.setEntity(se);
post.setHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setHeader("Content-type", "application/json");
Log.e("webservice request","executing");
ResponseHandler responseHandler = new BasicResponseHandler();
responseBody = client.execute(post, responseHandler);
/*
* You can work here on your responseBody
* if it's a simple String or XML/JSON response
*/
}
catch (Exception e) {
e.printStackTrace();
}
I hope this may be of help
In fact, it depends on what you want to do. With REST (see http://en.wikipedia.org/wiki/Representational_state_transfer), there are two ways to pass parameters or data. Before you need to understand some concepts:
Resource: the REST entity by itself.
Representation: corresponds to its state and can be gotten or updated using different HTTP methods. The kind of content is identified using the content type header (media type in Restlet).
Methods: the GET method is used to get the resource state, PUT to update it, POST to create a new resource and specify its state the same time, DELETE to delete a resource.
Restlet provides Java entities for REST elements.
So, after described that, you can see that passing data or parameters depends of your use case:
1°) Do you want to update the resource state? In this case, you will use the content of the request with methods like POST or PUT. The data structure is free from text, JSON, XML or binary... Restlet provides the ClientResource class to execute requests on RESTful applications. It also provides support to build the representation to send and extract data from the one received. In this case, your data gathered from a form will be used to build the representation. Here are some samples:
//Samples for POST / PUT
ClientResource cr = new ClientResource("http://...");
cr.post(new StringRepresentation("test"));
MyBean bean = new MyBean();
(...)
//Jackson is a tool for JSON format
JacksonRepresentation<MyBean> repr
= new JacksonRepresentation<MyBean>(bean);
cr.put(repr);
//Samples for GET
Representation repr1 = cr.get();
bean = (new JacksonRepresentation<MyBean>(repr1, MyBean.class)).getObject();
2°) Do you want to specify parameters on your GET requests (for example to configure data to retreive and so on)? In this case, you can simply add it on the ClientResource, as described below:
ClientResource cr = new ClientResource("http://...");
cr.getReference().addQueryParameter("q", "restlet");
Representation repr = cr.get();
In this case, your data gathered from a form will be used to build the parameters.
Hope it helps you.
Thierry
If you want request with json structure and your response as JSONObject maybe you can do like this in server side:
public class RequestJSON extends ServerRecource{
#Post("json")
public JSONObject testRequest(String entity){
JSONObject request = new JSONObject(entity);
String value1 = request.getString("key1");
int value2 = request.getInt("key2");
return /* your JSONObject response */;
}
}
And your request can be :
{"key1":"value1", "key2":value2}
I hope this can help you