I am referring to this example here to serialize my object.
I have this initially and it works.
public class MyClass implements Serializable {
private String mediaitem_id;
private String customer_id;
private int quantity;
public MyClass(String item, String customer, int quantity){
this.mediaitem_id = item;
this.customer_id = customer;
this.quantity = quantity;
}
public String toJson(){
ObjectMapper mapper = new ObjectMapper();
try{
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE);
return mapper.writeValueAsString(this);
}catch(Exception ex){
log.error("Error converting MyClass to json " + this, ex);
}
return "";
}
}
MyClass myClass = new MyClass("1234", "23234", 5);
myClass.toJson() gives the below, which is what I want:
{ mediaitem_id: '1234', customer_id: '23234', quantity: 5 }
But now I need to add an arraylist to the class and need to serialise it as well, so I add a new class Account:
public static class Account implements Serializable {
public String accountname;
public String accountid;
public Account(String accountname, String accountid) {
this.accountname = accountname;
this.accountid = accountid;
}
}
public class MyClass implements Serializable {
private String mediaitem_id;
private String customer_id;
private int quantity;
private List<Account> accounts = new ArrayList<>();
public MyClass(String item, String customer, int quantity){
this.mediaitem_id = item;
this.customer_id = customer;
this.quantity = quantity;
}
public void addAccount(String accountname, String accountid) {
Account anAccount = new Account(accountname, accountid);
accounts.add(anAccount);
}
public String toJson(){
ObjectMapper mapper = new ObjectMapper();
try{
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE);
return mapper.writeValueAsString(this);
}catch(Exception ex){
log.error("Error converting MyClass to json " + this, ex);
}
return "";
}
}
MyClass myClass = new MyClass("1234", "23234", 5);
myClass.addAccount("acc-01", "a001");
myClass.addAccount("acc-02", "a002");
myClass.toJson() still gives the same:
{ mediaitem_id: '1234', customer_id: '23234', quantity: 5 }
What am I missing now?
I wanted to get something like:
{ mediaitem_id: '1234', customer_id: '23234', quantity: 5, accounts: [{accountname: 'acc-01', accountid: 'a001'}, {accountname: 'acc-02', accountid: 'a002'}]}
I recommed add your getter and setter for all property in your MyClass .
public String getMediaitem_id() {
return mediaitem_id;
}
public void setMediaitem_id(String mediaitem_id) {
this.mediaitem_id = mediaitem_id;
}
public String getCustomer_id() {
return customer_id;
}
public void setCustomer_id(String customer_id) {
this.customer_id = customer_id;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
Related
The I am getting the above exception on a model which does contain the field. The exception also appears to be sporadic which is further cause for concern. I certainly can wrap the class with
JsonIgnoreProperties(ignoreUnknown = true)
But certainly will not want to do this.
The model is as follows:
public class OrderCommand {
private int orderId;
private String item;
private int numberOfItems;
private double price;
private Payment payment;
private String[] packages;
private List<Shipment> shipment;
private String orderStatus;
public OrderCommand(){}
public OrderCommand(String item, int numberOfItems, double price, OffsetDateTime timeStamp) {
this.item = item;
this.numberOfItems = numberOfItems;
this.price = price;
orderId = timeStamp.getNano();
}
public OrderCommand setOrderStatus(String orderStatus) {
this.orderStatus = orderStatus;
return this;
}
public String getOrderStatus(){
return this.orderStatus;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public int getNumberOfItems() {
return numberOfItems;
}
public void setNumberOfItems(int numberOfItems) {
this.numberOfItems = numberOfItems;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public void setPackages(String[] packages) {
this.packages = packages;
}
public String[] getPackages(){
return packages;
}
public void setShipment(List<Shipment> shipment) {
this.shipment = shipment;
}
public List<Shipment> getShipment(){
return this.shipment;
}
public String toString(){
return ReflectionToStringBuilder.toString(this);
}
public Payment getPayment() {
return payment;
}
public OrderCommand setPayment(Payment payment) {
this.payment = payment;
return this;
}
}
and the offending JSON is:
{
"item": "headphones",
"price": 200.0,
"orderId": 600000000,
"payment": {
"charge": 200.0,
"paymentMethod": "VISA",
"success": true,
"failureReason": null,
"accountNumber": "1234"
},
"packages": [
"headphones.package0",
"headphones.package1"
],
"shipment": null,
"orderStatus": "PAYMENT-RECEIVED",
"numberOfItems": 2
}
How do I prevent this from happening and get deserialization happening reliably?
EDIT 1:
The exception indicates that the payment field is not recognized. The payment class is:
public class Payment {
private double charge;
private String paymentMethod;
private boolean success;
private String failureReason;
private String accountNumber;
public double getCharge() {
return charge;
}
public Payment setCharge(double charge) {
this.charge = charge;
return this;
}
public String getPaymentMethod() {
return paymentMethod;
}
public Payment setPaymentMethod(String paymentMethod) {
this.paymentMethod = paymentMethod;
return this;
}
public boolean getSuccess() {
return success;
}
public Payment setSuccess(boolean success) {
this.success = success;
return this;
}
public String getFailureReason() {
return failureReason;
}
public Payment setFailureReason(String failureReason) {
this.failureReason = failureReason;
return this;
}
public String getAccountNumber() {
return accountNumber;
}
public Payment setAccountNumber(String accountNumber) {
this.accountNumber = accountNumber;
return this;
}
}
EDIT 2
Full exception is as follows:
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field \"payment\" (class com.sailpoint.rss.rss_service.model.OrderCommand), not marked as ignorable (8 known properties: \"numberOfItems\", \"item\", \"orderId\", \"shipment\", \"packages\", \"orderProcessingTime\", \"orderProcessed\", \"price\"])
at [Source: (String)\"{\"item\":\"headphones\",\"price\":200.0,\"orderId\":36000000,\"payment\":{\"charge\":200.0,\"paymentMethod\":\"VISA\",\"success\":true,\"failureReason\":null,\"accountNumber\":\"1234\"},\"packages\":null,\"shipment\":null,\"orderStatus\":\"PAYMENT-RECEIVED\",\"numberOfItems\":2}\"; line: 1, column: 66] (through reference chain: com.sailpoint.rss.rss_service.model.OrderCommand[\"payment\"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:823)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1153)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1589)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1567)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4014)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3005)
at io.zeebe.client.impl.ZeebeObjectMapper.fromJson(ZeebeObjectMapper.java:36)
Did not also mention but happens sporadically.
My experienced guess (in the absence of more details) is that the problem is with either orderStatus or payment because both setOrderStatus and setPayment return a value and not void.
Jackson cares about such things so I recommend annotating both methods with #JsonSetter.
The problem could also be with payment but it is impossible to tell since you didn't say which field could not be deserialized and you also didn't post the source code for the Payment class.
in this case, i want to show Json to an response page in java hibernate, query method from DAO like this:
public List<TransactionQR> getAllTransaction() throws HibernateException {
return this.session.createQuery("FROM TransactionQR tr, Batch b, Terminal t, User_Smartphone us, Merchant mc WHERE tr.batch = b.id AND b.user_smartphone = us.id AND b.terminal = t.id AND t.merchant = mc.id AND state = '1' ").list();
}
then in servlet class i try to convert the list into json using Json object and json array then write in response like this:
int start = 0;
String jsonResult = null;
JSONObject jo=new JSONObject();
HttpServletRequest request = context.getRequest();
HttpServletResponse response = context.getResponse();
HttpSession session = context.getSession();
DB db = getDB(context);
//JSONObject jo = new JSONObject();
QRTransactionDao QR = new QRTransactionDao(db);
//Gson objGson = new GsonBuilder().setPrettyPrinting().create();
//String json = objGson.toJson(QR.getAllTransaction());
//System.out.println(json);
List<TransactionQR> str = QR.getAllTransaction();
JSONArray array = new JSONArray();
for(TransactionQR tr : str){
JSONObject str3 = new JSONObject();
str3.put("amount", tr.getAmount());
context.put("jsoncontent", jsonResult);
array.add(str3);
}
jo.put("status", "ok");
jo.put("dataqr", array);
jsonResult=jo.toString();
response.setContentType("application/json");
response.getWriter().print(jsonResult);
but i got the error on syntax in this line loop:
for(TransactionQR tr : str){
the error like this:
[Ljava.lang.Object; cannot be cast to Transaction
here the model Transaction:
package id.co.keriss.consolidate.ee;
import java.io.Serializable;
import java.util.Date;
public class TransactionQR implements Serializable{
private Long id;
private String codeqr;
private Date approvaltime;
private String merchant;
private String code_merchant;
private Long amount;
private Long saldoawal;
private Integer tracenumber;
private String state;
private Date createdate;
private Batch batch;
public TransactionQR() {
}
public TransactionQR(Long id, String codeqr, Date approvaltime, String merchant, String code_merchant, Long amount,
Long saldoawal, Integer tracenumber, String state, Date createdate, Batch batch) {
super();
this.id = id;
this.codeqr = codeqr;
this.approvaltime = approvaltime;
this.merchant = merchant;
this.code_merchant = code_merchant;
this.amount = amount;
this.saldoawal = saldoawal;
this.tracenumber = tracenumber;
this.state = state;
this.createdate = createdate;
this.batch = batch;
}
public Long getId() {
return id;
}
public Date getApprovalTime() {
return approvaltime;
}
public Batch getBatch() {
return batch;
}
public void setBatch(Batch batch) {
this.batch = batch;
}
public void setApprovalTime(Date approvalTime) {
this.approvaltime = approvalTime;
}
public void setId(Long id) {
this.id = id;
}
public Date getApprovaltime() {
return approvaltime;
}
public void setApprovaltime(Date approvaltime) {
this.approvaltime = approvaltime;
}
public String getCodeqr() {
return codeqr;
}
public void setCodeqr(String codeqr) {
this.codeqr = codeqr;
}
public String getMerchant() {
return merchant;
}
public void setMerchant(String merchant) {
this.merchant = merchant;
}
public String getCode_merchant() {
return code_merchant;
}
public void setCode_merchant(String code_merchant) {
this.code_merchant = code_merchant;
}
public Long getAmount() {
return amount;
}
public void setAmount(Long amount) {
this.amount = amount;
}
public Long getSaldoawal() {
return saldoawal;
}
public void setSaldoawal(Long saldoawal) {
this.saldoawal = saldoawal;
}
public Integer getTracenumber() {
return tracenumber;
}
public void setTracenumber(Integer tracenumber) {
this.tracenumber = tracenumber;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Date getCreatedate() {
return createdate;
}
public void setCreatedate(Date createdate) {
this.createdate = createdate;
}
}
i have try to handle the list with Gson:
Gson objGson = new GsonBuilder().setPrettyPrinting().create();
String json = objGson.toJson(QR.getAllTransaction());
System.out.println(json);
in that way, it's work to show but it's not from POJO right i want work with pojo to parse the data to json ?
why i get the error can't cast to model ? any clue ?
Try adding Select tr to your query in getAllTransaction()
Wich is the relation between QRTransactionDao and TransactionQR ?
i would like to parse this json but im not able to do it. Heres the Json Structure:
For example: I would like to get String product type => Car
this Code doesnt work:
JSONObject mainData = response.getJSONObject("decode");
String productType = mainData.getString("Product Type");
Please help
decode is an array not an object so it should be
JSONArray mainData = response.getJSONArray("decode");
And then you can get inside objects using the index.
JSONObject jsonObj = mainData.getJSONObject(0);
String answer = jsonObj.getString("label"); //Make
You can try to use Gson
Define your class with something like that
public class YourClass implements Parcelable {
private int price;
#SerializedName("price_currency")
private String priceCurrency;
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getPriceCurrency() {
return priceCurrency;
}
public void setPriceCurrency(String priceCurrency) {
this.priceCurrency = priceCurrency;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(this.price);
dest.writeString(this.priceCurrency);
}
public YourClass() {
}
protected YourClass(Parcel in) {
super(in);
this.price = in.readInt();
this.priceCurrency = in.readString();
}
public static final Creator<YourClass> CREATOR = new Creator<YourClass>() {
#Override
public Pessoa createFromParcel(Parcel source) {
return new YourClass(source);
}
#Override
public YourClass[] newArray(int size) {
return new YourClass[size];
}
};
}
and try to convert your json with something like this
Gson gson = new Gson();
YourClass yourClass = gson.fromJson(yourJson, YourClass.class);
If you really want to do this correctly, you'll need a custom JsonDeserializer. Like this:
public class CarDeserializer implements JsonDeserializer<Car> {
#Override
public Car deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
Car car = new Gson().fromJson(json.toString(), Car.class);
try {
JSONObject object = new JSONObject(json.toString());
car.setCurrency(Currency.getInstance(object.getString("price_currency")));
car.setBalance(object.getJSONObject("balance").getInt("API Decode"));
JSONArray decodeArray = object.getJSONArray("decode");
for (int i = 0; i < decodeArray.length(); i++){
JSONObject decodeObject = (JSONObject) decodeArray.get(i);
if (decodeObject.get("label").equals("Make")){
car.setMake(decodeObject.getString("value"));
} else if (decodeObject.get("label").equals("Manufacturer")){
car.setManufacturer(decodeObject.getString("value"));
} else if (decodeObject.get("label").equals("Plant Country")){
car.setPlantCountry(decodeObject.getString("value"));
} else if (decodeObject.get("label").equals("Product Type")){
car.setProductType(decodeObject.getString("value"));
}
}
} catch (JSONException e){
Log.e("CarDeserializer", e.toString(), e);
}
return car;
}
}
The Car object looks like this:
public class Car {
private int price;
private transient Currency currency;
private transient int balance;
private transient String make;
private transient String manufacturer;
private transient String plantCountry;
private transient String productType;
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public Currency getCurrency() {
return currency;
}
public void setCurrency(Currency currency) {
this.currency = currency;
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getManufacturer() {
return manufacturer;
}
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
public String getPlantCountry() {
return plantCountry;
}
public void setPlantCountry(String plantCountry) {
this.plantCountry = plantCountry;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
}
If Currency doesn't work for you, you can change that one to a String type like this:
#SerializedName("price_currency") private String currency;
And change the getter and setter accordingly.
If you have more objects in the decode array. You can add them as more branches in the deserializer.
This is used like this:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Car.class, new CarDeserializer());
Gson gson = gsonBuilder.create();
gson.fromJson(myJsonString, Car.class);
Note: The transient keyword in the Car class indicates to Gson that it shouldn't attempt to automatically parse the json for those fields.
Note 2: You'll need to include Gson in your project if you haven't already added it.
I have the following json which has a product array with product_id as each array.Product ids are numbers. When I am looking online for the pojo classes I am getting Class names which starts with digits which is not allowed.
{
"_id:" : "1234AG567",
"products" : {
"1234":{
"product_name" : "xyz",
"product_type" : "abc"
},
"3456":{
"product_name" : "zzz",
"product_type" : "def"
}
}
}
Below are the Pojo classes I am getting
public class MyPojo
{
private Products products;
public Products getProducts ()
{
return products;
}
public void setProducts (Products products)
{
this.products = products;
}
#Override
public String toString()
{
return "ClassPojo [products = "+products+"]";
}
}
public class Products
{
private 1234 1234;
private 3456 3456;
public 1234 get1234 ()
{
return 1234;
}
public void set1234 (1234 1234)
{
this.1234 = 1234;
}
public 3456 get3456 ()
{
return 3456;
}
public void set3456 (3456 3456)
{
this.3456 = 3456;
}
#Override
public String toString()
{
return "ClassPojo [1234 = "+1234+", 3456 = "+3456+"]";
}
}
public class 3456
{
private String product_name;
private String product_type;
public String getProduct_name ()
{
return product_name;
}
public void setProduct_name (String product_name)
{
this.product_name = product_name;
}
public String getProduct_type ()
{
return product_type;
}
public void setProduct_type (String product_type)
{
this.product_type = product_type;
}
#Override
public String toString()
{
return "ClassPojo [product_name = "+product_name+", product_type = "+product_type+"]";
}
}
public class 1234
{
private String product_name;
private String product_type;
public String getProduct_name ()
{
return product_name;
}
public void setProduct_name (String product_name)
{
this.product_name = product_name;
}
public String getProduct_type ()
{
return product_type;
}
public void setProduct_type (String product_type)
{
this.product_type = product_type;
}
#Override
public String toString()
{
return "ClassPojo [product_name = "+product_name+", product_type = "+product_type+"]";
}
}
I have used the http://pojo.sodhanalibrary.com/ to convert
Any help how to create pojo for this JSON is welcome. Thanks in advance.
You can use Map to store the products and wrap it in another class to store the whole json. E.g. Product class would look like this:
class Product {
#JsonProperty("product_name")
private String productName;
#JsonProperty("product_type")
private String productType;
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductType() {
return productType;
}
public void setProductType(String productType) {
this.productType = productType;
}
}
Wrapper class would look like this:
class ProductList{
#JsonProperty("_id")
private String id;
private Map<String, Product> products;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Map<String, Product> getProducts() {
return products;
}
public void setProducts(Map<String, Product> products) {
this.products = products;
}
}
Here's is the deserialization example with Jackson:
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
ProductList list = mapper.readValue("{\"_id\" : \"1234AG567\",\"products\" : {\"1234\":{\"product_name\" : \"xyz\",\"product_type\" : \"abc\"},\"3456\":{\"product_name\" : \"zzz\",\"product_type\" : \"def\"}}}", ProductList.class);
System.out.println(list.getId());
System.out.println(list.getProducts());
}
Please note that your json has a typo in it. Id field should be _id and not _id: (if that is the actual field name then you can change JsonProperty annotation to _id:.
Here is documentation for Jackson.
The JSON is valid, but you WILL NOT be able to create POJOs to represent that. Like you have already seen, you cannot create classes that begin with numbers, and you don't want to do this anyway as they won't provide any meaning to you.
I'm going to guess that products is an array of Product, and that number is an ID or something. The JSON should look something like this:
{
"products": [
{
"id": "1234",
"product_name": "xyz",
"product_type": "abc"
},
{
"id": "3456",
"product_name": "zzz",
"product_type": "def"
}]
}
Which would deserialize into a class that contains
private List<Product> products;
assuming that that the Product class looks like
class Product {
private Integer id;
#JsonProperty(value = "product_name")
private String productName;
#JsonProperty(value = "product_type")
private String productType;
}
I am trying to show a combobox for each record that is fetched from database,but unfortunatley i can't get any combobox in expected column.
Here is code for my model class:
public class Employee {
private final int id;
private final SimpleStringProperty ename;
private final SimpleStringProperty ecnic;
private final SimpleDoubleProperty ebalance;
private final SimpleDoubleProperty etotalpaid;
private SimpleStringProperty estatus;
public Employee(int id, String ename, String ecnic, Double ebalance,
Double etotalpaid, String estatus) {
super();
this.id = id;
this.ename = new SimpleStringProperty(ename);
this.ecnic = new SimpleStringProperty(ecnic);
this.ebalance = new SimpleDoubleProperty(ebalance);
this.etotalpaid = new SimpleDoubleProperty(etotalpaid);
this.estatus = new SimpleStringProperty(estatus);
}
public String getEstatusproperty() {
return estatus.get();
}
public String getEstatus() {
return estatus.get();
}
public void setEstatus(String estatus) {
this.estatus = new SimpleStringProperty(estatus);
}
public int getId() {
return id;
}
public String getEname() {
return ename.get();
}
public String getEcnic() {
return ecnic.get();
}
public Double getEbalance() {
return ebalance.get();
}
public Double getEtotalpaid() {
return etotalpaid.get();
}
}
Here is code for my method that i call to fetch data from database..
public void attendence() throws SQLException{
employeelist = FXCollections.observableArrayList();
ename.setCellValueFactory(new PropertyValueFactory<Employee,String>("ename"));
ecnic.setCellValueFactory(new PropertyValueFactory<Employee,String>("ecnic"));
ebalance.setCellValueFactory(new PropertyValueFactory<Employee,Double>("ebalance"));
etotalpaid.setCellValueFactory(new PropertyValueFactory<Employee,Double>("etotalpaid"));
estatus.setCellValueFactory(new PropertyValueFactory<Employee,String>("estatus"));
estatus.setCellFactory(ComboBoxTableCell.forTableColumn(new DefaultStringConverter(), attendenceoptions));
estatus.setOnEditCommit(
new EventHandler<CellEditEvent<Employee, String>>() {
#Override
public void handle(CellEditEvent<Employee, String> t) {
((Employee) t.getTableView().getItems().get(t.getTablePosition().getRow())).setEstatus(t.getNewValue());
};
});
estatus.setEditable(true);
stmt = conn.createStatement();
sql = "select * from employe";
rs = stmt.executeQuery(sql);
while(rs.next()){
employeelist.add(new Employee(rs.getInt(1),rs.getString(2),rs.getString(3),rs.getDouble(5),rs.getDouble(6),"Present"));
employeetable.setItems(employeelist);
}
stmt.close();
rs.close();
}
}
Added this in method to solve issue.
employeetable.setEditable(true);