Spring Boot Json Format - json

I want to create the Json Format as Shown below by using SpringBoot.
[
{
"name": "foo",
"albums": [
{
"title": "album_one",
"artist": "foo",
"ntracks": 12
},
{
"title": "album_two",
"artist": "foo",
"ntracks": 15
}
]
},
{
"name": "bar",
"albums": [
{
"title": "foo walks into a bar",
"artist": "bar",
"ntracks": 12
},
{
"title": "album_song",
"artist": "bar",
"ntracks": 17
}
]
}]
Please help me and please refer spring boot application which helps to create Json format as similar.

You don't need spring boot for this, you can do it using jackson.
You just need to define bean like:
public class ArtistInfo {
private String name;
private List<Album> albums;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Album> getAlbums() {
return albums;
}
public void setAlbums(List<Album> albums) {
this.albums = albums;
}
public static class Album {
private String title;
private String artist;
private int ntracks;
public Album(String title, String artist, int ntracks) {
super();
this.title = title;
this.artist = artist;
this.ntracks = ntracks;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getArtist() {
return artist;
}
public void setArtist(String artist) {
this.artist = artist;
}
public int getNtracks() {
return ntracks;
}
public void setNtracks(int ntracks) {
this.ntracks = ntracks;
}
}
}
Now you can use Jackson object mapper to produce JSON:
Initialize List of ArtistInfo
ObjectMapper mapper = new ObjectMapper();
List<ArtistInfo> artistInfos = initData();
String json = mapper.writeValueAsString(artistInfos);
System.out.println(json);
If you using this with Spring REST controller, spring will produce json if you return List of ArtistInfo

Related

How to create an rest api which accepts nested api as request

I am creating a rest api in spring boot as well as in jersey. I need to pass a nested JSON structure as request. I have no idea how to do it.
The nested structure is below,
{
"student": "",
"groupId": "a1",
"standard": "Fifth",
"isPassed": true,
"section": "A",
"data": {
"name": "Abcd",
"age": "11"
},
"additional": {
"Personal": {
"1": {
"address": {
"Home": [
"xys"
],
"Permanent": [
"xyz"
],
"Language": [
"English",
"French"
]
},
"street": "5",
"Mother": null,
"Father": null
}
}
"state": "xyz",
"Sibblings": true
}
}
I am expecting the rest call to accept this structure.
You can try something like this, first create request dto which will map the json to the DTO
import java.util.List;
public class RequestDTO {
private String student;
private String groupId;
private String standard;
private Boolean isPassed;
private String section;
private UserData data;
private Additional additional;
public String getStudent() {
return student;
}
public void setStudent(String student) {
this.student = student;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getStandard() {
return standard;
}
public void setStandard(String standard) {
this.standard = standard;
}
public Boolean getPassed() {
return isPassed;
}
public void setPassed(Boolean passed) {
isPassed = passed;
}
public String getSection() {
return section;
}
public void setSection(String section) {
this.section = section;
}
public UserData getData() {
return data;
}
public void setData(UserData data) {
this.data = data;
}
public Additional getAdditional() {
return additional;
}
public void setAdditional(Additional additional) {
this.additional = additional;
}
}
class UserData {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Additional{
private Personal personal;
private String state;
private Boolean Sibblings;
public Personal getPersonal() {
return personal;
}
public void setPersonal(Personal personal) {
this.personal = personal;
}
}
class Personal{
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
class Address{
private List<String> Home;
private List<String> Permanent;
private List<Language> Language;
public List<String> getHome() {
return Home;
}
public void setHome(List<String> home) {
Home = home;
}
}
enum Language{
English,French;
}
Second create a API handler which will accept this request
#RestController
#RequestMapping("/api")
public class AdminController {
#RequestMapping(value = "/test", method = RequestMethod.POST)
public RequestDTO postData(#RequestBody RequestDTO requestDTO) {
logger.info("Body---->", requestDTO);
return requestDTO;
}
}
You can test it via below curl
curl -X POST \
http://localhost:<PORT>/<context>/api/test \
-H 'Content-Type: application/json' \
-H 'Postman-Token: 7b66a9cf-8b69-4555-9bb2-1c186bff368d' \
-H 'cache-control: no-cache' \
-d '{
"student": "",
"groupId": "a1",
"standard": "Fifth",
"isPassed": true,
"section": "A",
"data": {
"name": "Abcd",
"age": "11"
},
"additional": {
"Personal": {
"address": {
"Home": [
"xys"
],
"Permanent": [
"xyz"
],
"Language": [
"English",
"French"
]
},
"street": "5",
"Mother": null,
"Father": null
},
"state": "xyz",
"Sibblings": true
}
}'
I will suggest you to go though offical docs for better understanding
class Data
{
private String name;
private Integer age;
}
class Student{
private String student;
private String groupId;
private String standard;
private Boolean isPassed;
private String section;
private Data data;
private Additional additional;
}
Here is something to get started with. Further nesting has to be done the similar way

Android - JSON parsing without the array name using Retrofit

I have json respose with no arrayname.
Below are the code till now I have done.
JSON Response
[
{
"id": 1,
"user_id": 101,
"name": "abc",
"number": 1234567890
},
{
"id": 2,
"user_id": 102,
"name": "xyzzy",
"number": 8888888888
},
{
"id": 3,
"user_id": 103,
"name":"sdfdsdv",
"number": 2222222222
}
]
Interface Class
public interface ApiInterface {
#GET("user/details”)
Call<List<User_List>> getUser(
#Query(“id”)String id
);
}
User_List Class
public class User_List {
#SerializedName("id")
#Expose
int id;
#SerializedName("user_id")
#Expose
int user_id;
#SerializedName("name")
#Expose
String name;
#SerializedName("number")
#Expose
Int number;
public int getId() {
return id;
}
public int getUser_id() {
return user_id;
}
public int getNumber() {
return number;
}
public String getName() {
return name;
}
}
MainActivity Class
Public void fetch() {
ApiInterface apiInterface = ApiClient.getRetrofit().create(ApiInterface.class);
Call<List<User_List>> user = apiInterface.getUser(id);
user(new Callback<List<user_List>>() {
#Override
public void onResponse(Call<List<user_List>> call, retrofit2.Response<List<user_List>> response) {
try{
if (response.isSuccessful()) {
for (int i = 0; i < user_list(); i++) {
int id = user_list.get(i).getId();
String name = user_list.get(i).getName();
}
}else {
}
}catch (Exception e){
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ArrayList<ProductEnquiry_Contributor>> call, Throwable t) {
}
});
}
I tried to parse it but can't find success,Can anyone suggest me how to parse this type of Response using Retrofit?
It gives me failure in response
Error: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
you can do this like this
#POST("endpoint)
Call<List<yourPOJO> methodname(#Body BodyPOJO bodyPojo);
or
#POST("endpoint)
Call<Response<List<yourPOJO>> methodname(#Body BodyPOJO bodyPojo);

Expected BEGIN_OBJECT but was NUMBER at line 1 column 65 path $.data

I am trying to use Gson library to parse an api response. Here is the response String:
{
"data": {
"Thresh": {
"id": 412,
"title": "Zincirli Gardiyan",
"name": "Thresh",
"key": "Thresh"
},
"Aatrox": {
"id": 266,
"title": "Darkin Kılıcı",
"name": "Aatrox",
"key": "Aatrox"
},
"Tryndamere": {
"id": 23,
"title": "Barbar Kral",
"name": "Tryndamere",
"key": "Tryndamere"
},
"Gragas": {
"id": 79,
"title": "Kavgacı Ayyaş",
"name": "Gragas",
"key": "Gragas"
},
"Cassiopeia": {
"id": 69,
"title": "Yılanın Şefkati",
"name": "Cassiopeia",
"key": "Cassiopeia"
},
"type": "champion",
"version": "4.14.2"
}
}
Here are my classes:
public class Champion {
private int id;
private String title;
private String name;
private String key;
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 getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
and response class:
public class ChampionsResponse {
private String type;
private String version;
private Map<String, Map<String, Champion>> data;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public Map<String, Map<String, Champion>> getData() {
return data;
}
public void setData(Map<String, Map<String, Champion>> data) {
this.data = data;
}
}
I use the following line to use gson library:
Gson gson = new Gson();
try{
ChampionsResponse championsResponse = gson.fromJson(response, ChampionsResponse.class);
}catch(Exception e){
e.printStackTrace();
}
But i get the exception saying that "Expected BEGIN_OBJECT but was NUMBER at line 1 column 65 path $.data..". Can anyone tell me where i am mistaken?
Thanks
I found the problem, i need to use
private Map<String, Map<String, String>> data;
instead of
private Map<String, Map<String, Champion>> data;

Json Array to Pojo

I'm trying to unmarshal the following Json array response to a collection of pojos in RestTemplate.
[{
"client":{
"id": 6364,
"name": "7Seven7 Insurance Inc",
"email": "donna#7seven7ins.com",
"currency": {"name":"United States of America, Dollars","symbol":"$"},
"address": "941 Elm Ave. #5 ",
"city": "Long Beach",
"province": "CA",
"zip_code": "90813",
"country": "United States",
"full_address_with_comma": "941 Elm Ave. #5, Long Beach, CA, 90813, United States",
"phone": "562-556-4035",
"fax":"562-381-7500",
"custom_field_name": "listed",
"custom_field_value": "false",
"created_at": "2010-07-18T00:08:10Z",
"updated_at": "2010-07-21T11:04:58Z",
}
},
{
"client":{
"id":6365,
"name": "Affinity",
"email":"CGregory#affinitygroup.com",
"address":"2575 Vista Del Mar ",
"city":"Ventura",
"province":"California",
"zip_code":"93001",
"country":"United States",
"full_address_with_comma":"2575 Vista Del Mar, Ventura, California, 93001, United States",
"phone":"(270) 901-2913",
"fax":null,
"currency":{"name":"United States of America, Dollars","symbol":"$"},
"custom_field_name":null,
"custom_field_value":null
"created_at":"2010-07-18T00:08:10Z",
"updated_at":"2010-07-18T00:08:10Z",
}
}]
I have created a corresponding Java Pojo class
public class Client {
#JsonProperty("id")
private String id;
#JsonProperty("name")
private String name;
#JsonProperty("currency")
private String currency;
#JsonProperty("address")
private String address;
#JsonProperty("city")
private String city;
#JsonProperty("province")
private String province;
#JsonProperty("zip_code")
private String zip_code;
#JsonProperty("country")
private String country;
#JsonProperty("full_address_with_comma")
private String full_address_with_comma;
#JsonProperty("phone")
private String phone;
#JsonProperty("fax")
private String fax;
#JsonProperty("custom_field_name")
private String custom_field_name;
#JsonProperty("custom_field_value")
private String custom_field_value;
#JsonProperty("created_at")
private String created_at;
#JsonProperty("updated_at")
private String updated_at;
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 getCurrency() {
return currency;
}
public void setCurrency(String currency) {
this.currency = currency;
}
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 getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getZip_code() {
return zip_code;
}
public void setZip_code(String zip_code) {
this.zip_code = zip_code;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getFull_address_with_comma() {
return full_address_with_comma;
}
public void setFull_address_with_comma(String full_address_with_comma) {
this.full_address_with_comma = full_address_with_comma;
}
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 String getCustom_field_name() {
return custom_field_name;
}
public void setCustom_field_name(String custom_field_name) {
this.custom_field_name = custom_field_name;
}
public String getCustom_field_value() {
return custom_field_value;
}
public void setCustom_field_value(String custom_field_value) {
this.custom_field_value = custom_field_value;
}
public String getCreated_at() {
return created_at;
}
public void setCreated_at(String created_at) {
this.created_at = created_at;
}
public String getUpdated_at() {
return updated_at;
}
public void setUpdated_at(String updated_at) {
this.updated_at = updated_at;
}
}
I'm using RestTemplate, but I have got an array of clients with empty attribute values.
Client[] clients= restTemplate.getForObject(requestUrl, Client[].class);
Most of your POJO fields are of type String but your JSON has values without double quotes (""). Your JSON should be as follows to be valid:
[
{
"client": {
"id": "6364",
"name": "7Seven7 Insurance Inc",
"email": "donna#7seven7ins.com",
"currency": {
"name": "United States of America, Dollars",
"symbol": "$"
},
"address": "941 Elm Ave. #5 ",
"city": "Long Beach",
"province": "CA",
"zip_code": "90813",
"country": "United States",
"full_address_with_comma": "941 Elm Ave. #5, Long Beach, CA, 90813, United States",
"phone": "562-556-4035",
"fax": "562-381-7500",
"custom_field_name": "listed",
"custom_field_value": "false",
"created_at": "2010-07-18T00:08:10Z",
"updated_at": "2010-07-21T11:04:58Z"
}
},
{
"client": {
"id": "6365",
"name": "Affinity",
"email": "CGregory#affinitygroup.com",
"address": "2575 Vista Del Mar ",
"city": "Ventura",
"province": "California",
"zip_code": "93001",
"country": "United States",
"full_address_with_comma": "2575 Vista Del Mar, Ventura, California, 93001, United States",
"phone": "(270) 901-2913",
"fax": "null",
"currency": {
"name": "United States of America, Dollars",
"symbol": "$"
},
"custom_field_name": "null",
"custom_field_value": "null",
"created_at": "2010-07-18T00:08:10Z",
"updated_at": "2010-07-18T00:08:10Z"
}
}
]
Also, your JSON has an email field but your Client POJO has not email field, and your declared currency field in the POJO is not a String, it's an object with two fields, so your Client POJO should be:
public class Client {
private String id;
private String name;
private String email;
private Currency currency;
private String address;
private String city;
private String province;
private String zip_code;
private String country;
private String full_address_with_comma;
private String phone;
private String fax;
private String custom_field_name;
private String custom_field_value;
private String created_at;
private String updated_at;
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 Currency getCurrency() {
return currency;
}
public void setCurrency(Currency currency) {
this.currency = currency;
}
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 getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getZip_code() {
return zip_code;
}
public void setZip_code(String zip_code) {
this.zip_code = zip_code;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getFull_address_with_comma() {
return full_address_with_comma;
}
public void setFull_address_with_comma(String full_address_with_comma) {
this.full_address_with_comma = full_address_with_comma;
}
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 String getCustom_field_name() {
return custom_field_name;
}
public void setCustom_field_name(String custom_field_name) {
this.custom_field_name = custom_field_name;
}
public String getCustom_field_value() {
return custom_field_value;
}
public void setCustom_field_value(String custom_field_value) {
this.custom_field_value = custom_field_value;
}
public String getCreated_at() {
return created_at;
}
public void setCreated_at(String created_at) {
this.created_at = created_at;
}
public String getUpdated_at() {
return updated_at;
}
public void setUpdated_at(String updated_at) {
this.updated_at = updated_at;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
with a new Currency object:
public class Currency {
private String name;
private String symbol;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
}
On the other hand, you are trying to deserialize an array of Client objects, but your JSON is an array of objects where each object contains a Client object, so you need to wrap it:
public class Cliente {
private Client client;
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
}
and then you could deserialize your JSON with the restTemplate or with an ObjectMapper.
With a restTemplate:
Cliente[] clients= restTemplate.getForObject(requestUrl, Cliente[].class);
With an ObjectMapper (Jackson's genericMessageConverter does exactly the same, it uses an ObjectMapper as follows):
Cliente[] clientes= mapper.readValue(jsonStr, Cliente[].class);
Another thing is, you do not need the #JsonProperty annotations in your POJO if your JSON fields have the same name in the JSON and in the POJO.

Gson fromJson parsing nested json

{
"status_code": 200,
"status_text": "Success",
"count": 96,
"data": [
{
"model": "Spark",
"fuel_type": "",
"price": "352109",
"state": "",
"city": "Agartala",
"crawl_date": "2013-10-02 05:00:02",
"make": "Chevrolet",
"variant": "New Spark 1.0 BS4 OBDII"
},
{
"model": "Spark",
"fuel_type": "",
"price": "378914",
"state": "",
"city": "Agartala",
"crawl_date": "2013-10-02 05:00:03",
"make": "Chevrolet",
"variant": "New Spark 1.0 LS BS4 OBDII"
}
]
}
Above is the JSON string.
The equivalent classes for the JSON object is as follows :
public class CarPriceResult {
private int status_code;
private String status_text;
private int count;
private List<CarData> CarData;
public CarPriceResult() {
super();
}
public int getStatus_code() {
return status_code;
}
public void setStatus_code(int status_code) {
this.status_code = status_code;
}
public String getStatus_text() {
return status_text;
}
public void setStatus_text(String status_text) {
this.status_text = status_text;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public List<CarData> getCarData() {
return this.CarData;
}
public void setCarData(List<CarData> carData) {
this.CarData = carData;
}
public static class CarData {
private String model;
private String fuel_type;
private String state;
private String city;
private String crawl_date;
private String make;
private String variant;
public String getModel() {
return model;
}
public CarData() {
super();
}
public void setModel(String model) {
this.model = model;
}
public String getFuel_type() {
return fuel_type;
}
public void setFuel_type(String fuel_type) {
this.fuel_type = fuel_type;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCrawl_date() {
return crawl_date;
}
public void setCrawl_date(String crawl_date) {
this.crawl_date = crawl_date;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getVariant() {
return variant;
}
public void setVariant(String variant) {
this.variant = variant;
}
}
}
The code to convert JSON to Java using Gson is as follows :
CarPriceResult cpr;
List<CarData> cd;
cpr = gson.fromJson(inputLine, CarPriceResult.class);
cd = cpr.getCarData();
object "cd" returns null and hence NPE is thrown.
what am I doing wrong?
Problem is in inputLine.
This code works well
String str = "{ \"status_code\": 200, \"status_text\": \"Success\", \"count\": 96, \"data\": [ { \"model\": \"Spark\",\"fuel_type\": \"\", \"price\": \"352109\", \"state\": \"\", \"city\": \"Agartala\", \"crawl_date\": \"2013-10-02 05:00:02\", \"make\": \"Chevrolet\", \"variant\": \"New Spark 1.0 BS4 OBDII\" }, { \"model\": \"Spark\", \"fuel_type\": \"\", \"price\": \"378914\", \"state\": \"\", \"city\": \"Agartala\", \"crawl_date\": \"2013-10-02 05:00:03\", \"make\": \"Chevrolet\", \"variant\": \"New Spark 1.0 LS BS4 OBDII\" } ] }";
CarPriceResult cpr = new Gson().fromJson(str, CarPriceResult.class);
List<CarData> cd = cpr.getCarData();
EDIT:
Also, your json does not correspond to class mapping
Json:
"data": [
class CarPriceResult
private List<CarData> CarData;
You should rename field to data or change key in json to CarData.
e.g.
Json:
"data": [
class CarPriceResult
private List<CarData> data;