Reading JSON thru web service into POJOs annotated for Hibernate - json

I am reading the following json through a web service. Is there a way to read the json into three appropriate POJOs? The POJOs are generated by hibernate and are used to communicate to the database.
Basically I need to read the person json into a Person POJO, the pets json into a set of Pet POJOs, and the toy json into a set of Toy POJOs.
The JSON
{
"person":{"first_name":"John", "last_name":"Smith"},
"pets":[{"species":"dog", "name":"Adama"}, {"species":"cat", "name":"Benton"} ],
"toys":[{"car":"corvet", "color":"black"}, {"action_figure":"hancock", "height":"1ft"} ]
}
The Web Service
#Post
public Representation readForm(Representation representation) {
try {
Person aPerson = …
Set<Pet> petSet = …
Set<Toy> toySet = ...
….

You can use xStream . You will have to create a VO having all 3 types of your objects as properties. Give them respective aliases and you will get all 3 types of objects in that VO. You can get them simply by calling their getters.

Related

DRF: can you deserialize one JSON key:value pair into multiple fields

In my API I have a module, which collects JSON objects obtained via POST request. JSON objects I'm receiving look more or less like this:
{
"id": "bec7426d-c5c3-4341-9df2-a0b2c54ab8da",
"data": {
"temperature": -2.4,
// some other stuff is here as well ...
}
}
The problem is requirement that I have to save both: records from data dictionary and whole data dictionary as a JSONField. My ORM model looks like this:
class Report(BaseModel):
id = models.BigAutoField(primary_key=True)
data = JSONField(verbose_name=_("Data"), encoder=DjangoJSONEncoder, blank=True, null=True)
temperature = models.DecimalField(
max_digits=3,
decimal_places=1,
)
# other properties
Is there any neat way to get both properties in one attempt to deserialize JSON object? Currently I use nested serializers formed like this:
class DataSerializer(serializers.ModelSerializer):
temperature = serializers.DecimalField(
source="temperature", write_only=True, max_digits=3, decimal_places=1
)
class Meta:
model = Report
fields = ("temperature")
class ReportSerializer(serializers.ModelSerializer):
id = serializers.UUIDField(source="uuid", read_only=True)
data = DataSerializer(source="*")
class Meta:
model = Report
fields = ("id", "data")
which obviously does not pass whole data dictionary to validated_data, which means I have to update the JSON field elsewhere (not good since I would like to have both data and temperature at null=False in ORM model). Any good ideas on how to fix this using DRF serializers would be appreciated.
I believe you should be able to override validate method for your serializer where you can "store initial data JSON field" and do the default validation by calling super()... method.
More info https://www.django-rest-framework.org/api-guide/serializers/#validation
Also, there are object-level validation functions available, you can take a look there as well for the initial posted data
https://www.django-rest-framework.org/api-guide/serializers/#object-level-validation
Also, you can override the method run_validation to access the initially passed data object.

How can I define a ReST endpoint that allows json input and maps it to a JsonSlurper

I want to write an API ReST endpoint, using Spring 4.0 and Groovy, such that the #RequestBody parameter can be any generic JSON input, and it will be mapped to a Groovy JsonSlurper so that I can simply access the data via the slurper.
The benefit here being that I can send various JSON documents to my endpoint without having to define a DTO object for every format that I might send.
Currently my method looks like this (and works):
#RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> putTest(#RequestBody ExampleDTO dto) {
def json = new groovy.json.JsonBuilder()
json(
id: dto.id,
name: dto.name
);
return new ResponseEntity(json.content, HttpStatus.OK);
}
But what I want, is to get rid of the "ExampleDTO" object, and just have any JSON that is passed in get mapped straight into a JsonSlurper, or something that I can input into a JsonSlurper, so that I can access the fields of the input object like so:
def json = new JsonSlurper().parseText(input);
String exampleName = json.name;
I initially thought I could just accept a String instead of ExampleDTO, and then slurp the String, but then I have been running into a plethora of issues in my AngularJS client, trying to send my JSON objects as strings to the API endpoint. I'm met with an annoying need to escape all of the double quotes and surround the entire JSON string with double quotes. Then I run into issues if any of my data has quotes or various special characters in it. It just doesn't seem like a clean or reliable solution.
I open to anything that will cleanly translate my AngularJS JSON objects into valid Strings, or anything I can do in the ReST method that will allow JSON input without mapping it to a specific object.
Thanks in advance!
Tonya

Grails JSON Converter

I have a method in my main controller that return a string that I want to render as JSON.
So I am importing "import grails.converters.JSON" and calling
myMethod() as JSON
, and it works fine. But when I need to get some details of the json response in my integration test.
So in my integration test I have:
void testfoo() {
def bar = controller.myMethod();
def bar.name; //fails
JSON.parse(bar.toString()).name; // doesn't fail
....
..
}
any idea why I need to convert it to a string and then again to a JSON, since it already a JSON?
The value you get back from your method is a grails.converters.JSON, which is not a directly accessible JSON tree as such, but simply an object that knows how to serialize itself as JSON when required. If you want direct access to the JSON tree structure then you need to tell the grails.converters.JSON object to serialize itself and then pass that JSON to JSON.parse to turn it into a JSONElement (or one of its subclasses, in this case presumably a JSONObject).

Mapping unpredictable keys from JSON to POJO

I am using the Jackson JSON library to map JSON streams into POJO's.
My JSON's keys have unpredictable names.
i.e
{
"Random_ID":
{
"Another_Random_ID":
{
"some_key": "value"
"some_key1": "value1"
}
}
...
}
I would like to map this request to a POJO (with the same structure), however the mapper will fail since there is no such setXXX (where XXX is a random_id - since i cannot predict the name).
What would be the best way to map this request to the corresponding object without manually parsing it with createJsonParser.
If names are unpredictable, POJOs are not the way to go.
But you can use the Tree Model, like:
JsonNode root = objectMapper.readTree(jsonSource);
and access it as a logical tree. Also, if you do want to convert the tree (or any of sub-trees, as identified by node that is the root of sub-tree), you can do:
MyPOJO pojo = objectMapper.treeToValue(node, MyPOJO.class);
and back to tree
JsonNode node = objectMapper.valueToTree(pojo);

Marshalling an empty collection to json using jersey

I have a strange issue marshalling an empty object collection to json using jersey with the jaxb based json support. My object looks like
...
#XmlWrapper(name = "stuff") #XmlElement(name = "s")
private List<Foo> foos;
...
Marshaling this to json produces the expected results
... stuff: [{ "s": ... }, { "s": ... }] ...
except when the list is empty. I would expect to see
... stuff: [] ...
but I see
... stuff: [null] ...
instead. Any idea what's wrong? The problem seems to be related to the #XmlElementWrapper annotation, removing it I don't get the the stuff property in the output at all.
Are you serializing an empty list, or are you serializing an un-instantiated null object?
ie. I would expect:
private List<Foo> foos; - would serialize to 'stuff: [null]'
and I would also expect:
private List<Foo> foos = new ArrayList<Foo>(); - we serialize to 'stuff: []'
If that isn't the case, you can always direct Jackson (which is the default JSON serializer bundled with Jersey) to omit the writing of bean properties as null value..
I would suggest using POJO mapping based on Jackson. I am not sure why you want that intermediate "s" in there, but POJO would produce (and consume) simpler structure:
"stuff" : [ { ... }, { ... } ]
For that you need no annotations with POJO mapping; JAXB annotations are only needed for XML processing, since XML has no natural mechanism to distinguish arrays from objects (unlike JSON).
I managed to solve JSON array and primitive field "bug" in Jersey json library. Secret ingredient is JSONConfiguration and ContextResolver magic. See my following post it has a full code example, customized ContextResolver and rest Application class might be somewhat fuzzy logic in first look.
How to serialize Java primitives using Jersey REST
json array for zero or single-element Java lists
primitive integer or boolean fields without quotation chars