Creating Json Object Template From Objects Of Objects - java

I have one JSON which looks something like this
{
"uniqueId":"junk",
"buildingId":"123",
"famousFor":[
{
"famousForId":"asd",
"name":"Gaming",
"activeState":true
}
],
"openHours":[
{
"day":"Sunday",
"timingsFrom":{
"time":"11:00",
"meridian":"AM"
},
"timingsTo":{
"time":"11:59",
"meridian":"PM"
}
}
],
"uploadedImages":{
"coverPhoto":[
{
"imageUrl":"http://google.com/images/a123a.png",
"activeState":false
}
],
"profilePhoto":[
{
"imageUrl":"http://google.com/images/a123a.png,
" activeState":false
}
]
},
"fDescriptions":[
{
"fMapUrl":"http://google.com/images/a123a.png",
"tag":"1"
}
],
"Outlets":[
{
"outletName":"Halo",
"floorNumber":1,
"category":"Gaming"
}
]
}
Now the thing is I have to create one GET API which essentially will provide me the same template with empty value. While returning the Object it's sending me the null value. How can I standardized the template that looks the same. My Object looks something like this.
public class EssentialDetails {
#NotBlank(message=ApplicationUtil.MISSING_FIELD)
#Valid
#Pattern(regexp = "[0-9]+$",message="DP ID Must be Number")
String dpId;
#Id #NotBlank(message= ApplicationUtil.MISSING_FIELD)
#Valid
#Pattern(regexp = "[A-Za-z0-9]+$",message="Must Be Combination of Number and Letters")
String tpId;
#NotNull(message=ApplicationUtil.MISSING_FIELD) #Valid
List<FamousFor> famousFor;
#NotNull(message=ApplicationUtil.MISSING_FIELD) #Valid
List<OpenHours> openHours;
#NotNull(message=ApplicationUtil.MISSING_FIELD) #Valid
Pictures uploadedImages;
#NotNull(message=ApplicationUtil.MISSING_FIELD) #Valid
List<FloorDescription> floorDescriptions;
#NotNull(message=ApplicationUtil.MISSING_FIELD) #Valid
List<Outlets> mallOutlets;
}
How can I pass the empty template with every field present within the template? I'm using java 8 and spring boot 2.0.6.

Incase of empty or null or some valid values below annotation can be used above property of your model
#JsonInclude(ALWAYS)

Related

How to use WebMvcLinkBuilder with repository's findById?

I'm trying to use Spring Data Rest to implement a full set of services for about 60 entities. Right now, I'm getting by with just letting Spring use my repositories rather than implementing controllers, which is great!
The data I'm having to model isn't ideal--I'd prefer to have customerId come as part of the order object.
{
"tenantId": 42,
"id": "00000001",
"customer": {
"tenantId": 42,
"id": "CUST001",
"name": "Arthur Dent"
}
}
I have the ID for a related entity as a property on my JSON object.
public class Order {
Long tenantId;
String id;
String customerId;
}
I don't really want to pull the full Customer entity and all of the other related entities and place them as members on my Order object. Instead, I'd just like to add some links to the _links collection.
I believe I've figured out WebMvcLinkBuilder finally and I have the basic idea in place. However, JpaRepository.findById returns a java.util.Optional.
#Bean
public RepresentationModelProcessor<EntityModel<Order>> orderProcessor() {
return new RepresentationModelProcessor<EntityModel<Order>>() {
#Override
public EntityModel<Order> process(final EntityModel<Order> model) {
final CustomerRepository controller = WebMvcLinkBuilder.methodOn(CustomerRepository);
final CustomerId id = new CustomerId(model.getContent().getTenantId(), model.getContent().getCustomerId());
model.add(WebMvcLinkBuilder.linkTo(controller.findById(id)).withRel("customer"));
return model;
}
};
}
The error I get is:
Could not generate CGLIB subclass of class java.util.Optional: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class java.util.Optional
How can I add a link to my resource?

Return an array of objects with fieldName in spring boot

I am new to springboot. My requirement is as below.
I have carModel class as below.
#Data
public class CarModel {
private modelName;
private available;
}
Now I have a rest endpoint that returns the list of objects. So the resource looked something like this.
#GetMapping("/models")
public List<CarModel> getModels(){
//Resource Body
}
But this return an array of objects in json, with no field name. But I need the the json , something like this:
{ "AllModels" : [ { "modelName" : "Ferrari", "available" : "Yes"} , {"modelName": "Tesla" , "available" : "Yes"} ]
How can I do this in spring boot? I do know of a solution by defining one more wrapper class with list of CarModel objects in it. But is there any better way of doing it(Something like any annotations, etc.,)
Thanks!
You can use ResponseEntity method that is already there available in Spring MVC. Would something like this work for you?
#GetMapping("/models")
public ResponseEntity<List<CarModel>> getCars() {
List<CarModel> carModels = service.methodThatReturnsListOfCarModels();
return ResponseEntity.ok().body(new HashMap<>(){{put("AllModels", carModels);}});
}

Define required fields in POJO class for JSON mapping

I am mapping my API JSON response to Java object using ObjectMapper (Jackson). Below is how my json looks like :
[
{
firstKey : "value1",
secondKey : "value2",
thirdKey : "value3"
},
{
firstKey : "value4",
secondKey : "value5",
thirdKey : "value6"
}
]
Required fields are :
firstKey
secondKey
thirdKey
Some of my JSON responses might not have all these three required fields, for which I would like Jackson to throw exception while deserializing. How should I let Jackson know about the required fields ? Is there any annotation for it, except JsonProperty(required = true) since this does not works ?
Also, if a key has null value, it is accepted default value, so I cannot use #NotNull as well. For eg :
[
{
firstKey : null,
secondKey : "value2",
thirKey : "value3"
}
]
Above is valid JSON and should parsed without any exception during deserialization.
Validation functionality overall is not implemented in Jackson since it is considered to be out of scope, see for example Jackson - Required property?.
And some information about why the annotation #JsonProperty(required = true) does not work on field can be found here: Jackson #JsonProperty(required=true) doesn't throw an exception.
However there is a trick that might work for null & existing well-valued fields values but throw an exception if the field is missing completely. Create a constructor with annotation #JsonCreator (and do not create a default constructor!) where the same annotation #JsonProperty(value = "*field_name*", required = true) is used and it will throw in case of missing field, so like:
#Getter #Setter
public class KeyHolder {
private String firstKey;
private String secondKey;
private String thirdKey;
#JsonCreator
public KeyHolder(
#JsonProperty(value = "firstKey", required = true) String firstKey,
#JsonProperty(value = "secondKey", required = true) String secondKey,
#JsonProperty(value = "thirdKey", required = true) String thirdKey) {
this.firstKey = firstKey;
this.secondKey = secondKey;
this.thirdKey = thirdKey;
}
}
With these, doing:
new ObjectMapper().readValue("{ \"firstKey\": \"val1\", \"secondKey\": \"val2\" }"
, KeyHolder.class);
should result into something like:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Missing required creator property 'thirdKey' (index 2)
Any required parameter needs also to be a constructor parameter. So if there is added field fourthKey the constructor needs also a fix so like adding:
#JsonProperty(value = "fourthKey", required = true) String fourthKey) {
and
this.fourthKey = fourthKey;

How to make POJO dynamic so that it ignores an json tag but reads the value under that tag using jackson in java?

I've a parent DAO:
#XmlRootElement//(name="metadata")
public class FolderAttributes {
private Map nameValueForListValue;
Child DAO:
#XmlAccessorType(XmlAccessType.FIELD)
public class ListWrapper {
#XmlElementWrapper(name = "attrValue")
private List<Object> list;
JSON request that works (if I use "metadata" name as root element):
"metadata": {
"nameValueForListValue": {
"signed": {
"attrValue": [
"ahsdfhgakjf"
]
},
"id": {
"attrValue": [
"12345678",
"87654321"
]
},
.......... continues
I don't want the tag "nameValueForListValue" in request, instead it should be smart enough to read rest of the values without that tag. Looks like it always needs to have the param name "nameValueForListValue" on the request. Is there any annotations that will do my job easier? I'm using Java 6 & jackson 1.9.
What about using #JsonAnySetter Jackson annotation
It would be something like:
#XmlRootElement//(name="metadata")
public class FolderAttributes {
private Map nameValueForListValue;
#JsonAnySetter
public void genericSetter(String key, Object value){
nameValueForListValue.put(key, value);
}
}
That whay any unknown field could be handle by this setter.
More info:#JsonAnySetter example
#JsonInclude(JsonInclude.Include.NON_NULL)

Jackson Jersey JSON

I'm trying to use Jersey and Jackson (although any other way of doing JSON demarshalling works) to get this into my system in some form (be it POJO or some other representation).
Basically I only need the data section. I was trying to use GenericTypes with lists, but this is a nested list and I'm just not sure what to do. Lots of kudos for help and I really appreciate it!
{
"total": 4,
"data": [
{
"descriptor": "",
"multiInstance": false,
"active": false
},
{
"descriptor": "Apparel",
"multiInstance": true,
},
{
"descriptor": "abcd123",
"multiInstance": false,
},
{
"descriptor": "abcd",
"multiInstance": false,
}
]
}
This is the class I'm trying to use. I need a list of the class.
public class customObject {
#JsonProperty(value = "descriptor")
private String descriptor;
#JsonProperty(value = "multiInstance")
private Boolean multiInstance;
//getters and setters
}
Edit:
I'm using it in here.
CustomObjectResponse WDCOResponse =
resource
.type(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.header("Authorization", getToken()).get(WDCOResponse.class);
But it's still not working.
Edit2:
Figured this out! Thanks to everyone. :)
I had to add annotation to tell it to ignore if something wasn't found, some of the JSON I'm getting back was not fully-formed in that not all fields were absolutely neccesary.
If you the object you provided is what you are passing to your controller, then you will need one more wrapper object to contain the list like this:
public class CustomRequest {
#JSonProperty(value = "total");
private Integer total;
#JsonProperty(value = "data")
private List<CustomObject> data;
// getters/setters
}
public class CustomObject {
#JsonProperty(value = "descriptor")
private String descriptor;
#JsonProperty(value = "multiInstance")
private Boolean multiInstance;
// getters/setters
}
Then your controller will just have annotations that show that the RequestBody is the CustomRequest class:
#Controller
public class JSONController {
#RequestMapping(value="sendData")
public #ResponseBody CustomResponse sendData(
#RequestBody CustomRequest request)
{
return null;
}
}
If you are still getting errors, please provide detailed error or problem. Thanks!
You'd use POJO like:
public class Response {
int count;
List<customObject> data;
}
and access the data from there:
for (customObject ob : response.data) {
// process ig
}

Categories