How to serialize list of objects using GSON - java

I am using GSON library to send JSON response. I have a model which has a couple fields. Now my code is for sending JSON response is:
#RequestMapping(value="/sampleData/info", headers="Accept=*/*", method=RequestMethod.GET)
public #ResponseBody String getDealerInfoInJSON(#RequestParam("city") String city_id,
#RequestParam("dealer") String category_id) {
Gson gson = new Gson();
String s;
List<SampleData> foo = sampleDataService.getDealerInfo(city_id, category_id);
// foo contains [com.spring.model.SampleData#e64a0b]
List<SampleData> list = Collections.synchronizedList(
new Arraylist<SampleData>());
Iterator<SampleData> iterator = foo.iterator();
while (iterator.hasNext()) {
// Here I want to add sample data obj in list which is not working but
// new SampleData is working fine like added below:
list.add(iterator.next()) // Not working (stack overflow error)
list.add(new SampleData()); // Working
}
s = gson.toJson(list, ArrayList.class);
System.out.println(s); // This print [{}]
return s; // Works fine with a single object but not a list of objects
}
I don't know how to return JSON response of sample data objects fields. Please guide me.

You need to add property values in the sample data, otherwise you will get blank data [{}] as you are getting.
SampleData sample= new SampleData();
sample.setXXX(); // your setter methods to set data in object.
sample.setYYY();
sample.setCategory(category);
Gson gson = new Gson();
return gson.toJson(sample);

Related

Why does the String coming in POST request body come with additional quotes and get not a JSON Object

I am calling a RestFul API written in Java that consumes plain text or JSON and returns a response in JSON. I am using gson library to generate and parse my fields. I am calling the api from an Android simulation where I user retrofit2 library and GsonConverterFactory.
The generated String seems fine. I am not using a POJO, just a generic HashMap which I then convert to a String.
Generated gson from Android is {"password":"K16073","userid":"K16073"}
Code given below.
At the API service, the string received is wrapped with additional double quotes.
Printed String including the quotes in the beginning and end "{\"password\":\"K16073\",\"userid\":\"K16073\"}"
Because of this I am getting java.lang.IllegalStateException: Not a JSON Object: "{\"password\":\"K16073\",\"userid\":\"K16073\"}"
I tried to remove the quotes and then I get com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected name at line 1 column 2 path $.
/* Android code */
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(myRFReceivingApis.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Map<String, String> userData = new HashMap<>();
userData.put("userid",edtTxtUserId.getText().toString());
userData.put("password",editTxtPassword.getText().toString());
Gson gson = new Gson();
System.out.println(" generated gson " +gson.toJson(userData));
call = ApiClient.getInstance().getMyApi().callLogin(gson.toJson(userData));
call.enqueue(new Callback<Object>() {
#Override
public void onResponse(Call<Object> call, Response<Object> response) {
textViewResp.setText(response.body().toString());
:
/* End of Android code */
API Service code in Java
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
#Path("login")
public String RFLoginNew(String jsonString) {
String result = jsonString.substring(1, jsonString.length() - 1);
System.out.println(" Json String "+result);
// tried using JsonParser -- line 1 below
JsonObject o = JsonParser.parseString(result).getAsJsonObject();
// tried using Gson gson.fromJson
Gson gson = new Gson();
JsonElement element = gson.fromJson (result, JsonElement.class); //Converts the json string to JsonElement without POJO
JsonObject jsonObj = element.getAsJsonObject(); //Converting JsonElement to JsonObject
// --line 2 below
System.out.println(" RFLoginNew struser "+ jsonObj.get("userid").getAsString());
I am not getting the correct json format. I am not sure what is wrong with the way jsonString is generated.
Cause
You are making double serialization.
call = ApiClient.getInstance().getMyApi().callLogin(gson.toJson(userData));
Here your map gets serialized to json string, and then this json gets serialized a second time when request is sent.
Fix
Serialize only once on frontend - whatever library you are using(i don't do android stuff) should have method where you supply the payload as an Оbject - the method argument should be the map, userData in your case.
call = ApiClient.getInstance().getMyApi().callLogin(userData);
Something like that.
Or double deserialization on backend - deserialize to String, then deserialize the resulting string again to whatever you need.
String jsonString = gson.fromJson(doubleJson, String.class);
Map<String, String> result = gson.fromJson(jsonString, Map.class);
System.out.println(result);

How can I convert ArrayList/Set to JSON and post data using postforobject method?

I have set which contains string ["a" , "b" , "c"] , I want to POST json data like (comma seperated and one string)
Here is
JSON
{"view" : "a,b,c",
"fruits" : "apple"}
to the endpoing using Resttemplate postForObject method? I have used GSON but that is not working in my project. Are there any other alternatives?
Here is my code
private run(set<data> datas) {
Set<string> stack = new hashset<>();
iterator<data> itr = datas.iterator();
while (itr.hasnext()) {
data macro = itr.next();
if (//some condition) {
stack.add(macro);
}
}
}
}
Resttemplate.getmessageconverters().add(stringconvertor);
String result = resttemplate.postforobject(endpoint, request, String.class);
}
If the data is in a specific class like format, you could go with the POJO approach that is encouraged by Spring Boot. But looking at your example, it seems like you want to achieve a one time JSON Object response.
import org.json.simple.JSONObject;
public static void run(set<data> datas, string endpoint){
// build your 'stack' set
String joined = String.join(",", stack);
JSONObject obj=new JSONObject();
obj.put("view",joined);
obj.put("fruits","apple");
//return the jsonObject as the response to your entrypoint using your method
}
You could also try the following if you use #ResponseBody annotation in Spring Boot that will convert the Response Body to the appropriate (JSON) format.
HashMap<String, String> map = new HashMap<>();
map.put("view", joined);
map.put("fruits", "apple");
return map;

How to Split a JSON string to two JSON objects in Java

I have a JSON object as follows:
{
"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9",
"user":{
"pk":17,
"username":"user1",
"email":"user1#gmail.com",
"first_name":"",
"last_name":""
}
}
I am trying to get two JSON object from it; token and user. I have tried two different ways but both are failing:
//response.body().string() is the above json object
JSONArray jsonArray = new JSONArray(response.body().string());
jsonObjectRoot = new JSONObject(response.body().string());
Could any one please let me know how I could split this to two JSON objects?
You can split it this way:
// source object
JSONObject sourceObject = new JSONObject(sourceJson);
String tokenKey = "token";
// create new object for token
JSONObject tokenObject = new JSONObject();
// transplant token to new object
tokenObject.append(tokenKey, sourceObject.remove(tokenKey));
// if append method does not exist use put
// tokenObject.put(tokenKey, sourceObject.remove(tokenKey));
System.out.println("Token object => " + tokenObject);
System.out.println("User object => " + sourceObject);
Above code prints:
Token object => {"token":["eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"]}
User object => {"user":{"last_name":"","pk":17,"first_name":"","email":"user1#gmail.com","username":"user1"}}
You can parse a json string with
var obj = JSON.parse(jsonString);
You can filter sub parts of a json object by simply addressing them
var token = obj.token;
var user = obj.user;
The safer / cleaner way to do it is to create a POJO and deserialize your JSON into it using Jackson. Your pojo:
public class MyObject {
String token;
User user;
static class User {
int pk;
String username;
String email;
String first_name;
String last_name;
}
}
Then, when you want to deserialize:
import com.fasterxml.jackson.databind.ObjectMapper;
and
ObjectMapper mapper = new ObjectMapper();
MyObject myObject = mapper.readValue(jsonString, MyObject.class);
String token = myObject.token;
User user = myObject.user;
...
I recently faced the same situation, I used the below code which worked for me:
JSONObject jo1 = new JSONObject(output);
JSONObject tokenObject = new JSONObject();
tokenObject.put("token", jo1.get("token"));
JSONObject userObject = new JSONObject();
userObject.put("user", jo1.get("user"));
Here I am creating a new empty JSONObject and then put the retrieved object from the original object in the newly created JSONObject.
You can also verify the output by just sysout:
System.out.println("token:" + tokenObject.get("token"));
System.out.println("user:" + userObject.get("user"));
Output in my case :
token::eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
user:{"last_name":"","pk":17,"first_name":"","email":"user1#gmail.com","username":"user1"}
Yep. It is a JSON string.
Using like this
JSONParser jparse=new JSONParser();
JSONObject jObj=(JSONObject)jParse.parse(jsonString);
jObj will contain json Object now.

Convertig Json to List

I am trying to read and write a Json object to my database and I'm not getting how to convert the string you get from the database to a string and how I can use it later tp write back the changed list into my database again.
So when I'm asking the database for the field I want, I get this string back:
["[\"pw1\",\"pw2\",\"pw3\"]"]
Then I go and create an object of my class LastPasswords
List<String> passwordList = (List<String>) controllerServlet.getMacroDatabaseManager().executeNativeQuery(queryGet);
LastPasswords lastPasswords = new LastPasswords(passwordList);
Gson gson = new Gson();
String Json = gson.toJson(lastPasswords);
Here is the LastPasswords class
public class LastPasswords {
private List<String> passwords;
public LastPasswords(List<String> passwords) {
this.passwords = passwords;
}
public List<String> getPasswords(){
return passwords;
}
public void setPasswords(List<String> passwords){
this.passwords = passwords;
}
}
Then when I have this json string I try to get it as a list but I don't get the list.
lastPasswords.setPasswords((List<String>) gson.fromJson(banana, LastPasswords.class));
passwordList = lastPasswords.getPasswords();
Thanks for helping.
You can use com.google.gson.reflect.TypeToken.TypeToken to define return type of fromJson method.
Then, àter you have the list, you can create a new LastPasswords to use.
String json = "[\"pw1\",\"pw2\",\"pw3\"]";
Gson gson = new Gson();
List<String> list = gson.fromJson(json, new TypeToken<List<String>>() {}.getType());
System.out.println(list.size());
System.out.println(list);
Output:
3
[pw1, pw2, pw3]
You may use TypeToken to load the json string into a custom object.
String json = "[\"pw1\",\"pw2\",\"pw3\"]";
List<String> list = gson.fromJson(json, new TypeToken<List<String>>(){}.getType());
Or for an list of list of String
String json = "[\"[\"pw1\",\"pw2\",\"pw3\"]\"]";
List<List<String>> list = gson.fromJson(json, new TypeToken<List<List<String>>>(){}.getType());
list.get(0).get(0) == "pw1"
I would like to recommend to keep a Password class instead of keeping a ListPassword class.
Let us assume, you've a Password class like this.
public class Password {
public String password;
// Getter and setter
}
Now when you read the json string using gson, you might have to do this.
Password[] passwordArray = gson.fromJson(json, Password[].class);
This will map the json string into an array of Password. Then you might consider populating them in a list if you like.
List<Password> passwordList = Arrays.asList(passwordArray);

Converting Json to Pojo

I've recently decided to rewrite one of my older android applications and I can't figure out how to convert server response like this:
{
"response": "SUCCESS",
"data": {
"0": {
... fields ...
},
"1": {
... fields ...
},
... another objects
}
}
to regular java object (or in this case list of objects). I was previously using this method:
JSONObject response = new JSONObject(stringResponse);
JSONObject dataList = response.getJSONObject("data");
int i = 0;
while (true) {
dataList.getJSONObject(String.valueOf(i)); // here I get wanted object
i++;
}
to get relevant objects and then I can put them into List, but now I'm using Retrofit library and I'm not able to find any clean solution to parse such weird object using gson and retrofit.
Thanks for any help.
Edit: What I want:
Send request using retrofit like this:
#GET("/some params")
void restCall(... another params..., Callback<Response> callback);
and then have List of objects in Response object. What I don't know is how to declare Response object, so it can convert that weird response into normal List of objects.
You have many libraries around for this.. One i used was json-simple There you can just use:
JSONValue.parse(String);
look into gson too! i'm using it for all my projects, serializing and deserializing to pojos is remarkably simple and customizable (if needed, most things are fine out of the box)
gson
here is their first example:
class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// no-args constructor
}
}
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String json = gson.toJson(obj);
==> json is {"value1":1,"value2":"abc"}
obj = gson.fromJson( json );
==> you get back the same object

Categories

Resources