I have an Android App (written in Java) which retrieves a JSON object from the backend, parses it, and displays the data in the app. Everything is working fine (meaning that every field is being displayed correctly) except for one field. All the fields being displayed correctly are String whereas the one field which is causing the error is a string array!
Sample Object being retried from backend:
{
"attendance_type": "2",
"guest": [
"Test Guest",
"Test Guest 2"
],
"member_id": "1770428",
"attendance_time": "2020-04-27 04:42:22",
"name": "HENRY HHH",
"last_name": "",
"email": "henry#mailinator.com",
"onesignal_playerid": "",
"user_image": "311591.png",
"dateOfBirth": "06/22/1997",
"employeeID": "543210",
"socialSecurityNumber": "0000"
}
As I said, all the fields are being retrieved correctly except the "guest field"
This is the class in which everything is Serialized:
package com.lu.scanner.ui.attendance.model;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class AttendanceDetails {
String date;
#SerializedName("attendance_type")
private String attendance_type;
#SerializedName("member_id")
private String member_id;
#SerializedName("attendance_date")
private String attendance_date;
#SerializedName("name")
private String name;
#SerializedName("email")
private String email;
#SerializedName("onesignal_playerid")
private String onesignal_playerid;
#SerializedName("user_image")
private String user_image;
#SerializedName("dateOfBirth")
private String dateOfBirth;
#SerializedName("employeeID")
private String employeeID;
#SerializedName("socialSecurityNumber")
private String socialSecurityNumber;
#SerializedName("attendance_time")
private String attendance_time;
#SerializedName("guest")
private String[] guest;
public AttendanceDetails(String date) {
this.date = date;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getAttendance_type() {
return attendance_type;
}
public void setAttendance_type(String attendance_type) {
this.attendance_type = attendance_type;
}
public String getMember_id() {
return member_id;
}
public void setMember_id(String member_id) {
this.member_id = member_id;
}
public String getAttendance_date() {
return attendance_date;
}
public void setAttendance_date(String attendance_date) {
this.attendance_date = attendance_date;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getOnesignal_playerid() {
return onesignal_playerid;
}
public void setOnesignal_playerid(String onesignal_playerid) {
this.onesignal_playerid = onesignal_playerid;
}
public String getUser_image() {
return user_image;
}
public void setUser_image(String user_image) {
this.user_image = user_image;
}
public String getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(String dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public String getEmployeeID() {
return employeeID;
}
public void setEmployeeID(String employeeID) {
this.employeeID = employeeID;
}
public String getSocialSecurityNumber() {
return socialSecurityNumber;
}
public void setSocialSecurityNumber(String socialSecurityNumber) {
this.socialSecurityNumber = socialSecurityNumber;
}
public String getAttendance_time() {
return attendance_time;
}
public void setAttendance_time(String attendance_time) {
this.attendance_time = attendance_time;
}
public String[] getGuest(){
return guest;
}
public void setGuest(String[] guest){
this.guest=guest;
}
}
This is the SQLLite database:
private static final String CREATE_TABLE_ATTENDANCE_DETAILS = "CREATE TABLE IF NOT EXISTS " + TABLE_ATTENDANCE_DETAILS +
"( date TEXT , " +
"attendance_type TEXT, " +
"member_id TEXT, " +
"attendance_date TEXT, " +
"name TEXT, " +
"email TEXT, " +
"onesignal_playerid TEXT, " +
"user_image TEXT, " +
"dateOfBirth TEXT, " +
"employeeID TEXT, " +
"socialSecurityNumber TEXT, " +
"attendance_time TEXT, " +
"guest TEXT); ";
And finally, there is where the data is being retrieved:
public List<AttendanceDetails> getAllAttendanceDetails() {
List<AttendanceDetails> attendanceDetailsList = new ArrayList<AttendanceDetails>();
String selectQuery = "SELECT * FROM " + TABLE_ATTENDANCE_DETAILS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
AttendanceDetails attendanceDetails = new AttendanceDetails();
attendanceDetails.setDate(cursor.getString(0));
attendanceDetails.setAttendance_type(cursor.getString(1));
attendanceDetails.setMember_id(cursor.getString(2));
attendanceDetails.setAttendance_date(cursor.getString(3));
attendanceDetails.setName(cursor.getString(4));
attendanceDetails.setEmail(cursor.getString(5));
attendanceDetails.setOnesignal_playerid(cursor.getString(6));
attendanceDetails.setUser_image(cursor.getString(7));
attendanceDetails.setDateOfBirth(cursor.getString(8));
attendanceDetails.setEmployeeID(cursor.getString(9));
attendanceDetails.setSocialSecurityNumber(cursor.getString(10));
attendanceDetails.setAttendance_time(cursor.getString(11));
attendanceDetails.setGuest(cursor.getString(12));
attendanceDetailsList.add(attendanceDetails);
} while (cursor.moveToNext());
}
return attendanceDetailsList;
}
Therefore, the main problem, I think, is that the TEXT type in the table creation is not compatible with the String array. Plus I think the cursor.String() function is not working for the "guest" string array properly. What can I do to make all of this code compatible with the "guest" field?
NOTE: Everything is working perfectly fine except for the guest field...
A Database stores rows of data, divided into columns. Each column is a skalar. SQLite only supports (basically) numbers and Text for columns. A List of Texts (or array from strings) doesn't fit in there. You are trying to assign a single String to an array.
You have two options:
Model guest as its own table and use foreign keys and the appropriate JOIN to fetch the data.
Encode the data yourself. If you don't want to query the array, but always retrieve the whole thing, this is the easier way:
Gson gson;
String guestSerialized = gson.toJson(attendanceDetails.getGuest);
// Insert data like this
// Retrieve:
attendanceDetails.setGuest(gson.fromJson(cursor.getString(12), String[].class))
That is, if you are using GSON for JSON (de)serialization. You can choose a different format or library.
Maybe you could give some name in the fields of "guest", something like:
"guest": [
{
"guest" : "Test Guest",
},
{
"guest" : "Test Guest 2"
},
],
Then, in order to read these values, you can do that:
JSONArray ja = (JSONArray) jo.get("guest");
Map address = ((Map)jo.get("guest"))
Iterator itr = ja.iterator();
Iterator<Map.Entry> itr1;
while (itr.hasNext()) {
itr1 = ((Map) itr.next()).entrySet().iterator();
while (itr1.hasNext()) {
Map.Entry pair = itr1.next();
System.out.println(pair.getKey() + " : " + pair.getValue());
}
}
Where:
pair.getKey is the name of the key ("guest")
pair.getValue is the value of the key ("Test Guest")
The source code is here.
Sorry if I have made any mistakes. Please ask for clarifications! :)
Related
Trying to read a JSON file and serialize it to java object, I wrote a method:
public static PostPojo readFile(String titleFile){
String pathJSONFile = "src/main/resources/"+titleFile+".json";
ObjectMapper objectMapper = new ObjectMapper();
try {
objectMapper.readValue(pathJSONFile,PostPojo.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return postPojo;
}
but it produces an error:
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'src': was expecting (JSON
String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (String)"src/main/resources/ninetyNinthPost.json"; line: 1, column: 4]
at utils.ApiUtils.readFile(ApiUtils.java:71)
at ApiApplicationRequest.getValue(ApiApplicationRequest.java:31)
My JSON file from which values are calculated
[ {
"userId" : 10,
"id" : 99,
"title" : "temporibus sit alias delectus eligendi possimus magni",
"body" : "quo deleniti praesentium dicta non quod\naut est
molestias\nmolestias et officia quis nihil\nitaque dolorem quia"
} ]
My java object class
public class PostPojo {
private int userId;
private int id;
private String title;
private String body;
public PostPojo() {
}
public PostPojo(int userId, int id, String title, String body) {
this.userId = userId;
this.id = id;
this.title = title;
this.body = body;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
#Override
public String toString() {
return "PostModel{" +
"userId=" + userId +
", id=" + id +
", title='" + title + '\'' +
", body='" + body + '\'' +
'}';
}
}
I really don't understand what is the reason.As I understand it, reading in the documentation, it should read the file and present it in the java class. Any sugestions?
There is no method signature supposed to get a file path as first argument. You may pass a JSON String as first argument or you could use the method signature with a File Object as first argument, like this:
public static PostPojo[] readFile(String titleFile){
String pathJSONFile = "src/main/resources/"+titleFile+".json";
ObjectMapper objectMapper = new ObjectMapper();
File jsonFile = new File(pathJSONFile);
PostPojo[] postPojo = null;
try {
postPojo = objectMapper.readValue(jsonFile, PostPojo[].class);
} catch (IOException e) {
e.printStackTrace();
}
return postPojo;
}
EDIT: Since your file defines a wrapping array around the object you have to parse it as array. Afterwards you may return it as an array like i did in my edited answer or you just return the first array record.
I have 2 API responses and converted them into Json Array. When I convert 2 jsons into a map of key value pair the order of values are different and unable to perform comparison between 2 API responses.
JsonArray from API 1:
[
{
"employeeSalutation": null,
"EmployeeName": "Example",
"EmployeeCode": "SAA",
"Zip": 12345,
"DepartmentName": "Social science",
"EmployeeAddress": "123 st",
"StateCode": 9,
"updatedDate": "2018-01-22T03:48:43.59",
"EmployeeId": 1257
}
]
Json Array from API 2:
[
{
"Emp_Name": "Example",
"emp_Sal": null,
"Dept_Name": "Social science",
"Emp_addr": "123 st",
"Zip": "12345",
"Stat_cd": 9,
"Emp_id": 1257,
"upd_d": "2018-01-22 03:48:43.59",
"Emp_Code": "SAA"
}
]
I converted 2 Json Arrays into map of key-value pair with EmployeeId as key in Array 1 and Emp_id as key in Array 2. When I compare 2 maps the order of values in map are different and getting failed.
How to compare 2 APIs to ensure the values of each element in 2 apis are matched.
First of all you need to create a model which will represent these two JSON payloads. They are almost similar except of key names and values for Zip key where in first payload it is a number primitive in second - String primitive. Dates also have different format so you need to handle them by implementing custom date deserialiser.
Definitely you should use Jackson or Gson library which allows to deserialise JSON to POJO model, provide custom date deserialisers, any many other features.
Below example provide example solution:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonApi1 = new File("./resource/test.json").getAbsoluteFile();
File jsonApi2 = new File("./resource/test1.json").getAbsoluteFile();
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
private final SimpleDateFormat formatWithTimeZoneIndicator = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SS");
private final SimpleDateFormat formatWithoutTimeZoneIndicator = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SS");
#Override
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String date = json.getAsString();
try {
return formatWithoutTimeZoneIndicator.parse(date);
} catch (ParseException e) {
try {
return formatWithTimeZoneIndicator.parse(date);
} catch (ParseException e1) {
throw new JsonParseException(e1);
}
}
}
})
.create();
Type employeesType = new TypeToken<List<Employee>>() {}.getType();
try (FileReader readerApi1 = new FileReader(jsonApi1);
FileReader readerApi2 = new FileReader(jsonApi2)) {
List<Employee> employees1 = gson.fromJson(readerApi1, employeesType);
List<Employee> employees2 = gson.fromJson(readerApi2, employeesType);
System.out.println(employees1);
System.out.println(employees2);
System.out.println(employees1.equals(employees2));
}
}
}
class Employee {
#SerializedName(value = "employeeSalutation", alternate = {"emp_Sal"})
private String employeeSalutation;
#SerializedName(value = "EmployeeName", alternate = {"Emp_Name"})
private String employeeName;
#SerializedName(value = "EmployeeCode", alternate = {"Emp_Code"})
private String employeeCode;
#SerializedName("Zip")
private JsonPrimitive zip;
#SerializedName(value = "DepartmentName", alternate = {"Dept_Name"})
private String departmentName;
#SerializedName(value = "EmployeeAddress", alternate = {"Emp_addr"})
private String employeeAddress;
#SerializedName(value = "StateCode", alternate = {"Stat_cd"})
private int stateCode;
#SerializedName(value = "updatedDate", alternate = {"upd_d"})
private Date updatedDate;
#SerializedName(value = "EmployeeId", alternate = {"Emp_id"})
private int employeeId;
public String getEmployeeSalutation() {
return employeeSalutation;
}
public void setEmployeeSalutation(String employeeSalutation) {
this.employeeSalutation = employeeSalutation;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getEmployeeCode() {
return employeeCode;
}
public void setEmployeeCode(String employeeCode) {
this.employeeCode = employeeCode;
}
public JsonPrimitive getZip() {
return zip;
}
public void setZip(JsonPrimitive zip) {
this.zip = zip;
}
public String getDepartmentName() {
return departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public String getEmployeeAddress() {
return employeeAddress;
}
public void setEmployeeAddress(String employeeAddress) {
this.employeeAddress = employeeAddress;
}
public int getStateCode() {
return stateCode;
}
public void setStateCode(int stateCode) {
this.stateCode = stateCode;
}
public Date getUpdatedDate() {
return updatedDate;
}
public void setUpdatedDate(Date updatedDate) {
this.updatedDate = updatedDate;
}
public int getEmployeeId() {
return employeeId;
}
public void setEmployeeId(int employeeId) {
this.employeeId = employeeId;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return stateCode == employee.stateCode &&
employeeId == employee.employeeId &&
Objects.equals(employeeSalutation, employee.employeeSalutation) &&
Objects.equals(employeeName, employee.employeeName) &&
Objects.equals(employeeCode, employee.employeeCode) &&
Objects.equals(zip.getAsString(), employee.zip.getAsString()) &&
Objects.equals(departmentName, employee.departmentName) &&
Objects.equals(employeeAddress, employee.employeeAddress) &&
Objects.equals(updatedDate, employee.updatedDate);
}
#Override
public int hashCode() {
return Objects.hash(employeeSalutation, employeeName, employeeCode, zip, departmentName, employeeAddress, stateCode, updatedDate, employeeId);
}
#Override
public String toString() {
return "Employee{" +
"employeeSalutation='" + employeeSalutation + '\'' +
", employeeName='" + employeeName + '\'' +
", employeeCode='" + employeeCode + '\'' +
", zip=" + zip +
", departmentName='" + departmentName + '\'' +
", employeeAddress='" + employeeAddress + '\'' +
", stateCode=" + stateCode +
", updatedDate='" + updatedDate + '\'' +
", employeeId=" + employeeId +
'}';
}
}
Above code prints:
[Employee{employeeSalutation='null', employeeName='Example', employeeCode='SAA', zip=12345, departmentName='Social science', employeeAddress='123 st', stateCode=9, updatedDate='Mon Jan 22 03:48:43 CET 2018', employeeId=1257}]
[Employee{employeeSalutation='null', employeeName='Example', employeeCode='SAA', zip="12345", departmentName='Social science', employeeAddress='123 st', stateCode=9, updatedDate='Mon Jan 22 03:48:43 CET 2018', employeeId=1257}]
true
JSONAssert librairy is very handy for such tasks.
Here is good tutorial on how to use it.
I hope it helps you.
Since you are doing this in Java, I suggest you map this values into Java objects.
That way, it would be extremely easy for you to compare values. You can use libraries like Gson for that but here i will show you how to do that without a library.
Create a class which will be easy to use for your API responses:
public class Employee {
private String employeeSalutation; //i am not sure what type should this variable be
private String employeeName;
private String employeeCode;
private int zip;
private String departmentName;
private String employeeAddress;
private int stateCode;
private String updatedDate;
private int employeeId;
//this is where your parser can be used
public Employee(String employeeSalutation, String employeeName, String employeeCode,
int zip, String departmentName, String employeeAddress, int stateCode,String updatedDate, int employeeId){
this.employeeSalutation = employeeSalutation;
this.employeeName = employeeName;
this.employeeCode = employeeCode;
this.zip = zip;
this.departmentName = departmentName;
this.employeeAddress = employeeAddress;
this.stateCode = stateCode;
this.updatedDate = updatedDate;
this.employeeId = employeeId;
}
//getters, setters
}
Now you could have a class which will be used to convert this arrays into Java Objects, lets call it EmployeeConverter:
public class EmployeeConverter {
public Employee convertApi1Employee(String json){
//since you didn't clarify how are you accessing your Json values, i will now use pseudo-code to finish my answer.
//using variable.value pseudo-code to access json property value
return new Employee(employeeSalutation.value, EmployeeName.value, EmployeeCode.value, Zip.value, DepartmentName.value, EmployeeAddress.value, EmployeeAddress.value, StateCode.value, updatedDate.value, EmployeeId.value);
}
}
You should create method convertApi2Employee() which will have exact functionality as convertApi1Employee() method, but will use different JSON object.
I hope this helps.
I have this extremely long JSON file that has a structure like this
{
"count":123456,
"tags":[
{
"sameAs":["https://www.wikidata.org/wiki/Q11254"],
"url":"https://world.openfoodfacts.org/ingredient/salt",
"products":214841,
"name":"Salt",
"id":"en:salt"
},
{
"url":"https://world.openfoodfacts.org/ingredient/sugar",
"sameAs":["https://www.wikidata.org/wiki/Q11002"],
"name":"Sugar",
"id":"en:sugar",
"products":184348
},
...
]
The order of the inner tag objects do not remain the same but i dont think that would pose a problem. Currently this is the code that im using to parse this JSON Object:
This is the container holding the count item as well as the list of tags called IngredientItem.
public class Ingredients {
private int count;
private List<IngredientItem> items;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<IngredientItem> getItems() {
return items;
}
public void setItems(List<IngredientItem> items) {
this.items = items;
}
}
This is the code for each tag:
public class IngredientItem {
private List<String> sameAs;
private String id;
private String name;
private String url;
private int productNumber;
public IngredientItem(List<String> sameAs, String id, String name, String url, int productNumber) {
this.sameAs = sameAs;
this.id = id;
this.name = name;
this.url = url;
this.productNumber = productNumber;
}
public List<String> getSameAs() {
return sameAs;
}
public void setSameAs(List<String> sameAs) {
this.sameAs = sameAs;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getProductNumber() {
return productNumber;
}
public void setProductNumber(int productNumber) {
this.productNumber = productNumber;
}
#Override
public String toString() {
return "product number: " + getProductNumber() +
"\n" + "name: " + getName() +
"\n" + "id: " + getId() +
"\n" + "same as: " + getSameAs() +
"\n" + "url: " + getUrl();
}
}
and this is my main code to actually parse it.
Gson gson = new Gson();
FileReader fr = new FileReader("path\\to\\file\\ingredients.json");
Ingredients ingredients = gson.fromJson(fr,Ingredients.class);
if(ingredients.getItems() ==null){
System.out.println("NULL");
}else{
for (IngredientItem item: ingredients.getItems()) {
System.out.println(item.toString());
}
}
for some reason it wont ever fill up the items from all the tags. I have already extensively looked at this Parsing a complex Json Object using GSON in Java question and I cannot seem to find the error. The link to downloading this extremely long JSON file is here Really Long JSON File. If you save the page as a .json it is around 121MB so just keep that noted.
Thank you in advance. If any other information is required please let m
For it to be automatic, you need to change Ingredients.items to Ingredients.tags.
If you want to keep your object structure, you can check here how to do it with a Custom Deserializer or Annotations.
There is a database (northwind) on my machine and I have to write a code in java so as to extract the data from the table (Customers) stored in the database.
If this was only specific to Customers table then I would have done it but I want to make my code generic so that I can extract data from other tables also by simply giving the name of the table in a string variable.
Please have a look to my code.
Main class
package main;
import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import model.TableModel;
import service.DBConnection;
import service.WriteExcel;
public class Main {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
double start = System.nanoTime();
String tableName = "Customers";
Class<?> c = Class.forName(tableName);
Connection conn = new DBConnection().getConnection();
System.out.println("Connection Established");
QueryRunner run = new QueryRunner();
ResultSetHandler<List<TableModel>> resultHandler = new BeanListHandler<TableModel>(c.getClass())
List<TableModel> data = run.query(conn, "SELECT * FROM `" + tableName + "`;",
resultHandler);
WriteExcel we = new WriteExcel(tableName+"_sheet", new File(tableName+".xlsx"));
we.writeMultipleRows(data);
we.writeWorkbookToFile();
System.out.println("File Written Succesfully");
conn.close();
System.out.println("Time Taken: " + (System.nanoTime()-start)/1000000+" ms");
}
}
In the above code, at line 27, If the statement would have been as follows
ResultSetHandler<List<TableModel>> resultHandler = new BeanListHandler<TableModel>(Customers.class);
This is running perfectly, as I said I want this statement to be independent of the table name, making my code more general.
TableModel
package model;
import java.util.List;
public interface TableModel {
public List<String> getObjectAsList();
}
Customers
package model;
import java.util.ArrayList;
import java.util.List;
public class Customers implements TableModel {
private String customerId;
private String companyName;
private String contactName;
private String contactTitle;
private String address;
private String city;
private String region;
private String postalCode;
private String country;
private String phone;
private String fax;
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public String getContactTitle() {
return contactTitle;
}
public void setContactTitle(String contactTitle) {
this.contactTitle = contactTitle;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getFax() {
return fax;
}
public void setFax(String fax) {
this.fax = fax;
}
public List<String> getObjectAsList(){
List<String> fields = new ArrayList<>();
fields.add(customerId);
fields.add(companyName);
fields.add(contactName);
fields.add(contactTitle);
fields.add(address);
fields.add(city);
fields.add(region);
fields.add(postalCode);
fields.add(country);
fields.add(phone);
fields.add(fax);
return fields;
}
#Override
public String toString() {
return "{ CustomerID = "+getCustomerId()+","
+ " CompanyName = "+getCompanyName()+","
+ " ContactName = "+getContactName()+","
+ " ContactTitle = "+getContactTitle()+","
+ " Address = "+getAddress()+","
+ " City = "+getCity()+","
+ " Region = "+getRegion()+","
+ " PostalCode = "+getPostalCode()+","
+ " Country = "+getCountry()+","
+ " Phone = "+getPhone()+","
+ " Fax = "+getFax()+"}";
}
}
I have used DbUtils library for extracting database.
Any further suggestion for enhancing my code is welcomed.
If I understand your question right, you could try something like below.
To query the table, you can use run.query(SQL, ResultHandler).
ResultSetHandler<List<Map<String, Object>>> resultHandler = genericResultHandler();
List<Map<String, Object>> result = null;
// Execute the SQL statement and return the results in a List of
// T objects generated by the BeanListHandler.
try
{
result = run.query(sqlQuery, resultHandler, varargs);
}
catch (SQLException e)
{
e.printStackTrace();
}
result.stream().forEach(System.out::println);
The interesting part here is the private method genericResultHandler. For demonstration purposes, I used a HashMap to store the values and the corresponding cloumn names.
private ResultSetHandler<List<Map<String, Object>>> genericResultHandler()
{
return new ResultSetHandler<List<Map<String, Object>>>()
{
#Override
public List<Map<String, Object>> handle(java.sql.ResultSet rs) throws SQLException
{
List<Map<String, Object>> result = new ArrayList<>();
// Query all rows of the table.
while (rs.next())
{
// Get metadata of the table.
java.sql.ResultSetMetaData meta = rs.getMetaData();
int cols = meta.getColumnCount();
Map<String, Object> data = new HashMap<>();
// For each column store column name and value of the cell into the hashmap.
for (int i = 1; i < cols; i++)
{
String colName = meta.getColumnName(i);
Object value = rs.getObject(colName);
data.put(colName, value);
}
// Add the row to the result list.
result.add(data);
}
return result;
}
};
}
Afterwards some imports I have used:
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
Output would be something like this (for my test table):
{month=JANUARY, temperature=1.6, globalradiation=0.0, monthid=1}
{month=FEBRUARY, temperature=-0.9, globalradiation=0.0, monthid=2}
{month=MARCH, temperature=0.9, globalradiation=0.0, monthid=3}
{month=APRIL, temperature=7.2, globalradiation=0.0, monthid=4}
{month=MAY, temperature=14.1, globalradiation=0.0, monthid=5}
The error code :
org.codehaus.jackson.map.exc.UnrecognizedPropertyException:
Unrecognized field "id" (Class JacksonTester$Student), not
marked as ignorable
at [Source: [B#40334c25; line: 2, column: 8]
(through reference chain: Student["id"])
I have the below JSON file:
{
"id": "0",
"title": "0",
"externalId": "0",
"externalLink": "0",
"sourceApplication": "0",
"content": "0",
"summaryContent": "0",
"publishedDate": "0",
"harvestDate": "0",
"languageId": "0",
"regionId": "0",
"postStatus": "0"
}
and my code is
JacksonTester.java:
public class JacksonTester {
public static void main(String args[]) {
ObjectMapper mapper = new ObjectMapper();
// map json to student
try {
byte[] jsonData = Files.readAllBytes(Paths.get("output_json.txt"));
Student student = mapper.readValue(jsonData, Student.class);
System.out.println(student);
} catch (Exception e) {
e.printStackTrace();
}
}
static class Student {
String id;
String title;
String externalId;
String externalLink;
String sourceApplication;
String content;
String summaryContent;
String publishedDate;
String harvestDate;
String languageId;
String regionId;
String postStatus;
public Student() {
}
}
}
You need to either have setters for those fields or a constructor that accepts those fields as parameters (+ approriate annotations or -parameters from Java 8 and jackson-module-parameter-names
module):
public static class Student {
...
String postStatus;
public setPostStatus(postStatus) {
this.postStatus = postStatus;
}
...
}
Jackson has no access to the fields of Student.
Implement the public getters and setters for Student and it works.
I sorted this problem and it's working fine. Here is my code for the same.
**MainClass.java:**
public class MainClass {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
String jsonStr = "{\r\n" + " \"id\": \"168\",\r\n" + " \"title\": \"Mr\",\r\n"
+ " \"externalId\": \"247518\",\r\n" + " \"externalLink\": \"www.gmail.com\",\r\n"
+ " \"sourceApplication\": \"adsense\",\r\n" + " \"content\": \"hmtl\",\r\n"
+ " \"summaryContent\": \"null\",\r\n" + " \"publishedDate\": \"12122018\",\r\n"
+ " \"harvestDate\": \"12122018\",\r\n" + " \"languageId\": \"3\",\r\n" + " \"regionId\": \"45\",\r\n"
+ " \"postStatus\": \"1\"\r\n" + "}";
ObjectMapper mapper = new ObjectMapper();
MyPojo details = mapper.readValue(jsonStr, MyPojo.class);
System.out.println("Value for getId is: " + details.getId());
System.out.println("Value for getSourceApplication is: " + details.getSourceApplication());
System.out.println("Value for getExternalId is: " + details.getPublishedDate());
System.out.println("Value for getExternalLink is: " + details.getExternalLink());
} }
**MyPojo.class**
public class MyPojo {
private String content;
private String id;
private String sourceApplication;
private String title;
private String postStatus;
private String publishedDate;
private String summaryContent;
private String harvestDate;
private String languageId;
private String externalId;
private String regionId;
private String externalLink;
public String getContent() {
return content;
}
public String getId() {
return id;
}
public String getSourceApplication() {
return sourceApplication;
}
public String getTitle() {
return title;
}
public String getPostStatus() {
return postStatus;
}
public String getPublishedDate() {
return publishedDate;
}
public String getSummaryContent() {
return summaryContent;
}
public String getHarvestDate() {
return harvestDate;
}
public String getLanguageId() {
return languageId;
}
public String getExternalId() {
return externalId;
}
public String getRegionId() {
return regionId;
}
public String getExternalLink() {
return externalLink;
} }
**RESULT:**
Value for getId is: 168
Value for getSourceApplication is: adsense
Value for getExternalId is: 12122018
Value for getExternalLink is: www.gmail.com
NOTE
One has to change the fields in the json to begin with a lower case letter. The reason for the JSON change is that the Jackson bean serialisation will reflect over the class, and when it sees getXyz() and setXyz() methods will map these to a Json filed names "xyz" (and not "Xyz").I think there are several ways to override this behaviour, one is to use the one of the Jackson annotations.
Instead of creating so many public getters, you could simply modify private variables to public