I have some model classes like Customer, Product, etc. in my project which have several fields and their setter-getter methods, I need to exchange objects of these classes as a JSONObject via Sockets to and from client and server.
Is there any way I can create JSONObject directly from the object of model class such that fields of the object become keys and values of that model class object become values for this JSONObject.
Example:
Customer c = new Customer();
c.setName("Foo Bar");
c.setCity("Atlantis");
.....
/* More such setters and corresponding getters when I need the values */
.....
And I create JSON Object as:
JSONObject jsonc = new JSONObject(c); //I'll use this only once I'm done setting all values.
Which gets me something like:
{"name":"Foo Bar","city":"Atlantis"...}
Please note that, in some of my model classes, certain properties are itself an object of other model class. Such as:
Product p = new Product();
p.setName("FooBar Cookies");
p.setProductType("Food");
c.setBoughtProduct(p);
In a case like above, as I'd expect, the yielded JSON object would be:
{"name":"Foo Bar","city":"Atlantis","bought":{"productname":"FooBar Cookies","producttype":"food"}}
I know I could create something like toJSONString() in each model class and have the JSON-friendly string created and manipulate it then, but in my previous experiences of creating RESTful service in Java (which is totally out of context for this question), I could return JSON string from the service method by using #Produces(MediaType.APPLICATION_JSON) and have the method returning object of model class. So it produced JSON string, which I could consume at the client end.
I was wondering if it's possible to get similar behavior in current scenario.
Google GSON does this; I've used it on several projects and it's simple and works well. It can do the translation for simple objects with no intervention, but there's a mechanism for customizing the translation (in both directions,) as well.
Gson g = ...;
String jsonString = g.toJson(new Customer());
You can use Gson for that:
Maven dependency:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
Java code:
Customer customer = new Customer();
Product product = new Product();
// Set your values ...
Gson gson = new Gson();
String json = gson.toJson(customer);
Customer deserialized = gson.fromJson(json, Customer.class);
User = new User();
Gson gson = new Gson();
String jsonString = gson.toJson(user);
try {
JSONObject request = new JSONObject(jsonString);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Use gson to achieve this. You can use following code to get the json then
Gson gson = new Gson();
String json = gson.toJson(yourObject);
I have used XStream Parser to
Product p = new Product();
p.setName("FooBar Cookies");
p.setProductType("Food");
c.setBoughtProduct(p);
XStream xstream = new XStream(new JettisonMappedXmlDriver());
xstream.setMode(XStream.NO_REFERENCES);
xstream.alias("p", Product.class);
String jSONMsg=xstream.toXML(product);
System.out.println(xstream.toXML(product));
Which will give you JSON string array.
Related
I need GSON mapper to throw an exception if json contains unknown fields. For example if we have POJO like
public class MyClass {
String name;
}
and json like
{
"name": "John",
"age": 30
}
I want to get some sort of message that json contains unknown field (age) that can not be deserialized.
I know there is out-of-box solution in Jackson mapper, but in our project we have been using Gson as a mapper for several years and using Jackson ends up in conflicts and bugs in different parts of project, so it is easier for me to write my own solution than using Jackson.
In other words, I want to know if there is some equivalent to Jackson's DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES in Gson. Or maybe if it can be done using Gson's DeserializationStrategy other than using reflections
I believe you cannot do it automatically with Gson.
I had to do this in a project at work. I did the following:
Gson GSON = new GsonBuilder().create();
(static final) Map<String, Field> FIELDS = Arrays.stream(MyClass.class.getDeclaredFields())
.collect(Collectors.toMap(Field::getName, Function.identity()));
JsonObject object = (JsonObject) GSON.fromJson(json, JsonObject.class);
List<String> objectProperties = object.entrySet().stream().map(Entry::getKey).collect(Collectors.toList());
List<String> classFieldNames = new ArrayList<>(FIELDS.keySet());
if (!classFieldNames.containsAll(objectProperties)) {
List<String> invalidProperties = new ArrayList<>(objectProperties);
invalidProperties.removeAll(classFieldNames);
throw new RuntimeException("Invalid fields: " + invalidProperties);
}
I need GSON mapper to throw an exception if json contains unknown fields. For example if we have POJO like
public class MyClass {
String name;
}
and json like
{
"name": "John",
"age": 30
}
I want to get some sort of message that json contains unknown field (age) that can not be deserialized.
I know there is out-of-box solution in Jackson mapper, but in our project we have been using Gson as a mapper for several years and using Jackson ends up in conflicts and bugs in different parts of project, so it is easier for me to write my own solution than using Jackson.
In other words, I want to know if there is some equivalent to Jackson's DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES in Gson. Or maybe if it can be done using Gson's DeserializationStrategy other than using reflections
I believe you cannot do it automatically with Gson.
I had to do this in a project at work. I did the following:
Gson GSON = new GsonBuilder().create();
(static final) Map<String, Field> FIELDS = Arrays.stream(MyClass.class.getDeclaredFields())
.collect(Collectors.toMap(Field::getName, Function.identity()));
JsonObject object = (JsonObject) GSON.fromJson(json, JsonObject.class);
List<String> objectProperties = object.entrySet().stream().map(Entry::getKey).collect(Collectors.toList());
List<String> classFieldNames = new ArrayList<>(FIELDS.keySet());
if (!classFieldNames.containsAll(objectProperties)) {
List<String> invalidProperties = new ArrayList<>(objectProperties);
invalidProperties.removeAll(classFieldNames);
throw new RuntimeException("Invalid fields: " + invalidProperties);
}
I have the following SP (SQL server) that return a Json output.
BEGIN
SET #jsonOutput = (
SELECT
Program.Name AS ProgramName,
ProgramOwner.FirstName AS OwnerFirstName,
FROM ProgramOwner, Program
WHERE Program.Id = ProgramOwner.ProgramOwner2Program
FOR JSON PATH,WITHOUT_ARRAY_WRAPPER)
I would like to map the return Json output to a List of ProgramDto via modelMapper. Not sure hot to do that since the return values from call.execute is an Object.
Something like this:
SimpleJdbcCall call = new
SimpleJdbcCall(jdbcTemplate).withProcedureName(programProc).declareParameters(
new SqlOutParameter("jsonOutput", Types.VARCHAR));
Map<String,Object>out = call.execute(new MapSqlParameterSource());
if(out.size()>0) {
// Only to show what I am trying to do
Type rootType = new TypeToken<List<ProgramDto>>() {}.getType();
modelMapper.map(out.get("jsonOutput"),rootType );
}
Thank you
As I understood you are trying to get a list of object from
You can use Jackson api
Like this
say for example your json is in variable named jsonData, then you can get the object you need like below.
ObjectMapper mapper = new ObjectMapper();
List<Type> myList = Arrays.asList(mapper.readValue(jsonData, Type[].class));
You can also find more examples here
In my Android app, I used Gson in order to save/load the object's Arraylist in SharedPreferences. Follows are my code using Gson.
public static ArrayList<RequestModal> getModalList(Context ctx) {
Gson gson = new Gson();
String json = getSharedPreferences(ctx).getString("ModalList", new Gson().toJson(new ArrayList<>()));
Type type = new TypeToken<ArrayList<RequestModal>>() {}.getType();
return gson.fromJson(json, type);
}
In here "RequestModal" is the simple object include a bit of strings and integers.
It works well in case "online". But if internet is offline, forever works on below code.
Type type = new TypeToken<ArrayList<RequestModal>>() {}.getType();
How can I solve it? What is the way implement the feature like this with/without using Gson? Please help me anyone having a good idea.
Thank you in advance.
You can implement this without Gson:
public static EpisodeDetails parseEpisodeDetails(String content) {
EpisodeDetails episodeDetails = new EpisodeDetails();
try {
JSONObject jsonObject = new JSONObject(content);
episodeDetails.title = jsonObject.getString("title");
episodeDetails.subTitle = jsonObject.getString("subtitle");
episodeDetails.synopsis = jsonObject.getString("synopsis");
episodeDetails.ends_on = jsonObject.getString("ends_on");
JSONArray images = jsonObject.getJSONArray("image_urls");
if (images.length() > 0) {
episodeDetails.image_url = images.getString(0);
}
} catch (JSONException e) {
e.printStackTrace();
return null;
}
return episodeDetails;
}
What I'm doing is just taking the String, in your case the one saved on the shared prefs called ModalList and inserting the values on my structure, on my code the structure is called EpisodeDetails, on your code the correspondent is RequestModal. If you don't want to do it via code and want to try another library I recommend Jackson.
Another thing, on this line:
String json = getSharedPreferences(ctx).getString("ModalList", new Gson().toJson(new ArrayList<>()));
Your second parameter is not necessary. getString takes the key to load as first parameter and a default value as second paramter (in the case of empty result). You could change this to "" or null.
Well, another solution to your problem could be TinyDB. It makes use of Gson to save ArrayLists of objects in sharedPrefs, its usage is so simple as:
Person person = new Person("john", 24);
tinydb.putObject("user1", person);
ArrayList<Person> usersWhoWon = new ArrayList<Person>();
tinydb.putListObject("allWinners", usersWhoWon);
and that's it, check out my link given above to see the usage details.
I like the idea of having a standard for JSON serialization in Java, javax.json is a great step forward you can do an object graph like this:
JsonObject jsonObject3 =
Json.createObjectBuilder()
.add("name", "Ersin")
.add("surname", "Çetinkaya")
.add("age", 25)
.add("address",
Json.createObjectBuilder()
.add("city", "Bursa")
.add("country", "Türkiye")
.add("zipCode", "33444"))
.add("phones",
Json.createArrayBuilder()
.add("234234242")
.add("345345354"))
.build();
That's it, but how can I serialize a pojo or simple Java object(like a Map) direct to JSON?, something like I do in Gson:
Person person = new Person();
String jsonStr = new Gson().toJson(person);
How can I do this with the new standard API?
Java API for JSON Processing (JSR-353) does not cover object binding. This will be covered in a separate JSR.
See JSR-367, Java API for JSON Binding (JSON-B), a headline feature in Java™ EE 8.
Document: Json Binding 1.0 Users Guide
// Create Jsonb and serialize
Jsonb jsonb = JsonbBuilder.create();
String result = jsonb.toJson(dog);
// Deserialize back
dog = jsonb.fromJson("{name:\"Falco\", age:4, bitable:false}", Dog.class);
Maybe it's because this question is almost 5 years old (I didn't check which java release has these classes) but there is a standard way with javax.json.* classes:
JsonObject json = Json.createObjectBuilder()
.add("key", "value")
.build();
try(JsonWriter writer = Json.createWriter(outputStream)) {
writer.write(json);
}