Am retrieving information from my SQLite database to display on CardView
My SQLite database structure is SQLite DB
My class is
public class ServiceRequest{
public String reqid;
public String name;
public String branch;
public Date date;
public Date time;
public String services;
//Getter and setter
.............
.............
}
I can convert this to JSON format using
List<ServiceRequest> reqs = getAllReqs();
List<ServiceRequest> jobservList = new ArrayList<>();
for (ServiceRequest access : reqs) {
ServiceRequest ob = new ServiceRequest();
ob.setId(access.getId());
ob.setBranch(access.getBranch());
ob.setName(access.getName());
ob.setDate(access.getDate());
ob.setTime(access.getTime());
ob.setServices(access.getServices());
jobservList.add(ob);
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json2 = gson.toJson(jobservList);
return json2;
but my desired JSONObject format is
{
"100": {
"name": "Rahul Suresh",
"branch": "Koramangala",
"phNumber":"123456",
"date": "2016-08-06",
"time": "16:00",
"reqServices": "Loans"
},
"200": {
"name": "Sidh",
"branch": "Jayanagar",
"phNumber":"182694",
"date": "2016-08-12",
"time": "11:00",
"reqServices": "OpenAcc,SafeDeposit"
}
}
so that I will get one whole JSON object with a single call
JSONObject jb = (JSONObject) jsonObject.get(Integer.toString(id));
100,200 are 'reqid' s
It's possible to achieve this using string builder. But is there any other ways to implement this like using an object mapper along with a class or something..?
If you would like to form the JSON you have shown, you could "pull out" the ID into a HashMap key, then set the value to be your object.
I can't remember how Gson handles the conversion of the object values in the map, but this is the general idea
List<ServiceRequest> reqs = getAllReqs();
HashMap<Integer, ServiceRequest> map = new HashMap<Integer, ServiceRequest>();
for (ServiceRequest access : reqs) {
map.put(access.getId(), access);
}
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json2 = gson.toJson(map); // TODO: Not sure if this will work
return json2;
Related
I am trying to consume a json through an api using Google's GSON library to be able to recover the data.
I would like to be able to obtain the data of the CssValidation and Result key but it took hours and I have not been able to get it.
{
"cssvalidation": {
"uri": "https://www.mywebsite.com",
"checkedby": "http://www.w3.org/2005/07/css-validator",
"csslevel": "css3",
"date": "2021-10-17T05:07:38Z",
"timestamp": "1634490458519",
"validity": false,
"result": {
"errorcount": 7,
"warningcount": 350
}
}
}
My code in java is this:
Gson gson = new Gson();
ApiResponse apiResponse = gson.fromJson(response.body().string(), ApiResponse.class);
public class ApiResponse {
private CssValidation validation;
}
public class CssValidation{
public String uri;
public String getUri() {
return uri;
}
}
There are some problems with your json string which you need to fix before attempting to parse it, the uri value quotation is not closed, and there is an additional comma after the result object, after fixing both you end up with the functional json text
{
"cssvalidation": {
"uri": "https://www.mywebsite.com",
"checkedby": "http://www.w3.org/2005/07/css-validator",
"csslevel": "css3",
"date": "2021-10-17T05:07:38Z",
"timestamp": "1634490458519",
"validity": false,
"result": {
"errorcount": 7,
"warningcount": 350
}
}
}
you can parse it with the JsonParser and get its elements in the following way
JsonObject root = JsonParser.parseString(resp).getAsJsonObject();
JsonObject cssValidation = root.get("cssvalidation").getAsJsonObject();
String uri = cssValidation.get("uri").getAsString();
System.out.println(uri);
And you will get the following output
https://www.mywebsite.com
You seem to be doing it right, but your Java object property keys need to match up exactly with the keys in the JSON.
Specifically, the name of the property validation needs to changed to cssvalidation, so like this:
Gson gson = new Gson();
ApiResponse apiResponse = gson.fromJson(response.body().string(), ApiResponse.class);
public class ApiResponse {
private CssValidation cssvalidation;
}
public class CssValidation{
public String uri;
public String getUri() {
return uri;
}
}
Also, if the given JSON string is really what you get, then your JSON needs to be fixed, as pointed out by Lukas Ownen's answer
My Rest API is returning the following response, in which only the inner list is required, all data shall be discarded:
{
"meta": [],
"links": [],
"body": [
{
"meta": [],
"links": [],
"body": {
"field1": "value1",
"fieldn": "valuen"
} // <-----
},
{
"meta": [],
"links": [],
"body": {
"field1": "value1",
"fieldn": "valuen"
} // <-----
}
]
}
Is there any way in Gson or another other java library to fetch an array of the body or a straightforward way of doing that? Or maybe even using standard of java 8?
Or, should I use a standard iterator as follows:
//Old way to do this
JSONArray BodyArr = (JSONArray) jsonObject.get("Body");
Iterator<JSONObject> itBody = BodyArr.iterator();
int teller = 0;
while (itBody.hasNext()) {
JSONObject bodyObj = itBody.next();
JSONObject body = (JSONObject) bodyObj.get("Body");
}
Also in mysql we have way to do that using notation ($.body.body[] etc.). Is there any notational way to fetch the object
I think we have a nicely written article on this.
Json object iteration
If you have a class that represents an object in the array, then you can deserialize the JSONArray to an array of that class using public <T> T fromJson(JsonElement json, java.lang.Class<T> classOfT) throws JsonSyntaxException on the Gson class:
class BodyItem {
public String[] meta;
public String[] links;
public String field1;
public String fieldn;
}
public BodyItem[] getBodyItems(final Gson gson, final JsonObject jsonObject) {
final JsonElement body = jsonObject.get("body");
return gson.fromJson(body, BodyItem[].class);
}
public static void main(final String[] args) {
final String response = "<your REST API JSON response>";
final Gson gson = new Gson();
final JsonObject jsonObject = gson.fromJson(response, JsonObject.class);
final BodyItem[] bodyItems = getBodyItems(gson, jsonObject);
}
If you want a more notational way of accessing fields in Gson objects, you can use JsonObject's convenience accessors:
JsonArray getAsJsonArray(java.lang.String memberName)
JsonObject getAsJsonObject(java.lang.String memberName)
JsonPrimitive getAsJsonPrimitive(java.lang.String memberName)
And then with a JsonArray, you can iterate with for (final JsonElement element : jsonArray) or .forEach, and you can get JsonElements with the JsonElement get(int i) accessor.
So, say you had your original JsonObject response and wanted to get the value of body.field1 in the second element of the body list, you might do:
String value = jsonObject
.getAsJsonArray("body")
.get(1)
.getAsJsonObject()
.getAsJsonObject("body")
.getAsJsonObject("field1");
I have a use case where I get the object as a json string and consecutively needs to transform it into a HashMap. My code is as follows:
public Map<String, Object> toMap(String jsonString) {
Gson gson = new Gson();
Type type = new TypeToken<Map<String, Object>>() {
}.getType();
Map<String, Object> mapped = gson.fromJson(jsonString, type);
return mapped;
}
The date value I get from jsonString is "date": "2018-07-29T23:52:35.814Z" but upon serialization into HashMap, the "date" value is a String and not a Date object. Is there a way around it? Even solutions where Gson is not used is welcome
Sample jsonString is as follows:
{
"id": "1351",
"date": "2018-07-30T00:32:31.564Z",
"university": "US",
"typeofwork": "Report",
"title": "Thesis title",
"subject": "Masters",
"noofwords": "123"
}
To clarify, I am not getting any errors with the serialization/deserialization per se. I just want the date value to be of type java.util.Date such that a validation of if(map.get("date") instanceOf java.util.Date) will return true
If you have known exactly the property "date" is a Date, after parsing from Json, you can try somethiing like:
String dateStr = mapped.get("date");
mapped.put("date",new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(dateStr));
If you don't want to do it manually, simply define a class that matches your Json object format (with the "date" field declared as a Date object), then:
Gson g = new GsonBuilder().setDateFormat("your date format").create();
NewClass obj = g.fromJson(jsonStr, NewClass.class);
Gson will parse the date string follow the format in setDateFormat() method.
You can do it using customDeserialzer class in Jackson:
public class CustomDeserializer extends JsonDeserializer {
#Override
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
if(p.getCurrentName().equals("date")){
try {
return new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSS").parse(p.getText());
}catch (Exception ex){
}
return p.getText();
}
return p.getText();
}
}
Then parse like it:
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> hashMap = new HashMap<>();
String json = "{\"date\": \"2018-07-29T23:52:35.814Z\"}";
SimpleModule module = new SimpleModule().addDeserializer(String.class, new CustomDeserializer());
objectMapper.registerModule(module);
hashMap = objectMapper.readValue(json,new TypeReference<HashMap<String,Object>>(){});
hashMap.entrySet().parallelStream().forEach(e -> System.out.println(e.getValue()));
I am new to stackoverflow.
I am creating an Java application which it will get data from a web server. The data is in json format. Example"
[
{
"item_name": "Adame",
"item_type": "Special",
"item": "Chestplate",
"item_min_lvl": "50",
"enchantment": {
"health": "0.3",
"dam": "24%",
"life": "0.1",
"xp": "24%",
"loot": "22%"
},
"def": "73"
},
{
"item_name": "Sticks'",
"item_type": "Unique",
"item": "Stick",
"item_min_lvl": "4",
"enchantment": {
"health": "0.6",
"mana": "1",
"dam": "12%",
"life": "0.3",
"xp": "17%",
"loot": "17%"
},
"min_dam": "39",
"max_dam": "34"
}
]
I know how to deserialize json using Gson. As you can see, it's started with [. I never deserialize this case before. Also, the json data is not the same(e.g. enchantment). I also searched in Google but I can't find any similar case. Can anyone help me with the code?
Try with this code. You will get the answer of your question. It's an List with 2 items.
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new FileReader(new File("resources/json1.txt")));
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
reader.close();
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<MyJSON>>() {
}.getType();
List<MyJSON> list = gson.fromJson(builder.toString(), listType);
// you can try this form as well
// MyJSON[] list = gson.fromJson(builder.toString(), MyJSON[].class);
for (MyJSON json : list) {
System.out.println(json.toString());
}
...
class MyJSON {
String item_name;
String item_type;
String item;
String item_min_lvl;
Enchantment enchantment;
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("\nitem_name:").append(item_name);
builder.append("\nitem_type:").append(item_type);
builder.append("\nitem:").append(item);
builder.append("\nitem_min_lvl:").append(item_min_lvl);
builder.append("\n\nEnchantment Details:");
builder.append("\nhealth:").append(enchantment.health);
builder.append("\ndam:").append(enchantment.dam);
builder.append("\nlife:").append(enchantment.life);
builder.append("\nxp:").append(enchantment.xp);
builder.append("\nloot:").append(enchantment.loot);
return builder.toString();
}
}
class Enchantment {
String health;
String dam;
String life;
String xp;
String loot;
}
output:
item_name:Adame
item_type:Special
item:Chestplate
item_min_lvl:50
Enchantment Details:
health:0.3
dam:24%
life:0.1
xp:24%
loot:22%
item_name:Sticks'
item_type:Unique
item:Stick
item_min_lvl:4
Enchantment Details:
health:0.6
dam:12%
life:0.3
xp:17%
loot:17%
EDIT
The structure of each entry is not same hence you can't use POJO for this type of JSON.
Simply use ArrayList<Map<String, Object>> and access the value based on key from the map.
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<Map<String, Object>>>() {
}.getType();
ArrayList<Map<String, Object>> list = gson.fromJson(builder.toString(), listType);
for (Map<String, Object> json : list) {
for (String key : json.keySet()) {
System.out.println(key + ":" + json.get(key));
}
System.out.println("===========");
}
output:
item_name:Adame
item_type:Special
item:Chestplate
item_min_lvl:50
enchantment:{health=0.3, dam=24%, life=0.1, xp=24%, loot=22%}
def:73
===========
item_name:Sticks'
item_type:Unique
item:Stick
item_min_lvl:4
enchantment:{health=0.6, mana=1, dam=12%, life=0.3, xp=17%, loot=17%}
min_dam:39
max_dam:34
===========
This is actually valid in Java and with GSON:
YourObject[] locs = gson.fromJson (someJsonString, YourObject[].class);
It'll parse and return an array of YourObject. Just create Java Classes that represent your JSON objects, and replace the placeholders as necessary.
EDIT:
As Braj said before, you can create a fully formed POJO, including the other, (non-symmetrical) attributes (I'm borrowing the code from from Braj's answer here):
//... snip ...
class MyJSON
{
String item_name;
String item_type;
String item;
String item_min_lvl;
Enchantment enchantment;
// Heres the other attributes
String min_dam;
String max_dam;
}
//... snip ...
GSON will parse it and set the values to null if they aren't provided in the original JSON.
However, from the other question, it seems that the JSON (Java - JSON Parser Error) for enchantment is provided inconsistently, so this will cause issues. I would recommend sending JSON for enchantment as an array for consistency, then you could structure your POJO as:
//... snip ...
class MyJSON
{
String item_name;
String item_type;
String item;
String item_min_lvl;
Enchantment[] enchantment;
// Heres the other attributes
String min_dam;
String max_dam;
}
//... snip ...
I have a two POJO classes: AddressInformation and PackageInformation (with their getters and setters which are not specified in the below code).
public class AddressInformation {
private Integer address_id;
private String street_name;
private String city;
private String state;
private Integer zipcode;
}
public class PackageInformation {
private Integer packageId;
private Integer packageType;
private Double packageWeight;
private AddressInformation packageSource;
private AddressInformation packageDestination;
}
I am persisting the instances of the classes using hibernate, and trying to retrieve the contents of PackageInformation from the database using hibernate and return the contents as JSON format. I am not using any framework.
Session session = HibernateUtils.getSessionFactory().openSession();
List<PackageInformation> packagelist = null;
tx = session.beginTransaction();
packagelist = session.createQuery("FROM PackageInformation").list();
tx.commit();
session.close();
I wanted the packagelist which has the collection of PackageInformation to be converted to JSON.
The catch here is that PackageInformation object has AddressInformation embedded in to it.
I tried the below code to convert the collection of PackageInformation to JSON:
JSONArray json = new JSONArray();
Gson gson = new Gson();
try{
for(PackageInformation pack : packagelist){
JSONObject jsonObj = new JSONObject();
AddressInformation sourceAddress = pack.getPackageSource();
JsonElement sourceAddressJson = gson.toJsonTree(sourceAddress);
jsonObj.put("sourceAddress",sourceAddressJson);
AddressInformation destinationAddress = pack.getPackageDestination();
JsonElement destinationeAddressJson = gson.toJsonTree(destinationAddress);
jsonObj.put("destinationAddress",destinationeAddressJson);
jsonObj.put("package_id",pack.getPackageId());
jsonObj.put("package_type",pack.getPackageType());
jsonObj.put("package_weight",pack.getPackageWeight());
}
returnString = json.toString();
}catch(JSONException je){
returnString = je.toString();
}
return Response.status(200).entity(returnString).build();
But I do not get JSON with sourceAddress and destinationAddress details embedded as JSON. Instead I got black fields: the sourceAddress and destinationAddress details are missing as in the JSON below.
[
{
"sourceAddress": {},
"destinationAddress: {},
"package_id": 1,
"package_type": 1,
"package_weight": 500,
}
{
"sourceAddress": {},
"destinationAddress: {},
"package_id": 2,
"package_type": 5,
"package_weight": 700,
}
]
To answer straight to your question, I think that your AddressInformation fields are empty (not null, just empty objects) so you are missing some points into your hibernate calls.
However, you can try to serialize all your stuff in another way that is more simple and safe. You are using JsonElement and JsonObject that I consider "low level" respect to the services that Gson provides to you.
I want to use my example also to show you at the same time the effect of an empty object, so compare source to destination addresses in the final JSON. This is my proposal.
public class PackageInformation {
#SerializedName("package_id")
Integer packageId;
#SerializedName("package_type")
Integer packageType;
#SerializedName("package_weight")
Double packageWeight;
#SerializedName("sourceAddress")
AddressInformation packageSource;
#SerializedName("destinationAddress")
AddressInformation packageDestination;
}
As you can note, I added the #SerializedName annotation to change the name of serialized field (this is why, I think, you are using this approach). Then I use the simpliest serialization method the Gson provides you with.
public class Q19615935 {
public static void main(String[] args) {
List<PackageInformation> list = new ArrayList<PackageInformation>();
PackageInformation pi = new PackageInformation();
pi.packageId = 42;
pi.packageType = 21;
pi.packageWeight = 2000.0;
AddressInformation source = new AddressInformation();
source.address_id = 1;
source.city="A city";
source.state="A state";
source.street_name="A street name";
source.zipcode=0;
pi.packageSource= source;
pi.packageDestination=new AddressInformation();
list.add(pi);
Gson g = new Gson();
System.out.println(g.toJson(list));
}
}
Since I do not have your db, I built a list by hands and this is my result (I formatted the console result):
[
{
"package_id": 42,
"package_type": 21,
"package_weight": 2000,
"sourceAddress": {
"address_id": 1,
"street_name": "A street name",
"city": "A city",
"state": "A state",
"zipcode": 0
},
"destinationAddress": { }
}
]
My conclusions:
If source and destination are not empty objects, you should use my serialization code.
If they are empty, you should check how they come from db and once solved, check again point 1.