I have a database that looks like this on MySQL Workbench:
[mysql][1]
[1]: https://i.stack.imgur.com/WQmTp.png
I created an endpoint in Spring that returns all records from above database:
#RequestMapping("/api/v1/")
public class ProductController {
#Autowired
private ProductRepository productRepository;
// get all products
#GetMapping("/products")
public List<Product> getAllProducts() {
return productRepository.findAll();
}
}
Currently the endpoint returns JSON in this format:
[
{
"id": 1,
"name": "Brown Brim",
"price": 25,
"title": "Hats"
},
...
{
"id": 9,
"name": "Adidas NMD",
"price": 220,
"title": "Sneakers"
},
...
]
Just an array with all the data.
Is there a way to format it like this with a Java function?:
[
Hats: {"id":1, "name": "Brown Brim", "price":25},{... another product that is a hat},
Sneakers: {"id":9, "name": "Adidas NMD", "price": 220},{... more sneakers}
]
I want it to create an array of objects, where the object is identified by the "title" field and has the rest of values in an object inside.
Or do I need to change the database itself?
Thank you.
Related
I have a list of object. Object contain name and version now in the List we have different names with version and same name with different version.
eg:
[
{
"name": "ss",
"version": 1
},
{
"name": "ss",
"version": 2
},
{
"name": "sam",
"version": 1
},
{
"name": "sam",
"version": 2
},
{
"name": "sim",
"version": 1
}
]
Now in the response i need something like below
[
{
"name": "ss",
"version": 2
},
{
"name": "sam",
"version": 2
},
{
"name": "sim",
"version": 1
}
]
Can we do this using java8 features?
i think two solutions
you can use stream to solve the problem.first,group by the name field;then,get the bigger version.
you can use the map,when put a object to map,judge the version field.if the version is bigger,you can put it in map.
Assuming you have a POJO class like this:
class YourObject {
private String name;
private int version;
// setters & getters
}
this should do the trick:
import static java.util.Comparator.comparing;
import static java.util.function.BinaryOperator.maxBy;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
// ...
List<YourObject> list = ...
// ...
List<YourObject> maxVersions = new ArrayList<>(
list.stream()
.collect(toMap(YourObject::getName, identity(),
maxBy(comparing(YourObject::getVersion))))
.values()
);
Here is the sample JSON I want to deserialize with Jackson.
{
"person": {
"contacts": {
"address": {
"type": "Office",
"street": "1600 Amphitheatre Parkway",
"city": "Mountain View",
"state": "CA",
"zip": "94043",
"country": "United States"
},
"email": {
"type": "Home",
"emailAddress": "e.schmidt#google.com"
},
"phone": [
{
"type": "Mobile",
"phoneNumber": "+1 888 555555"
},
{
"type": "Home",
"phoneNumber": "+1 888 1111111"
}
],
"website": {
"type": "work",
"webService": "URL",
"webAddress": "www.google.com"
}
},
"firstName": "Eric",
"lastName": "Schmidt"
}
}
The tricky bit to deserialize here is the contacts node.
Things to note:
contacts is a polymorphic abstract type (see POJOs below)
the type information (e.g., `addresss) is contained as a key in a wrapper
this wrapper can be an object if there is only one value (email, address, website) OR an array if there are multiple (phone)
Target POJOs:
public class Person
{
public String firstName;
public String LastName;
public List<Contact> contacts; // mixes Address, Phone, Email, Website
}
public abstract class Contact {
public Long id;
}
public class Phone extends Contact
{
public String type;
public String phoneNumber;
}
// other subtypes of Contact omitted for brevity
note: external requirements require that I use the abstract Contact type. I would rather deserialize directly to these POJOs rather than having an intermediate Contacts POJO that the contact types hang off of and them manual mapping/converting to my List in another step.
I've looked over many other jackson + polymorphic deserialization questions, but none seem to handle this case (#2 and #3 in particular).
I want to deserialize the contacts object to a List<Contact>.
What is proper application of #JsonTypeInfo and #JsonSubTypes needed to achieve this?
(if anyone is interested this is CapsuleCRM's JSON format)
You'll need to write a custom deserializer and register it with Jackson. The implementation would check for initial start then parse accordingly. Think sax style processing.
I have a basic Rest Controller which returns a list of models in json to the client:
#RestController
public class DataControllerREST {
#Autowired
private DataService dataService;
#GetMapping("/data")
public List<Data> getData() {
return dataService.list();
}
}
Which returns data in this format:
[
{
"id": 1,
"name": "data 1",
"description": "description 1",
"active": true,
"img": "path/to/img"
},
// etc ...
]
Thats great for starting, but i thought about returning data of this format:
[
"success": true,
"count": 12,
"data": [
{
"id": 1,
"name": "data 1",
"description": "description 1",
"active": true,
"img": "path/to/img"
},
{
"id": 2,
"name": "data 2",
"description": "description 2",
"active": true,
"img": "path/to/img"
},
]
// etc ...
]
But i am not sure about this issue as i can not return any class as JSON... anybody has suggestions or advices?
Greetings and thanks!
"as i can not return any class as JSON" - says who?
In fact, that's exactly what you should do. In this case, you will want to create an outer class that contains all of the fields that you want. It would look something like this:
public class DataResponse {
private Boolean success;
private Integer count;
private List<Data> data;
<relevant getters and setters>
}
And your service code would change to something like this:
#GetMapping("/data")
public DataResponse getData() {
List<Data> results = dataService.list();
DataResponse response = new DataResponse ();
response.setSuccess(true);
response.setCount(results.size());
response.setData(results);
return response;
}
I have a JSON file like following:
{
"count": 60,
"value": [{
"changesetId": 60,
"url": "http://...",
"author": {
"id": "...",
"displayName": "*...",
"uniqueName": "...",
"url": "http://...*
"imageUrl": "http://..."
},
"checkedInBy": {
"id": "...",
"displayName": "...",
"uniqueName": "...",
"url": "http://...",
"imageUrl": "http://..."
},
"createdDate": "2016-11-08T22:05:11.17Z",
"comment": "..."
},
I am stuck at the point to create a model to use the API Gson. I started like:
public class Changesets{
int count;
*TODO* // model for the JSON above.
}
A start for the model or the entire model would be much appreciated. I will use this to deserialize.
Edit: I tried;
public class Changesets {
int count;
int changeset;
String url;
Changeset.Author author;
Changeset.CheckedInBy checkedInBy;
String createdDate;
String comment;
}
Where I could successfully write Changeset model.
If you really need to model the respective Java classes, you will need to reverse engineering the JSON structure.
In your case it will be something like this:
public class Changesets{
int count;
List<Change> value;
}
and I will let you complete the work.
However, if you only need an ad hoc Java object to deal with a complex JSON object in which you are only interested in a very specific property value, you can use the solution I suggested in this answer:
Dynamic JSON structure to Java structure
I'm programming one android list-detail application and I have to load app structure from json. I'm trying to deserialize non-optimal json with Gson (Java) to objects, from that I'm going to dynamically generate fragments (I hope it can be done :-) ).
I have tabs within main FragmentActivity and one tab has own fragment and own json. Every tabs has own fragmentstack for controlling with back and up button.
I have this json:
{
"data": [],
"children": [
{
"data": {
"id": "5",
"deep": "0",
"url": "compare",
"type": "navigation",
"name": "Vergleich",
"text": null,
"number": null
},
"children": [
{
"data": {
"id": "12",
"deep": "1",
"url": "information",
"type": "navigation",
"name": "information",
"text": null,
"number": null
},
"children": []
},
{
"data": {
"id": "13",
"deep": "1",
"url": "application",
"type": "navigation",
"name": "application",
"text": null,
"number": null
},
"children": []
}
]
}
]
}
and I created this classes for gson:
public class StructureItem {
StructureData data;
ArrayList<StructureItem> children;
}
public class StructureData {
public int id;
public int deep;
public String url;
public String type;
public String name;
public String text;
public String number;
}
I tried to create Object with:
String s = LoadJson();
Gson gson = gsonBuilder.create();
StructureItem root = gson.fromJson(s, StructureItem.class);
But cannot succeed.
How would you solve my problem? Any easy solution?
It would be awesome has some notes for this.
I'm programming for couple years, but this is my first android project. Quite monstrous framework!
Try to replace ArrayList<StructureItem> to StructureItem[] in class StructureItem.