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.
Related
I want to add the elements to JSON array from the Java GUI at runtime
but every time the new array is created in JSON file
Java GUI to enter data:
String _itemType = txtItemType.getText();
int _itemQuantity = Integer.parseInt(txtItemQuantity.getText());
JSONWriteExample obj = new JSONWriteExample(_itemType, _itemQuantity);
obj.jsonParse();
JSON:
public JSONWriteExample(String type, int number) {
this.type = type;
this.quantity = number;
}
public void jsonParse() throws IOException {
JSONObject jo = new JSONObject();
Map m = new LinkedHashMap(4);
JSONArray ja = new JSONArray();
m = new LinkedHashMap(2);
m.put("Item Type", type);
m.put("Quantity", quantity);
ja.add(m);
jo.put("Items", ja);
FileWriter file=new FileWriter("jsonArray.json",true);
file.append(jo.toString());
file.flush();
file.close();
}
I expect the output like:
{
"Items":[
{
"Item Type":"TV",
"Quantity":3
},
{
"Item Type":"phone",
"Quantity":3
}
]
}
But new array is created each time like:
{
"Items":[
{
"Item Type":"TV",
"Quantity":3
}
]
}{
"Items":[
{
"Item Type":"phone",
"Quantity":3
}
]
}
As #fabian mentioned in the comment - you should first parse the file content, modify and overwrite the file. Here is a sample code how to achieve that:
First of all, I don't know what json library you're using, but I would strongly suggest to use the following:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
It will generally ease your work with json. If you don't want to use libraries you can still follow the instruction, but adapt it for your needs. The whole implementation is like this:
public class JSONWriteExample {
private static final String FILE_NAME = "jsonArray.json";
private static final Path FILE_PATH = Paths.get(FILE_NAME);
private final String type;
private final int quantity;
public JSONWriteExample(String type, int quantity) {
this.type = type;
this.quantity = quantity;
}
public void jsonParse() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
if (Files.notExists(FILE_PATH)) {
Files.createFile(FILE_PATH);
objectMapper.writeValue(FILE_PATH.toFile(), createItems(new ArrayList<>()));
}
Items items = objectMapper.readValue(FILE_PATH.toFile(), Items.class);
final List<Item> itemsList = items.getItems();
objectMapper.writeValue(FILE_PATH.toFile(), createItems(itemsList));
}
private Items createItems(List<Item> itemsList) {
final Item item = new Item();
item.setType(type);
item.setQuantity(quantity);
itemsList.add(item);
final Items items = new Items();
items.setItems(itemsList);
return items;
}
public static class Items {
private List<Item> items;
// Setters, Getters
}
public static class Item {
private String type;
private int quantity;
// Setters, Getters
}
}
Okay, what's going on in this code?
First of all, note the usage of Java 7 NIO - recommended way to work with files in java.
In jsonParse method we first check if file exists.
If it does - then we read it to the data class (Items) that describes our model. The reading part is done under the hood of this library, just the fileds of your json file should have the same names as the fields of the data classes (or specified with JsonAlias annotation.
If it doesn't - then we create it first and populate with the initial values.
ObjectMapper is the class from the library and it's used to read\write json files.
Now if we run this piece of code, e.g.
public static void main(String[] args) throws IOException {
JSONWriteExample example = new JSONWriteExample("TV", 3);
example.jsonParse();
JSONWriteExample example2 = new JSONWriteExample("phone", 3);
example2.jsonParse();
}
json file will look like:
{
"items": [
{
"type": "TV",
"quantity": 3
},
{
"type": "TV",
"quantity": 3
},
{
"type": "phone",
"quantity": 3
}
]
}
via this shape:
{
"to": "000",
"priority": "high",
"data": {
"title": "A Title",
"message": "A Message",
"link": {
"url": "http://www.espn.com",
"text": "ESPN",
}
}
}
how can I access "url" and "text"?
String messageLink = remoteMessage.getData().get("link");
gets me:
{"text":"ESPN","url":"http://www.espn.com"}
but how do I drill deeper?
remoteMessage.getData().get("link").get("text");
doesnt quite work... I have also attempted JSONObject:
JSONObject json = new JSONObject(remoteMessage.getData());
JSONObject link = json.getJSONObject("link");
but this gives me try catch errors...
Any help and direction as always is greatly appreciated!
I would use gson and define a model class. The remote message gives you a Map<String, String> and their is no matching constructor for creating a json object.
Add gson to your build.xml:
compile 'com.google.code.gson:gson:2.5'
Create a notification model:
import com.google.gson.annotations.SerializedName;
public class Notification {
#SerializedName("title")
String title;
#SerializedName("message")
String message;
#SerializedName("link")
private Link link;
public String getTitle() {
return title;
}
public String getMessage() {
return message;
}
public Link getLink() {
return link;
}
public class Link {
#SerializedName("url")
String url;
#SerializedName("text")
String text;
public String getUrl() {
return url;
}
public String getText() {
return text;
}
}
}
Deserialize a notification object from the remote message.
If all your custom keys are at the top level:
Notification notification = gson.fromJson(gson.toJson(remoteMessage.getData()), Notification.class);
If your custom json data is nested in a single key for example "data" then use:
Notification notification = gson.fromJson(remoteMessage.getData().get("data"), Notification.class);
Note in this simple case the #SerializedName() annotations are unnecessary since the field names exactly match the keys in the json, but if you for example have a key name start_time but you want to name the java field startTime you would need the annotation.
As simple as that:
String linkData = remoteMessage.getData().get("link");
JSONObject linkObject = new JSONObject(linkData);
String url = linkObject.getString("url");
String text = linkObject.getString("text");
Of course, together with proper error handling.
Faced this issue when migrating from GCM to FCM.
The following is working for my use case, so perhaps it will work for you.
JsonObject jsonObject = new JsonObject(); // com.google.gson.JsonObject
JsonParser jsonParser = new JsonParser(); // com.google.gson.JsonParser
Map<String, String> map = remoteMessage.getData();
String val;
for (String key : map.keySet()) {
val = map.get(key);
try {
jsonObject.add(key, jsonParser.parse(val));
} catch (Exception e) {
jsonObject.addProperty(key, val);
}
}
// Now you can traverse jsonObject, or use to populate a custom object:
// MyObj o = new Gson().fromJson(jsonObject, MyObj.class)
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;
So I'm looking to add a lot of users to a group messaging app that allows http post requests and I'm going to try to use the file upload function to read from a JSON but I'm a little confused as to how to write this in java:
{
"members": [
{
"nickname": "Mom",
"user_id": "1234567890",
"guid": "GUID-1"
},
{
"nickname": "Dad",
"phone_number": "+1 2123001234",
"guid": "GUID-2"
},
{
"nickname": "Jane",
"email": "jane#example.com",
"guid": "GUID-3"
}
]
}
This is an exmaple of the JSON file that I need to write to, can someone explain how to write that in Java? (It would need nickname & phone_number fields, only those two per person) Thanks!
EDIT 1: Sorry, wasn't clear. I need to use Java to produce a file with these contents.
Try try https://github.com/google/gson
http://www.studytrails.com/java/json/java-google-json-parse-json-to-java.jsp
Example:
import com.google.gson.Gson;
public class JavaToJsonAndBack {
public static void main(String[] args) {
Albums albums = new Albums();
albums.title = "Free Music Archive - Albums";
albums.message = "";
albums.total = "11259";
albums.total_pages = 2252;
albums.page = 1;
albums.limit = "5";
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
System.out.println(gson.toJson(albums));
}
}
This is how the resulting JSON looks like
{"title":"Free Music Archive - Albums","message":"","errors":[],
"total":"11259","total_pages":2252,"page":1,"limit":"5"}
Treat {} as classes and [] as arrays:
import com.google.gson.annotations.SerializedName;
public class Message {
#SerializedName("members")
private List<Member> members;
...
public class Member {
#SerializedName("nickname")
private String nickname;
#SerializedName("user_id")
private String userId;
#SerializedName("guid")
private String guid;
...
To transform to JSON:
Message msg;
...
String jsonResult = new Gson().toJson(msg);
To get back from JSON:
Message msg = new Gson().fromJson(jsonStr, Message.class);
User guide: https://sites.google.com/site/gson/gson-user-guide
I'm having trouble trying to make sense of this JSON string.
{
"results":[
{
"user":{
"gender":"female",
"name":{
"title":"miss",
"first":"taylor",
"last":"anderson"
},
"location":{
"street":"3645 dogwood ave",
"city":"roseburg",
"state":"new hampshire",
"zip":"20963"
},
"email":"taylor.anderson49#example.com",
"username":"heavyduck595",
"password":"liverpool",
"salt":"UK`o;9a_",
"md5":"6c8db0305b4591d8d9820d9f8edfd162",
"sha1":"906df4c09f3a87899666cb57bf974bd9b1950ea6",
"sha256":"3b12f5e51688578f845bef8ae1750d3e263c2010691010a80ce632a6b2323c03",
"registered":"1359027425",
"dob":"16243995",
"phone":"(934)-888-7068",
"cell":"(727)-467-8384",
"SSN":"697-20-6143",
"picture":"http://api.randomuser.me/0.3/portraits/women/30.jpg"
},
"seed":"5eaf02877746c7e",
"version":"0.3"
}
]
}
It's the first time I've really used JSON and want to try and interpret it appropriately. This is the code i have thus far:
static class Results{
String results;
}
static class User{
String gender;
String name;
String location;
List<Results> items;
}
private static String readUrl(String urlString) throws Exception {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
return buffer.toString();
} finally {
if (reader != null)
reader.close();
}
}
public void larry() throws Exception{
String json = readUrl("http://api.randomuser.me/");
System.out.println(json);
Gson gson = new Gson();
User page = gson.fromJson(json, User.class);
System.out.println(page.name);
for (Results item : page.items)
System.out.println(" " + item.results);
}
There is nothing particularly complicated about JSON, or mapping it to your own Java classes. You just have to understand the basic structure.
Your JSON is an object that has exactly one field; results. This is what {} means:
{ "results": ... }
That field holds an array. That's the [].
{ "results": [ ... ] }
That array holds another object (presumably you'd have more than one in an array, but the JSON you've posted just has one). That object has three fields, one of which ("user") holds another object with the other two being strings.
To map that to your own classes, you simply make them look like that JSON:
class JsonResult {
List<Result> results; // JSON arrays map to Java Lists
}
class Result {
User user;
String seed;
String version;
}
class User {
String gender;
Name name;
// and so on ...
}
class Name {
String title;
String first;
String last;
}
And so forth. You build classes to match the objects (again, denoted by {}) in the JSON, and structure everything accordingly.
As #HotLicks notes in his comment, you can decide not to map to Java classes and use a "clean" parser. In fact, Gson offers this with it's JsonParser class. This will just parse the JSON to a tree from which you can extract the info you want:
JsonElement element = new JsonParser().parse(yourJsonString);
From there you can access the JSON structure using the field names:
JsonObject root = element.getAsJsonObject();
JsonArray array = root.getAsJsonArray("results");
By accessing the JSON structure you can get to whatever you want.