Mapping JSON Array to Spring Hibernate Database (H2) - json

Hi I'm trying to map a JSON to databse table in SprinBoot.
This is my #Entity:
#Data
#AllArgsConstructor
#Entity
public class User {
#Id
#GeneratedValue( strategy = GenerationType.AUTO )
private Long id;
private String name;
private String tagline;
private String first_brewed;
#Column(length=700)
private String description;
private String image_url;
private Long ibu;
private String[] food_pairing;
public User() {}
}
And JSON looks that:
[
{
"id": 1,
"name": "Buzz",
"tagline": "A Real Bitter Experience.",
"first_brewed": "09/2007",
"description": "A light, crisp and bitter IPA brewed with English and American hops. A small batch brewed only once.",
"image_url": "https://images.punkapi.com/v2/keg.png",
"ibu": 60,
"food_pairing": [
"Spicy chicken tikka masala",
"Grilled chicken quesadilla",
"Caramel toffee cake"
]
}
]
I want to save this in to the H2 database.
Got only 1 column in the database with string of letters and numbers
My question is: How to change
private String[] food_pairing;
to show all food_pairings as a separate columns in the database?
(If I have an object in JSON i can do that in the #Entity:
#Embedded private Address address;
And then in other class:
#Embeddable public class Address {
private String street;
private String suite;
}
And I have a automatic created columns in my database. I want to do the same but not with an object in JSON only with an Array of Strings in JSON.

If I understand your requirement, you want to persist this array private String[] foodPairing; in one column. If so, you can proceed like below :
public class User {
....
#Transient
private String[] foodPairing;
#Column(name="food_pairing")
private String food_Pairing;
}
And before persisting your entity you can do this:
user.setFood_Paring(user.getFoodPairing().toString());
Then persist.
EDIT:
In case where you want each String in a one column, you can add 3 fields in your entity like this:
public class User {
....
#Transient
private String[] foodPairing;
#JsonIgnore
#Column(name="food_pairing1")
private String foodPairing1;
#JsonIgnore
#Column(name="food_pairing2")
private String foodPairing2;
#JsonIgnore
#Column(name="food_pairing3")
private String foodPairing3;
}
And when you persist:
user.setFoodParing1(user.getFoodPairing()[0]); //etc...

Related

Validate 2 Json Fields for Not Null at the same time

I have below JSON . At any point of time only one of the field "car" or "bike" can be null .Not both at the same time.How can I validate json using Jackson annotations.
All the fields in JSON are mandatory
{
"name": "John",
"age": 30,
"car": "Toyota",
"bike": "Honda"
}
My Java Pojo Objects
public class Example
{
#JsonProperty("name")
public String name;
#JsonProperty("age")
public Integer age;
#JsonProperty("car")
public String car;
#JsonProperty("bike")
public String bike;
Depending what you want, you can use #NotBlank from javax.validation.constraints.NotBlank;
public class Example
{
#NotBlank(message = "This field cannot be blank")
#JsonProperty("name")
public String name;
#JsonProperty("age")
public Integer age;
#JsonProperty("car")
public String car;
#JsonProperty("bike")
public String bike;
}
You can also try #NotNull or #NotEmpty from same package. They have some differences, see what best fit on your case.

Json Spring Boot Jackson How do I deserialise Json that has a child entity that has a namespace prefix?

I'm attempting to deserialize this json in my Spring Boot server application (which uses Jackson). Its throws an com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field. The prefix seems to be an issue and I can tell Jackson to ignore the user_metadata field and it works fine, however I do need to access that value. I've had a look through the various Spring #Json annotations and none seem to deal with the prefix.
{
"sub":"",
"nickname":"",
"name":"",
"picture":"",
"updated_at":"2020-05-01T11:23:01.110Z",
"email":"",
"email_verified":false,
"https://somedomain:eu:auth0:com/user_metadata":{
"tennant":"value"
}
}
And the model classes in Java
public class UserMetaData {
private String tennant;
public String getTennant() {
return tennant;
}
public void setTennant(String tennant) {
this.tennant = tennant;
}
}
public class UserInfo {
private String email;
private String sub;
private String picture;
private String nickname;
private Date updated_at;
private boolean email_verified;
private UserMetaData user_metadata;
private String name;
}
Getters and setters removed for brevity
Stack trace below:-
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "https://raptorsoftware:eu:auth0:com/user_metadata" (class uk.co.raptorsoftware.domain.UserInfo), not marked as ignorable (8 known properties: "sub", "user_metadata", "updated_at", "name", "email", "picture", "email_verified", "nickname"])
at [Source: (String)"{"sub":"","nickname":"darren.roberts","name":"","picture":"https://s.gravatar.com/avatar/c496e319edc303163f2e87e5ca91507d?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fda.png","updated_at":"2020-05-01T16:39:11.271Z","email":"darren.roberts#","email_verified":false,"https://raptorsoftware:eu:auth0:com/user_metadata":{"tennant":"some value"}}"; line: 1, column: 411] (through reference chain: uk.co.raptorsoftware.domain.UserInfo["https://raptorsoftware:eu:auth0:com/user_metadata"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61) at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:840)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1206)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1592)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1570)
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:4202)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3205)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3173)
at uk.co.raptorsoftware.web.BaseController.getUserInfo(BaseController.java:49)
at uk.co.raptorsoftware.web.MemberController.listMembers(MemberController.java:49)'''
The problem is the url as key of the UserMetaData. Try to use #JsonProperty
public class UserInfo {
private String email;
private String sub;
private String picture;
private String nickname;
private Date updated_at;
private boolean email_verified;
#JsonProperty(name="https://somedomain:eu:auth0:com/user_metadata")
private UserMetaData user_metadata;
private String name;
}

Spring MVC - get only a single object from an external json

i need to consume a RESTApi, which gives me a JSON output like this
{
"id": "e5d5ccc0-8da4-430d-b0ec-096d17ae2af8",
"car": [
{
"identifier": "XX000YY",
"formattedAddress": "Address 1",
"lat": 45.841664,
"lng": 18.199905,
"isOn": false,
"odometer": 763.4,
}
],
"location": "92589f4a-8c6e-4494-8548-b5428f8fa598"
}
Usually i would create a Wrapper Object
public class Wrapper{
private String id;
private Car car;
private String location;
//getters and setters
}
Then in my controller i would do something like this
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Wrapper> response = restTemplate.exchange(url, HttpMethod.POST, httpEntity,wrapper);
to get the response
But basically i need only the Car object, so i was thinking if there was a way to just return the it instead of the whole wrapper and taking the Car objects from it
First of all, you must create a serializable object like this :
Car.java
package com.wrapper;
public class Car implements Serializable{
public String identifier;
public String formattedAddress;
public Float lat;
public Float lng;
public Boolean isOn;
public Float odometer;
}
Wrapper.java
package com.wrapper;
import java.util.List;
public class Wrapper implements Serializable{
public String id;
public List<Car> car = null;
public String location;
}
After that, use a google API gson and use this instruction to get an object :
Wrapper wrapper = gson.fromJson(response, Wrapper.class);

How does gson maps json with POJO where json key has 2 space separated words

I have a yelp dataset in json format. I am using gson to map to POJOs. However, some keys like "Drive-Thru", "Good For" are hyphen or space separated. How to map POJO classes for these types of keys?
{
"business_id":"5UmKMjUEUNdYWqANhGckJw",
"attributes":{
"Take-out":true,
"Drive-Thru":false,
"Good For":{
"dessert":false,
"latenight":false
},
"Caters":false,
"Noise Level":"average",
"Has TV":false,
"Good For Groups":true,
"Wi-Fi":"free",
"Price Range":1
},
"type":"business"
}
I have following pojo but this returns me null for special key types
public class BusinessPojo {
private String type;
private String business_id;
private BusinessAttributes attributes;
// getters and setters
}
public class BusinessAttributes {
private boolean takeOut;
private boolean driveThru;
private boolean Caters;
private String noiseLevel;
private boolean hasTV;
private String wiFi;
private boolean goodforGroups;
private int priceRange;
private BusinessGoodFor goodFor;
//getters and setters
}
public class BusinessGoodFor {
private boolean dessert;
private boolean latenight;
//getters and setters
}
Gson provides a "serialized name" annotation:
public class BusinessAttributes {
#SerializedName("Take-out")
private boolean takeOut;
etc...

Spring controller #ResponseBody does not return exptected value

I have a Spring controller class which returns JSON having #ResponseBody. But strangely, it returns integer for double field. I am using JacksonMapper as JSON library. Here are the classes.
Phone
public class Phone implements Serializable {
#JsonProperty(value="phoneid")
private long phoneId;
private Plan plan;
private String sim;
private String imei;
#JsonProperty(value="phonetype")
private String phoneType;
#JsonProperty(value="phonenumber")
private String phoneNumber;
private String label;
#JsonProperty(value="connecteddate")
private String connectedDate;
//getters and setters
}
Plan
public class Plan implements Serializable {
#JsonProperty(value="planid")
private long planId;
#JsonProperty(value="planname")
private String planName;
private double billingIncrement;
private double owiStdUnitCost;
private double owiFlagFall;
private double stdCap;
private double dataCap;
private double smsCap;
private double owiDataUnitCost;
private double owiSms;
//getters and setters
}
PhoneResult
public class PhoneResult implements Serializable {
private boolean ok;
private String message;
private Phone result;
//getters and setters
}
When I return PhoneResult oject, it returns like this:
{
"ok": true,
"message": "",
"result":
{
"phoneid": 600003,
"phonenumber": "12343423",
"phonetype": "Samsung Galaxy S2",
"imei": "343242",
"sim": "1234324",
"label": "Mr Bean",
"connecteddate": "2012-09-19 00:00:00.0",
"plan":
{
"planid": 34,
"planname": "$59 Jeenee Plan",
"billingIncrement": 30,
"owiStdUnitCost": 81.8181818181818,
"owiFlagFall": 0,
"stdCap": 636.3636,
"dataCap": 227.2665,
"smsCap": 1363.638,
"owiDataUnitCost": 0.022194,
"owiSms": 22.7272727272727
}
}
}
billingIncrement and owiFlagFall has integer type even though those fields are double type in the classes and database. I do not want to care about this but I causes error when I convert the return JSON to object again using Spring resttemplate. It does not cause any error if those field have double type like 30.0 and 0.0. This looks weird behaviour but it is true.
Can you give me any advice? Your answer would be appreciated.